--- client/ai/ai.c.orig	Sun Aug  5 11:56:34 2007
+++ client/ai/ai.c	Mon Jan 21 09:30:47 2008
@@ -37,6 +37,7 @@ static int waittime = 1000;
 static gboolean silent = FALSE;
 static gboolean enable_debug = FALSE;
 static gboolean show_version = FALSE;
+static Map *map = NULL;
 
 static const struct algorithm_info {
 	/** Name of the algorithm (for commandline) */
@@ -217,9 +218,21 @@ void ai_chat(const char *message)
 		cb_chat(message);
 }
 
+static Map *ai_get_map(void)
+{
+	return map;
+}
+
+static void ai_set_map(Map * new_map)
+{
+	map = new_map;
+}
+
 void frontend_set_callbacks(void)
 {
 	callbacks.init = &ai_init;
 	callbacks.offline = &ai_offline;
 	callbacks.start_game = &ai_start_game;
+	callbacks.get_map = &ai_get_map;
+	callbacks.set_map = &ai_set_map;
 }
--- client/ai/greedy.c.orig	Sun Aug  5 11:56:34 2007
+++ client/ai/greedy.c	Mon Jan 21 09:30:47 2008
@@ -117,12 +117,14 @@ typedef void iterate_node_func_t(Node * n, void *rock)
  */
 static void for_each_node(iterate_node_func_t * func, void *rock)
 {
+	Map *map;
 	int i, j, k;
 
-	for (i = 0; i < get_map()->x_size; i++) {
-		for (j = 0; j < get_map()->y_size; j++) {
+	map = callbacks.get_map();
+	for (i = 0; i < map->x_size; i++) {
+		for (j = 0; j < map->y_size; j++) {
 			for (k = 0; k < 6; k++) {
-				Node *n = map_node(get_map(), i, j, k);
+				Node *n = map_node(map, i, j, k);
 
 				if (n)
 					func(n, rock);
@@ -344,7 +346,8 @@ static void reevaluate_resources(resource_values_t * o
 	/*
 	 * Save the maritime info too so we know if we can do port trades
 	 */
-	map_maritime_info(get_map(), &outval->info, my_player_num());
+	map_maritime_info(callbacks.get_map(), &outval->info,
+			  my_player_num());
 }
 
 
@@ -467,11 +470,12 @@ static Node *best_settlement_spot(gboolean during_setu
 	Node *best = NULL;
 	float bestscore = -1.0;
 	float score;
+	Map *map = callbacks.get_map();
 
-	for (i = 0; i < get_map()->x_size; i++) {
-		for (j = 0; j < get_map()->y_size; j++) {
+	for (i = 0; i < map->x_size; i++) {
+		for (j = 0; j < map->y_size; j++) {
 			for (k = 0; k < 6; k++) {
-				Node *n = map_node(get_map(), i, j, k);
+				Node *n = map_node(map, i, j, k);
 				if (!n)
 					continue;
 				if (during_setup) {
@@ -505,11 +509,12 @@ static Node *best_city_spot(const resource_values_t * 
 	int i, j, k;
 	Node *best = NULL;
 	float bestscore = -1.0;
+	Map *map = callbacks.get_map();
 
-	for (i = 0; i < get_map()->x_size; i++) {
-		for (j = 0; j < get_map()->y_size; j++) {
+	for (i = 0; i < map->x_size; i++) {
+		for (j = 0; j < map->y_size; j++) {
 			for (k = 0; k < 6; k++) {
-				Node *n = map_node(get_map(), i, j, k);
+				Node *n = map_node(map, i, j, k);
 				if (!n)
 					continue;
 				if ((n->owner == my_player_num())
@@ -662,11 +667,12 @@ static Edge *best_road_to_road(const resource_values_t
 	int i, j, k;
 	Edge *best = NULL;
 	float bestscore = -1.0;
+	Map *map = callbacks.get_map();
 
-	for (i = 0; i < get_map()->x_size; i++) {
-		for (j = 0; j < get_map()->y_size; j++) {
+	for (i = 0; i < map->x_size; i++) {
+		for (j = 0; j < map->y_size; j++) {
 			for (k = 0; k < 6; k++) {
-				Node *n = map_node(get_map(), i, j, k);
+				Node *n = map_node(map, i, j, k);
 				Edge *e;
 				float score;
 
@@ -696,6 +702,7 @@ static Edge *best_road_spot(const resource_values_t * 
 	Edge *best = NULL;
 	float bestscore = -1.0;
 	node_seen_set_t nodeseen;
+	Map *map = callbacks.get_map();
 
 	/*
 	 * For every node that we're the owner of traverse out to find the best
@@ -705,10 +712,10 @@ static Edge *best_road_spot(const resource_values_t * 
 	 * xxx loops
 	 */
 
-	for (i = 0; i < get_map()->x_size; i++) {
-		for (j = 0; j < get_map()->y_size; j++) {
+	for (i = 0; i < map->x_size; i++) {
+		for (j = 0; j < map->y_size; j++) {
 			for (k = 0; k < 6; k++) {
-				Node *n = map_node(get_map(), i, j, k);
+				Node *n = map_node(map, i, j, k);
 
 				if ((n != NULL)
 				    && (n->owner == my_player_num())) {
@@ -1060,7 +1067,7 @@ static gboolean will_do_maritime_trade(gint assets[NO_
 	Resource res, want, discard;
 	gint ports[NO_RESOURCE];
 
-	map_maritime_info(get_map(), &info, my_player_num());
+	map_maritime_info(callbacks.get_map(), &info, my_player_num());
 
 	for (res = 0; res < NO_RESOURCE; res++) {
 		if (info.specific_resource[res])
@@ -1410,11 +1417,12 @@ static void greedy_place_robber(void)
 	int i, j;
 	float bestscore = -1000;
 	Hex *besthex = NULL;
+	Map *map = callbacks.get_map();
 
 	ai_wait();
-	for (i = 0; i < get_map()->x_size; i++) {
-		for (j = 0; j < get_map()->y_size; j++) {
-			Hex *hex = map_hex(get_map(), i, j);
+	for (i = 0; i < map->x_size; i++) {
+		for (j = 0; j < map->y_size; j++) {
+			Hex *hex = map_hex(map, i, j);
 			float score = score_hex_hurt_opponents(hex);
 
 			if (score > bestscore) {
@@ -1432,7 +1440,7 @@ static void greedy_steal_building(void)
 	int i;
 	int victim = -1;
 	int victim_resources = -1;
-	Hex *hex = map_robber_hex(get_map());
+	Hex *hex = map_robber_hex(callbacks.get_map());
 
 	/* which opponent to steal from */
 	for (i = 0; i < 6; i++) {
--- client/callback.h.orig	Sun Aug  5 11:56:34 2007
+++ client/callback.h	Mon Jan 21 09:30:47 2008
@@ -260,6 +260,10 @@ struct callbacks {
 	void (*new_bank) (const gint * new_bank);
 	/* some communication error occurred, and it has already been logged */
 	void (*error) (const gchar * message);
+	/* get the map */
+	Map *(*get_map) (void);
+	/* set the map */
+	void (*set_map) (Map * map);
 	/* mainloop.  This is initialized to run the glib main loop.  It can
 	 * be overridden */
 	void (*mainloop) (void);
@@ -407,7 +411,6 @@ int robber_count_victims(const Hex * hex, gint * victi
 const gint *get_bank(void);
 const DevelDeck *get_devel_deck(void);
 const gchar *get_devel_name(DevelType type);
-Map *get_map(void);
 
 /** Returns instructions for the user */
 const gchar *road_building_message(gint build_amount);
--- client/common/build.c.orig	Sun Aug  5 11:56:34 2007
+++ client/common/build.c	Mon Jan 21 09:30:47 2008
@@ -88,7 +88,7 @@ void build_move(gint sx, gint sy, gint spos, gint dx, 
 	GList *list;
 	BuildRec *rec;
 	if (isundo) {
-		map->has_moved_ship = FALSE;
+		callbacks.get_map()->has_moved_ship = FALSE;
 		list = g_list_last(build_list);
 		rec = list->data;
 		if (rec->type != BUILD_MOVE_SHIP && rec->x != sx
@@ -109,7 +109,7 @@ void build_move(gint sx, gint sy, gint spos, gint dx, 
 		rec = buildrec_new(BUILD_MOVE_SHIP, sx, sy, spos);
 		build_list = g_list_append(build_list, rec);
 		built = TRUE;
-		map->has_moved_ship = TRUE;
+		callbacks.get_map()->has_moved_ship = TRUE;
 	}
 	player_build_move(my_player_num(), sx, sy, spos, dx, dy, dpos,
 			  isundo);
@@ -156,7 +156,8 @@ gint build_count(BuildType type)
 
 gboolean build_is_valid(void)
 {
-	return buildrec_is_valid(build_list, map, my_player_num());
+	return buildrec_is_valid(build_list, callbacks.get_map(),
+				 my_player_num());
 }
 
 gboolean build_can_undo(void)
@@ -173,24 +174,21 @@ gboolean have_built(void)
  */
 gboolean build_can_setup_road(const Edge * edge, gboolean double_setup)
 {
-	return buildrec_can_setup_road(build_list, map, edge,
-				       double_setup);
+	return buildrec_can_setup_road(build_list, edge, double_setup);
 }
 
 /* Place some restrictions on ship placement during setup phase
  */
 gboolean build_can_setup_ship(const Edge * edge, gboolean double_setup)
 {
-	return buildrec_can_setup_ship(build_list, map, edge,
-				       double_setup);
+	return buildrec_can_setup_ship(build_list, edge, double_setup);
 }
 
 /* Place some restrictions on bridge placement during setup phase
  */
 gboolean build_can_setup_bridge(const Edge * edge, gboolean double_setup)
 {
-	return buildrec_can_setup_bridge(build_list, map, edge,
-					 double_setup);
+	return buildrec_can_setup_bridge(build_list, edge, double_setup);
 }
 
 /* Place some restrictions on road placement during setup phase
@@ -198,6 +196,6 @@ gboolean build_can_setup_bridge(const Edge * edge, gbo
 gboolean build_can_setup_settlement(const Node * node,
 				    gboolean double_setup)
 {
-	return buildrec_can_setup_settlement(build_list, map, node,
+	return buildrec_can_setup_settlement(build_list, node,
 					     double_setup);
 }
--- client/common/callback.c.orig	Sun Aug  5 11:56:34 2007
+++ client/common/callback.c	Mon Jan 21 09:30:47 2008
@@ -390,21 +390,21 @@ gboolean road_building_can_build_road(void)
 {
 	return build_count_edges() < 2
 	    && stock_num_roads() > 0
-	    && map_can_place_road(map, my_player_num());
+	    && map_can_place_road(callbacks.get_map(), my_player_num());
 }
 
 gboolean road_building_can_build_ship(void)
 {
 	return build_count_edges() < 2
 	    && stock_num_ships() > 0
-	    && map_can_place_ship(map, my_player_num());
+	    && map_can_place_ship(callbacks.get_map(), my_player_num());
 }
 
 gboolean road_building_can_build_bridge(void)
 {
 	return build_count_edges() < 2
 	    && stock_num_bridges() > 0
-	    && map_can_place_bridge(map, my_player_num());
+	    && map_can_place_bridge(callbacks.get_map(), my_player_num());
 }
 
 gboolean road_building_can_finish(void)
@@ -419,28 +419,29 @@ gboolean turn_can_build_road(void)
 {
 	return have_rolled_dice()
 	    && stock_num_roads() > 0 && can_afford(cost_road())
-	    && map_can_place_road(map, my_player_num());
+	    && map_can_place_road(callbacks.get_map(), my_player_num());
 }
 
 gboolean turn_can_build_ship(void)
 {
 	return have_rolled_dice()
 	    && stock_num_ships() > 0 && can_afford(cost_ship())
-	    && map_can_place_ship(map, my_player_num());
+	    && map_can_place_ship(callbacks.get_map(), my_player_num());
 }
 
 gboolean turn_can_build_bridge(void)
 {
 	return have_rolled_dice()
 	    && stock_num_bridges() > 0 && can_afford(cost_bridge())
-	    && map_can_place_bridge(map, my_player_num());
+	    && map_can_place_bridge(callbacks.get_map(), my_player_num());
 }
 
 gboolean turn_can_build_settlement(void)
 {
 	return have_rolled_dice()
 	    && stock_num_settlements() > 0 && can_afford(cost_settlement())
-	    && map_can_place_settlement(map, my_player_num());
+	    && map_can_place_settlement(callbacks.get_map(),
+					my_player_num());
 }
 
 gboolean turn_can_build_city(void)
@@ -448,14 +449,16 @@ gboolean turn_can_build_city(void)
 	return have_rolled_dice()
 	    && stock_num_cities() > 0
 	    && can_afford(cost_upgrade_settlement())
-	    && map_can_upgrade_settlement(map, my_player_num());
+	    && map_can_upgrade_settlement(callbacks.get_map(),
+					  my_player_num());
 }
 
 gboolean turn_can_build_city_wall(void)
 {
 	return have_rolled_dice()
 	    && stock_num_city_walls() > 0 && can_afford(cost_city_wall())
-	    && map_can_place_city_wall(map, my_player_num());
+	    && map_can_place_city_wall(callbacks.get_map(),
+				       my_player_num());
 }
 
 gboolean turn_can_trade(void)
@@ -475,12 +478,12 @@ gboolean turn_can_trade(void)
 	    || can_trade_domestic();
 }
 
-static gboolean really_try_move_ship(G_GNUC_UNUSED Map * map, Hex * hex,
-				     Edge * from)
+static gboolean really_try_move_ship(const Hex * hex, gpointer closure)
 {
 	gint idx;
+	const Edge *from = closure;
 	for (idx = 0; idx < G_N_ELEMENTS(hex->edges); ++idx) {
-		Edge *edge;
+		const Edge *edge;
 		edge = hex->edges[idx];
 		if (edge->x != hex->x || edge->y != hex->y)
 			continue;
@@ -502,7 +505,7 @@ gboolean can_move_ship(const Edge * from, const Edge *
 	owner = from->owner;
 	if (!can_ship_be_moved(from, owner))
 		return FALSE;
-	ship_sailed_from_here = map_edge(map, from->x, from->y, from->pos);	/* Copy to non-const pointer */
+	ship_sailed_from_here = map_edge(callbacks.get_map(), from->x, from->y, from->pos);	/* Copy to non-const pointer */
 	ship_sailed_from_here->owner = -1;
 	ship_sailed_from_here->type = BUILD_NONE;
 	retval = can_ship_be_built(to, owner);
@@ -511,19 +514,20 @@ gboolean can_move_ship(const Edge * from, const Edge *
 	return retval;
 }
 
-static gboolean try_move_ship(Map * map, Hex * hex)
+static gboolean try_move_ship(const Hex * hex,
+			      G_GNUC_UNUSED gpointer closure)
 {
 	gint idx;
 	for (idx = 0; idx < G_N_ELEMENTS(hex->edges); ++idx) {
-		Edge *edge;
+		Edge *edge;	/* Huh? Can non-const be taken from const Hex ? */
 		edge = hex->edges[idx];
 		if (edge->x != hex->x || edge->y != hex->y)
 			continue;
 		if (edge->owner != my_player_num()
 		    || edge->type != BUILD_SHIP)
 			continue;
-		if (map_traverse
-		    (map, (HexFunc) really_try_move_ship, edge))
+		if (map_traverse_const
+		    (callbacks.get_map(), really_try_move_ship, edge))
 			return TRUE;
 	}
 	return FALSE;
@@ -531,9 +535,10 @@ static gboolean try_move_ship(Map * map, Hex * hex)
 
 gboolean turn_can_move_ship(void)
 {
-	if (!have_rolled_dice() || map->has_moved_ship)
+	if (!have_rolled_dice() || callbacks.get_map()->has_moved_ship)
 		return FALSE;
-	return map_traverse(map, (HexFunc) try_move_ship, NULL);
+	return map_traverse_const(callbacks.get_map(), try_move_ship,
+				  NULL);
 }
 
 int robber_count_victims(const Hex * hex, gint * victim_list)
@@ -612,9 +617,4 @@ int pirate_count_victims(const Hex * hex, gint * victi
 	}
 
 	return num_victims;
-}
-
-Map *get_map(void)
-{
-	return map;
 }
--- client/common/client.c.orig	Sun Aug  5 11:56:34 2007
+++ client/common/client.c	Mon Jan 21 09:30:47 2008
@@ -36,7 +36,6 @@
 
 static enum callback_mode previous_mode;
 GameParams *game_params;
-Map *map;
 static struct recovery_info_t {
 	gchar *prevstate;
 	gint turnnum;
@@ -338,6 +337,13 @@ static void dummy_new_bank(G_GNUC_UNUSED const gint * 
 static void dummy_error(G_GNUC_UNUSED const gchar * message)
 {;
 }
+static Map *dummy_get_map(void)
+{
+	return NULL;
+}
+static void dummy_set_map(G_GNUC_UNUSED Map * map)
+{;
+}
 
 /*----------------------------------------------------------------------
  * Entry point for the client state machine
@@ -410,6 +416,8 @@ void client_init(void)
 	callbacks.incoming_chat = &dummy_incoming_chat;
 	callbacks.new_bank = &dummy_new_bank;
 	callbacks.error = &dummy_error;
+	callbacks.get_map = &dummy_get_map;
+	callbacks.set_map = &dummy_set_map;
 	/* mainloop and quit are not set here */
 	resource_init();
 }
@@ -944,7 +952,7 @@ static gboolean mode_load_game(StateMachine * sm, gint
 	}
 	if (sm_recv(sm, "end")) {
 		params_load_finish(game_params);
-		map = game_params->map;
+		callbacks.set_map(game_params->map);
 		stock_init();
 		develop_init();
 		/* initialize global recovery info struct */
@@ -1519,9 +1527,9 @@ gboolean mode_robber_move_response(StateMachine * sm, 
 			return TRUE;
 		}
 		if (sm_recv(sm, "rob %d %d", &x, &y)) {
-			Hex *hex;
+			const Hex *hex;
 			waiting_for_network(FALSE);
-			hex = map_hex(map, x, y);
+			hex = map_hex_const(callbacks.get_map(), x, y);
 			if (hex->terrain == SEA_TERRAIN)
 				sm_push(sm, mode_robber_steal_ship);
 			else
@@ -2625,7 +2633,7 @@ gboolean can_trade_maritime(void)
 		return FALSE;
 	can_trade = FALSE;
 	/* Check if we can do a maritime trade */
-	map_maritime_info(map, &info, my_player_num());
+	map_maritime_info(callbacks.get_map(), &info, my_player_num());
 	for (idx = 0; idx < NO_RESOURCE; idx++)
 		if (info.specific_resource[idx]
 		    && resource_asset(idx) >= 2) {
--- client/common/client.h.orig	Sun Aug  5 11:56:34 2007
+++ client/common/client.h	Mon Jan 21 09:30:47 2008
@@ -27,7 +27,6 @@
 #include "callback.h"
 
 /* variables */
-extern Map *map;
 extern GameParams *game_params;
 extern gchar *requested_name;
 extern gboolean requested_viewer;
--- client/common/player.c.orig	Sun Aug  5 11:56:34 2007
+++ client/common/player.c	Mon Jan 21 09:30:47 2008
@@ -467,7 +467,7 @@ void player_build_add(gint player_num,
 
 	switch (type) {
 	case BUILD_ROAD:
-		edge = map_edge(map, x, y, pos);
+		edge = map_edge(callbacks.get_map(), x, y, pos);
 		edge->owner = player_num;
 		edge->type = BUILD_ROAD;
 		callbacks.draw_edge(edge);
@@ -479,7 +479,7 @@ void player_build_add(gint player_num,
 			stock_use_road();
 		break;
 	case BUILD_SHIP:
-		edge = map_edge(map, x, y, pos);
+		edge = map_edge(callbacks.get_map(), x, y, pos);
 		edge->owner = player_num;
 		edge->type = BUILD_SHIP;
 		callbacks.draw_edge(edge);
@@ -491,7 +491,7 @@ void player_build_add(gint player_num,
 			stock_use_ship();
 		break;
 	case BUILD_SETTLEMENT:
-		node = map_node(map, x, y, pos);
+		node = map_node(callbacks.get_map(), x, y, pos);
 		node->type = BUILD_SETTLEMENT;
 		node->owner = player_num;
 		callbacks.draw_node(node);
@@ -505,7 +505,7 @@ void player_build_add(gint player_num,
 			stock_use_settlement();
 		break;
 	case BUILD_CITY:
-		node = map_node(map, x, y, pos);
+		node = map_node(callbacks.get_map(), x, y, pos);
 		if (node->type == BUILD_SETTLEMENT) {
 			player_modify_statistic(player_num,
 						STAT_SETTLEMENTS, -1);
@@ -524,7 +524,7 @@ void player_build_add(gint player_num,
 			stock_use_city();
 		break;
 	case BUILD_CITY_WALL:
-		node = map_node(map, x, y, pos);
+		node = map_node(callbacks.get_map(), x, y, pos);
 		node->city_wall = TRUE;
 		node->owner = player_num;
 		callbacks.draw_node(node);
@@ -545,7 +545,7 @@ void player_build_add(gint player_num,
 			    player_name(player_num, TRUE));
 		break;
 	case BUILD_BRIDGE:
-		edge = map_edge(map, x, y, pos);
+		edge = map_edge(callbacks.get_map(), x, y, pos);
 		edge->owner = player_num;
 		edge->type = BUILD_BRIDGE;
 		callbacks.draw_edge(edge);
@@ -572,7 +572,7 @@ void player_build_remove(gint player_num,
 
 	switch (type) {
 	case BUILD_ROAD:
-		edge = map_edge(map, x, y, pos);
+		edge = map_edge(callbacks.get_map(), x, y, pos);
 		edge->owner = -1;
 		callbacks.draw_edge(edge);
 		edge->type = BUILD_NONE;
@@ -582,7 +582,7 @@ void player_build_remove(gint player_num,
 			stock_replace_road();
 		break;
 	case BUILD_SHIP:
-		edge = map_edge(map, x, y, pos);
+		edge = map_edge(callbacks.get_map(), x, y, pos);
 		edge->owner = -1;
 		callbacks.draw_edge(edge);
 		edge->type = BUILD_NONE;
@@ -592,7 +592,7 @@ void player_build_remove(gint player_num,
 			stock_replace_ship();
 		break;
 	case BUILD_SETTLEMENT:
-		node = map_node(map, x, y, pos);
+		node = map_node(callbacks.get_map(), x, y, pos);
 		node->type = BUILD_NONE;
 		node->owner = -1;
 		callbacks.draw_node(node);
@@ -603,7 +603,7 @@ void player_build_remove(gint player_num,
 			stock_replace_settlement();
 		break;
 	case BUILD_CITY:
-		node = map_node(map, x, y, pos);
+		node = map_node(callbacks.get_map(), x, y, pos);
 		node->type = BUILD_SETTLEMENT;
 		node->owner = player_num;
 		callbacks.draw_node(node);
@@ -617,7 +617,7 @@ void player_build_remove(gint player_num,
 		}
 		break;
 	case BUILD_CITY_WALL:
-		node = map_node(map, x, y, pos);
+		node = map_node(callbacks.get_map(), x, y, pos);
 		node->city_wall = FALSE;
 		node->owner = player_num;
 		callbacks.draw_node(node);
@@ -635,7 +635,7 @@ void player_build_remove(gint player_num,
 			    player_name(player_num, TRUE));
 		break;
 	case BUILD_BRIDGE:
-		edge = map_edge(map, x, y, pos);
+		edge = map_edge(callbacks.get_map(), x, y, pos);
 		edge->owner = -1;
 		callbacks.draw_edge(edge);
 		edge->type = BUILD_NONE;
@@ -655,8 +655,8 @@ void player_build_remove(gint player_num,
 void player_build_move(gint player_num, gint sx, gint sy, gint spos,
 		       gint dx, gint dy, gint dpos, gint isundo)
 {
-	Edge *from = map_edge(map, sx, sy, spos),
-	    *to = map_edge(map, dx, dy, dpos);
+	Edge *from = map_edge(callbacks.get_map(), sx, sy, spos),
+	    *to = map_edge(callbacks.get_map(), dx, dy, dpos);
 	if (isundo) {
 		Edge *tmp = from;
 		from = to;
--- client/common/robber.c.orig	Sun Aug  5 11:56:34 2007
+++ client/common/robber.c	Mon Jan 21 09:30:47 2008
@@ -30,6 +30,7 @@
 
 void robber_move_on_map(gint x, gint y)
 {
+	Map *map = callbacks.get_map();
 	Hex *hex = map_hex(map, x, y);
 	Hex *old_robber = map_robber_hex(map);
 
@@ -42,6 +43,7 @@ void robber_move_on_map(gint x, gint y)
 
 void pirate_move_on_map(gint x, gint y)
 {
+	Map *map = callbacks.get_map();
 	Hex *hex = map_hex(map, x, y);
 	Hex *old_pirate = map_pirate_hex(map);
 
--- client/common/setup.c.orig	Sun Aug  5 11:56:34 2007
+++ client/common/setup.c	Mon Jan 21 09:30:47 2008
@@ -44,12 +44,14 @@ gboolean setup_can_build_road(void)
 		if (build_count_edges() == 2)
 			return FALSE;
 		return build_count_settlements() < 2
-		    || map_can_place_road(map, my_player_num());
+		    || map_can_place_road(callbacks.get_map(),
+					  my_player_num());
 	} else {
 		if (build_count_edges() == 1)
 			return FALSE;
 		return build_count_settlements() < 1
-		    || map_can_place_road(map, my_player_num());
+		    || map_can_place_road(callbacks.get_map(),
+					  my_player_num());
 	}
 }
 
@@ -61,12 +63,14 @@ gboolean setup_can_build_ship(void)
 		if (build_count_edges() == 2)
 			return FALSE;
 		return build_count_settlements() < 2
-		    || map_can_place_ship(map, my_player_num());
+		    || map_can_place_ship(callbacks.get_map(),
+					  my_player_num());
 	} else {
 		if (build_count_edges() == 1)
 			return FALSE;
 		return build_count_settlements() < 1
-		    || map_can_place_ship(map, my_player_num());
+		    || map_can_place_ship(callbacks.get_map(),
+					  my_player_num());
 	}
 }
 
@@ -78,12 +82,14 @@ gboolean setup_can_build_bridge(void)
 		if (build_count_edges() == 2)
 			return FALSE;
 		return build_count_settlements() < 2
-		    || map_can_place_bridge(map, my_player_num());
+		    || map_can_place_bridge(callbacks.get_map(),
+					    my_player_num());
 	} else {
 		if (build_count_edges() == 1)
 			return FALSE;
 		return build_count_settlements() < 1
-		    || map_can_place_bridge(map, my_player_num());
+		    || map_can_place_bridge(callbacks.get_map(),
+					    my_player_num());
 	}
 }
 
--- client/common/turn.c.orig	Sun Aug  5 11:56:34 2007
+++ client/common/turn.c	Mon Jan 21 09:30:47 2008
@@ -39,7 +39,7 @@ void turn_rolled_dice(gint player_num, gint die1, gint
 
 	if (player_num == my_player_num()) {
 		rolled_dice = TRUE;
-		map->has_moved_ship = FALSE;
+		callbacks.get_map()->has_moved_ship = FALSE;
 	}
 	callbacks.rolled_dice(die1, die2, player_num);
 }
--- client/gtk/callbacks.c.orig	Sun Aug  5 11:56:34 2007
+++ client/gtk/callbacks.c	Mon Jan 21 09:30:47 2008
@@ -168,4 +168,6 @@ void frontend_set_callbacks(void)
 	callbacks.viewer_quit = &frontend_viewer_quit;
 	callbacks.incoming_chat = &chat_parser;
 	callbacks.new_bank = &frontend_new_bank;
+	callbacks.get_map = &frontend_get_map;
+	callbacks.set_map = &frontend_set_map;
 }
--- client/gtk/frontend.h.orig	Sun Aug  5 11:56:34 2007
+++ client/gtk/frontend.h	Mon Jan 21 09:30:47 2008
@@ -150,6 +150,8 @@ void frontend_steal_building(void);
 void frontend_steal_ship(void);
 void frontend_robber_done(void);
 void frontend_game_over(gint player, gint points);
+Map *frontend_get_map(void);
+void frontend_set_map(Map * map);
 
 /* connect.c */
 const gchar *connect_get_server(void);
--- client/gtk/gui.c.orig	Sun Aug  5 11:56:34 2007
+++ client/gtk/gui.c	Mon Jan 21 09:30:47 2008
@@ -1605,3 +1605,15 @@ void gui_set_show_no_setup_nodes(gboolean show)
 {
 	guimap_set_show_no_setup_nodes(gmap, show);
 }
+
+Map *frontend_get_map(void)
+{
+	g_return_val_if_fail(gmap != NULL, NULL);
+	return gmap->map;
+}
+
+void frontend_set_map(Map * map)
+{
+	g_assert(gmap != NULL);
+	gmap->map = map;
+}
--- client/gtk/interface.c.orig	Sun Aug  5 11:56:34 2007
+++ client/gtk/interface.c	Mon Jan 21 09:30:47 2008
@@ -733,7 +733,7 @@ static void place_robber_or_pirate_cb(MapElement hex,
 void frontend_steal_ship(void)
 {
 	MapElement hex;
-	hex.hex = map_pirate_hex(get_map());
+	hex.hex = map_pirate_hex(callbacks.get_map());
 
 	gui_cursor_set(STEAL_SHIP_CURSOR, can_edge_be_robbed, rob_edge,
 		       NULL, &hex);
@@ -743,7 +743,7 @@ void frontend_steal_ship(void)
 void frontend_steal_building(void)
 {
 	MapElement hex;
-	hex.hex = map_robber_hex(get_map());
+	hex.hex = map_robber_hex(callbacks.get_map());
 
 	gui_cursor_set(STEAL_BUILDING_CURSOR, can_building_be_robbed,
 		       rob_building, NULL, &hex);
--- client/gtk/quote-view.c.orig	Sun Aug  5 11:56:34 2007
+++ client/gtk/quote-view.c	Mon Jan 21 09:30:47 2008
@@ -607,7 +607,7 @@ void quote_view_begin(QuoteView * qv)
 {
 	quotelist_new(&qv->quote_list);
 	if (qv->with_maritime) {
-		map_maritime_info(get_map(), &qv->maritime_info,
+		map_maritime_info(callbacks.get_map(), &qv->maritime_info,
 				  my_player_num());
 	}
 
--- common/buildrec.c.orig	Sun Aug  5 11:56:34 2007
+++ common/buildrec.c	Mon Jan 21 09:30:47 2008
@@ -29,8 +29,7 @@
 #include "buildrec.h"
 
 /* Local function prototypes. */
-static gboolean buildrec_can_setup_edge(GList * list, Map * map,
-					const Edge * edge,
+static gboolean buildrec_can_setup_edge(GList * list, const Edge * edge,
 					gboolean is_double);
 
 
@@ -114,7 +113,7 @@ BuildRec *buildrec_get_edge(GList * list, gint idx)
 	return NULL;
 }
 
-gboolean buildrec_is_valid(GList * list, Map * map, gint owner)
+gboolean buildrec_is_valid(GList * list, const Map * map, gint owner)
 {
 	while (list != NULL) {
 		BuildRec *rec = list->data;
@@ -155,9 +154,8 @@ gboolean buildrec_is_valid(GList * list, Map * map, gi
 		case BUILD_CITY_WALL:
 			/* Buildings must be adjacent to a road
 			 */
-			if (!map_building_connect_ok(map, owner, rec->type,
-						     rec->x, rec->y,
-						     rec->pos))
+			if (!map_building_connect_ok
+			    (map, owner, rec->x, rec->y, rec->pos))
 				return FALSE;
 			continue;
 		}
@@ -181,11 +179,10 @@ static gboolean edge_has_place_for_settlement(const Ed
 
 /* Check if we can place this edge with 0 existing settlements during setup
  */
-static gboolean can_setup_edge_0(GList * list, Map * map,
-				 const Edge * edge)
+static gboolean can_setup_edge_0(GList * list, const Edge * edge)
 {
 	BuildRec *rec = buildrec_get_edge(list, 0);
-	Edge *other_edge;
+	const Edge *other_edge;
 	int idx;
 
 	if (rec == NULL)
@@ -201,7 +198,7 @@ static gboolean can_setup_edge_0(GList * list, Map * m
 	 * there is still a place where the second settlement can be
 	 * placed.
 	 */
-	other_edge = map_edge(map, rec->x, rec->y, rec->pos);
+	other_edge = map_edge(edge->map, rec->x, rec->y, rec->pos);
 	for (idx = 0; idx < G_N_ELEMENTS(edge->nodes); idx++) {
 		Node *node = edge->nodes[idx];
 
@@ -222,12 +219,12 @@ static gboolean can_setup_edge_0(GList * list, Map * m
 
 /* Check if we can place this edge with 1 existing settlement during setup
  */
-static gboolean can_setup_edge_1(GList * list, Map * map,
-				 const Edge * edge)
+static gboolean can_setup_edge_1(GList * list, const Edge * edge)
 {
 	BuildRec *rec = buildrec_get(list, BUILD_SETTLEMENT, 0);
-	Node *node = map_node(map, rec->x, rec->y, rec->pos);
-	Edge *other_edge;
+	const Node *node =
+	    map_node_const(edge->map, rec->x, rec->y, rec->pos);
+	const Edge *other_edge;
 
 	rec = buildrec_get_edge(list, 0);
 	if (rec == NULL)
@@ -243,7 +240,7 @@ static gboolean can_setup_edge_1(GList * list, Map * m
 	 * edges is adjacent to the settlement, and the other has a
 	 * place for the second settlement.
 	 */
-	other_edge = map_edge(map, rec->x, rec->y, rec->pos);
+	other_edge = map_edge_const(edge->map, rec->x, rec->y, rec->pos);
 	return (is_edge_adjacent_to_node(edge, node)
 		&& edge_has_place_for_settlement(other_edge))
 	    || (is_edge_adjacent_to_node(other_edge, node)
@@ -252,16 +249,16 @@ static gboolean can_setup_edge_1(GList * list, Map * m
 
 /* Check if we can place this edge with 2 existing settlements during setup
  */
-static gboolean can_setup_edge_2(GList * list, Map * map,
-				 const Edge * edge)
+static gboolean can_setup_edge_2(GList * list, const Edge * edge)
 {
 	BuildRec *rec = buildrec_get(list, BUILD_SETTLEMENT, 0);
-	Node *node = map_node(map, rec->x, rec->y, rec->pos);
-	Node *other_node;
-	Edge *other_edge;
+	const Node *node =
+	    map_node_const(edge->map, rec->x, rec->y, rec->pos);
+	const Node *other_node;
+	const Edge *other_edge;
 
 	rec = buildrec_get(list, BUILD_SETTLEMENT, 1);
-	other_node = map_node(map, rec->x, rec->y, rec->pos);
+	other_node = map_node_const(edge->map, rec->x, rec->y, rec->pos);
 
 	rec = buildrec_get_edge(list, 0);
 	if (rec == NULL)
@@ -277,7 +274,7 @@ static gboolean can_setup_edge_2(GList * list, Map * m
 	 * bridges, it is possible to have both settlements adjacent
 	 * to a single bridge.
 	 */
-	other_edge = map_edge(map, rec->x, rec->y, rec->pos);
+	other_edge = map_edge_const(edge->map, rec->x, rec->y, rec->pos);
 	if (is_edge_adjacent_to_node(other_edge, node)
 	    && is_edge_adjacent_to_node(other_edge, other_node))
 		/* other_edge is a bridge connecting both settlements
@@ -300,8 +297,7 @@ static gboolean can_setup_edge_2(GList * list, Map * m
 		return is_edge_adjacent_to_node(edge, other_node);
 }
 
-static gboolean buildrec_can_setup_edge(GList * list, Map * map,
-					const Edge * edge,
+static gboolean buildrec_can_setup_edge(GList * list, const Edge * edge,
 					gboolean is_double)
 {
 	if (!is_double) {
@@ -310,8 +306,8 @@ static gboolean buildrec_can_setup_edge(GList * list, 
 			/* We have placed a settlement, the edge must
 			 * be placed adjacent to that settlement.
 			 */
-			Node *node =
-			    map_node(map, rec->x, rec->y, rec->pos);
+			const Node *node =
+			    map_node(edge->map, rec->x, rec->y, rec->pos);
 			return is_edge_adjacent_to_node(edge, node);
 		}
 		/* We have not placed a settlement yet, the edge can
@@ -326,47 +322,46 @@ static gboolean buildrec_can_setup_edge(GList * list, 
 	 */
 	switch (buildrec_count_type(list, BUILD_SETTLEMENT)) {
 	case 0:
-		return can_setup_edge_0(list, map, edge);
+		return can_setup_edge_0(list, edge);
 	case 1:
-		return can_setup_edge_1(list, map, edge);
+		return can_setup_edge_1(list, edge);
 	case 2:
-		return can_setup_edge_2(list, map, edge);
+		return can_setup_edge_2(list, edge);
 	}
 	g_warning("more than 2 settlements in setup!!!");
 	return FALSE;
 }
 
-gboolean buildrec_can_setup_road(GList * list, Map * map,
-				 const Edge * edge, gboolean is_double)
+gboolean buildrec_can_setup_road(GList * list, const Edge * edge,
+				 gboolean is_double)
 {
 	if (!can_road_be_setup(edge))
 		return FALSE;
 
-	return buildrec_can_setup_edge(list, map, edge, is_double);
+	return buildrec_can_setup_edge(list, edge, is_double);
 }
 
-gboolean buildrec_can_setup_ship(GList * list, Map * map,
-				 const Edge * edge, gboolean is_double)
+gboolean buildrec_can_setup_ship(GList * list, const Edge * edge,
+				 gboolean is_double)
 {
 	if (!can_ship_be_setup(edge))
 		return FALSE;
 
-	return buildrec_can_setup_edge(list, map, edge, is_double);
+	return buildrec_can_setup_edge(list, edge, is_double);
 }
 
-gboolean buildrec_can_setup_bridge(GList * list, Map * map,
-				   const Edge * edge, gboolean is_double)
+gboolean buildrec_can_setup_bridge(GList * list, const Edge * edge,
+				   gboolean is_double)
 {
 	if (!can_bridge_be_setup(edge))
 		return FALSE;
 
-	return buildrec_can_setup_edge(list, map, edge, is_double);
+	return buildrec_can_setup_edge(list, edge, is_double);
 }
 
 /* Check if we can place this settlement with 0 existing edges during setup
  */
 static gboolean can_setup_settlement_0(G_GNUC_UNUSED GList * list,
-				       G_GNUC_UNUSED Map * map,
 				       G_GNUC_UNUSED const Node * node)
 {
 	return TRUE;
@@ -374,12 +369,12 @@ static gboolean can_setup_settlement_0(G_GNUC_UNUSED G
 
 /* Check if we can place this settlement with 1 existing edge during setup
  */
-static gboolean can_setup_settlement_1(GList * list, Map * map,
-				       const Node * node)
+static gboolean can_setup_settlement_1(GList * list, const Node * node)
 {
 	BuildRec *rec = buildrec_get_edge(list, 0);
-	Edge *edge = map_edge(map, rec->x, rec->y, rec->pos);
-	Node *other_node;
+	const Edge *edge =
+	    map_edge_const(node->map, rec->x, rec->y, rec->pos);
+	const Node *other_node;
 
 	/* Make sure that we place one settlement next to the existing edge.
 	 */
@@ -392,24 +387,24 @@ static gboolean can_setup_settlement_1(GList * list, M
 	/* There is one edge and one settlement placed.  One of the
 	 * settlements must be placed next to the edge.
 	 */
-	other_node = map_node(map, rec->x, rec->y, rec->pos);
+	other_node = map_node_const(node->map, rec->x, rec->y, rec->pos);
 	return is_edge_adjacent_to_node(edge, node)
 	    || is_edge_adjacent_to_node(edge, other_node);
 }
 
 /* Check if we can place this settlement with 2 existing edges during setup
  */
-static gboolean can_setup_settlement_2(GList * list, Map * map,
-				       const Node * node)
+static gboolean can_setup_settlement_2(GList * list, const Node * node)
 {
 	BuildRec *rec = buildrec_get_edge(list, 0);
-	Edge *edge = map_edge(map, rec->x, rec->y, rec->pos);
-	Edge *other_edge;
-	Node *other_node;
+	const Edge *edge =
+	    map_edge_const(node->map, rec->x, rec->y, rec->pos);
+	const Edge *other_edge;
+	const Node *other_node;
 	Node *try_build_here;
 
 	rec = buildrec_get_edge(list, 1);
-	other_edge = map_edge(map, rec->x, rec->y, rec->pos);
+	other_edge = map_edge_const(node->map, rec->x, rec->y, rec->pos);
 
 	/* Two edges placed, we must make sure that we place this
 	 * settlement adjacent to an edge.
@@ -426,7 +421,7 @@ static gboolean can_setup_settlement_2(GList * list, M
 		 */
 		gboolean is_ok = FALSE;
 
-		try_build_here = map_node(map, node->x, node->y, node->pos);	/* Copy to non-const pointer */
+		try_build_here = map_node(node->map, node->x, node->y, node->pos);	/* Copy to non-const pointer */
 		try_build_here->type = BUILD_SETTLEMENT;
 		try_build_here->owner = edge->owner;
 		if (is_edge_adjacent_to_node(edge, node)) {
@@ -460,7 +455,7 @@ static gboolean can_setup_settlement_2(GList * list, M
 	/* Two edges and one settlement placed, ensure that each edge
 	 * is adjacent to at least one settlement.
 	 */
-	other_node = map_node(map, rec->x, rec->y, rec->pos);
+	other_node = map_node_const(node->map, rec->x, rec->y, rec->pos);
 	if (is_edge_adjacent_to_node(edge, other_node)) {
 		if (is_edge_adjacent_to_node(other_edge, other_node))
 			return TRUE;
@@ -470,8 +465,7 @@ static gboolean can_setup_settlement_2(GList * list, M
 		return is_edge_adjacent_to_node(edge, node);
 }
 
-gboolean buildrec_can_setup_settlement(GList * list, Map * map,
-				       const Node * node,
+gboolean buildrec_can_setup_settlement(GList * list, const Node * node,
 				       gboolean is_double)
 {
 	if (!can_settlement_be_setup(node))
@@ -483,8 +477,9 @@ gboolean buildrec_can_setup_settlement(GList * list, M
 			/* We have placed an edge, the settlement must
 			 * be placed adjacent to that edge.
 			 */
-			Edge *edge =
-			    map_edge(map, rec->x, rec->y, rec->pos);
+			const Edge *edge =
+			    map_edge_const(node->map, rec->x, rec->y,
+					   rec->pos);
 			return is_edge_adjacent_to_node(edge, node);
 		}
 		/* We have not placed an edge yet, the settlement is OK.
@@ -497,11 +492,11 @@ gboolean buildrec_can_setup_settlement(GList * list, M
 	 */
 	switch (buildrec_count_edges(list)) {
 	case 0:
-		return can_setup_settlement_0(list, map, node);
+		return can_setup_settlement_0(list, node);
 	case 1:
-		return can_setup_settlement_1(list, map, node);
+		return can_setup_settlement_1(list, node);
 	case 2:
-		return can_setup_settlement_2(list, map, node);
+		return can_setup_settlement_2(list, node);
 	}
 	g_warning("more than 2 settlements in setup!!!");
 	return FALSE;
--- common/buildrec.h.orig	Sun Aug  5 11:56:34 2007
+++ common/buildrec.h	Mon Jan 21 09:30:47 2008
@@ -45,16 +45,15 @@ BuildRec *buildrec_get(GList * list, BuildType type, g
 BuildRec *buildrec_get_edge(GList * list, gint idx);
 BuildRec *buildrec_new(BuildType type, gint x, gint y, gint pos);
 GList *buildrec_free(GList * list);
-gboolean buildrec_is_valid(GList * list, Map * map, int owner);
-gboolean buildrec_can_setup_road(GList * list, Map * map,
-				 const Edge * edge, gboolean is_double);
-gboolean buildrec_can_setup_ship(GList * list, Map * map,
-				 const Edge * edge, gboolean is_double);
-gboolean buildrec_can_setup_settlement(GList * list, Map * map,
-				       const Node * node,
+gboolean buildrec_is_valid(GList * list, const Map * map, gint owner);
+gboolean buildrec_can_setup_road(GList * list, const Edge * edge,
+				 gboolean is_double);
+gboolean buildrec_can_setup_ship(GList * list, const Edge * edge,
+				 gboolean is_double);
+gboolean buildrec_can_setup_settlement(GList * list, const Node * node,
 				       gboolean is_double);
-gboolean buildrec_can_setup_bridge(GList * list, Map * map,
-				   const Edge * edge, gboolean is_double);
+gboolean buildrec_can_setup_bridge(GList * list, const Edge * edge,
+				   gboolean is_double);
 gint buildrec_count_edges(GList * list);
 
 #endif
--- common/game.c.orig	Sun Aug  5 11:56:34 2007
+++ common/game.c	Mon Jan 21 09:30:47 2008
@@ -189,12 +189,12 @@ struct nosetup_t {
 	gpointer user_data;
 };
 
-static gboolean find_no_setup(G_GNUC_UNUSED Map * map, Hex * hex,
-			      struct nosetup_t *data)
+static gboolean find_no_setup(const Hex * hex, gpointer closure)
 {
 	gint idx;
+	struct nosetup_t *data = closure;
 	for (idx = 0; idx < G_N_ELEMENTS(hex->nodes); ++idx) {
-		Node *node = hex->nodes[idx];
+		const Node *node = hex->nodes[idx];
 		if (node->no_setup) {
 			gchar buff[50];
 			if (node->x != hex->x || node->y != hex->y)
@@ -284,7 +284,7 @@ void params_write_lines(GameParams * params, gboolean 
 		struct nosetup_t tmp;
 		tmp.user_data = user_data;
 		tmp.func = func;
-		map_traverse(params->map, (HexFunc) find_no_setup, &tmp);
+		map_traverse_const(params->map, find_no_setup, &tmp);
 	}
 }
 
--- common/gtk/guimap.c.orig	Sun Aug  5 11:56:34 2007
+++ common/gtk/guimap.c	Mon Jan 21 09:30:47 2008
@@ -621,14 +621,14 @@ void draw_dice_roll(PangoLayout * layout, GdkPixmap * 
 	}
 }
 
-static gboolean display_hex(const Map * map, const Hex * hex,
-			    const GuiMap * gmap)
+static gboolean display_hex(const Hex * hex, gpointer closure)
 {
 	gint x_offset, y_offset;
 	GdkPoint points[MAX_POINTS];
 	Polygon poly;
 	int idx;
 	const MapTheme *theme = theme_get_current();
+	const GuiMap *gmap = closure;
 
 	calc_hex_pos(gmap, hex->x, hex->y, &x_offset, &y_offset);
 
@@ -881,7 +881,7 @@ static gboolean display_hex(const Map * map, const Hex
 	}
 
 	/* Draw the pirate */
-	if (hex == map->pirate_hex) {
+	if (hex == hex->map->pirate_hex) {
 		poly.num_points = G_N_ELEMENTS(points);
 		guimap_pirate_polygon(gmap, hex, &poly);
 		gdk_gc_set_line_attributes(gmap->gc, 1, GDK_LINE_SOLID,
@@ -1089,7 +1089,7 @@ void guimap_display(GuiMap * gmap)
 		gmap->chit_radius = size_for_text;
 	}
 
-	map_traverse(gmap->map, (HexFunc) display_hex, gmap);
+	map_traverse_const(gmap->map, display_hex, gmap);
 }
 
 static const Edge *find_hex_edge(GuiMap * gmap, const Hex * hex, gint x,
@@ -1323,7 +1323,7 @@ void guimap_draw_edge(GuiMap * gmap, const Edge * edge
 
 	for (idx = 0; idx < G_N_ELEMENTS(edge->hexes); idx++)
 		if (edge->hexes[idx] != NULL)
-			display_hex(gmap->map, edge->hexes[idx], gmap);
+			display_hex(edge->hexes[idx], gmap);
 
 	gdk_window_invalidate_rect(gmap->area->window, &rect, FALSE);
 }
@@ -1410,7 +1410,7 @@ void guimap_draw_node(GuiMap * gmap, const Node * node
 			   rect.x, rect.y, rect.width, rect.height);
 	for (idx = 0; idx < G_N_ELEMENTS(node->hexes); idx++)
 		if (node->hexes[idx] != NULL)
-			display_hex(gmap->map, node->hexes[idx], gmap);
+			display_hex(node->hexes[idx], gmap);
 
 	gdk_window_invalidate_rect(gmap->area->window, &rect, FALSE);
 }
@@ -1531,7 +1531,7 @@ static void erase_robber_cursor(GuiMap * gmap)
 		guimap_robber_polygon(gmap, hex, &poly);
 	poly_bound_rect(&poly, 1, &rect);
 
-	display_hex(gmap->map, hex, gmap);
+	display_hex(hex, gmap);
 
 	gdk_window_invalidate_rect(gmap->area->window, &rect, FALSE);
 }
@@ -1562,20 +1562,20 @@ static void draw_robber_cursor(GuiMap * gmap)
 	gdk_window_invalidate_rect(gmap->area->window, &rect, FALSE);
 }
 
-static gboolean highlight_chits(G_GNUC_UNUSED Map * map, const Hex * hex,
-				HighlightInfo * closure)
+static gboolean highlight_chits(const Hex * hex, gpointer closure)
 {
-	GuiMap *gmap = closure->gmap;
+	HighlightInfo *highlight_info = closure;
+	GuiMap *gmap = highlight_info->gmap;
 	GdkPoint points[6];
 	Polygon poly;
 	gint x_offset, y_offset;
 	GdkRectangle rect;
 
-	if (hex->roll != closure->old_highlight
+	if (hex->roll != highlight_info->old_highlight
 	    && hex->roll != gmap->highlight_chit)
 		return FALSE;
 
-	display_hex(gmap->map, hex, gmap);
+	display_hex(hex, gmap);
 
 	poly.points = points;
 	poly.num_points = G_N_ELEMENTS(points);
@@ -1598,8 +1598,7 @@ void guimap_highlight_chits(GuiMap * gmap, gint roll)
 	closure.old_highlight = gmap->highlight_chit;
 	gmap->highlight_chit = roll;
 	if (gmap->pixmap != NULL)
-		map_traverse(gmap->map, (HexFunc) highlight_chits,
-			     &closure);
+		map_traverse_const(gmap->map, highlight_chits, &closure);
 }
 
 void guimap_draw_hex(GuiMap * gmap, const Hex * hex)
@@ -1612,7 +1611,7 @@ void guimap_draw_hex(GuiMap * gmap, const Hex * hex)
 	if (hex == NULL)
 		return;
 
-	display_hex(gmap->map, hex, gmap);
+	display_hex(hex, gmap);
 
 	poly.points = points;
 	poly.num_points = G_N_ELEMENTS(points);
--- common/map.c.orig	Sun Aug  5 11:56:34 2007
+++ common/map.c	Mon Jan 21 09:30:47 2008
@@ -37,8 +37,18 @@ Hex *map_hex(Map * map, gint x, gint y)
 	return map->grid[y][x];
 }
 
-Hex *hex_in_direction(Map * map, const Hex * hex, HexDirection direction)
+const Hex *map_hex_const(const Map * map, gint x, gint y)
 {
+	if (x < 0 || x >= map->x_size || y < 0 || y >= map->y_size)
+		return NULL;
+
+	return map->grid[y][x];
+}
+
+/** Returns the hex in the given direction, or NULL
+ */
+Hex *hex_in_direction(const Hex * hex, HexDirection direction)
+{
 	gint x = hex->x;
 	gint y = hex->y;
 
@@ -70,7 +80,7 @@ Hex *hex_in_direction(Map * map, const Hex * hex, HexD
 		y++;
 		break;
 	}
-	return map_hex(map, x, y);
+	return map_hex(hex->map, x, y);
 }
 
 Node *map_node(Map * map, gint x, gint y, gint pos)
@@ -87,6 +97,20 @@ Node *map_node(Map * map, gint x, gint y, gint pos)
 	return hex->nodes[pos];
 }
 
+const Node *map_node_const(const Map * map, gint x, gint y, gint pos)
+{
+	const Hex *hex;
+
+	if (x < 0 || x >= map->x_size
+	    || y < 0 || y >= map->y_size || pos < 0 || pos >= 6)
+		return NULL;
+
+	hex = map->grid[y][x];
+	if (hex == NULL)
+		return NULL;
+	return hex->nodes[pos];
+}
+
 Edge *map_edge(Map * map, gint x, gint y, gint pos)
 {
 	Hex *hex;
@@ -101,12 +125,26 @@ Edge *map_edge(Map * map, gint x, gint y, gint pos)
 	return hex->edges[pos];
 }
 
-/* Traverse the map and perform processing at a each node.
+const Edge *map_edge_const(const Map * map, gint x, gint y, gint pos)
+{
+	const Hex *hex;
+
+	if (x < 0 || x >= map->x_size
+	    || y < 0 || y >= map->y_size || pos < 0 || pos >= 6)
+		return NULL;
+
+	hex = map->grid[y][x];
+	if (hex == NULL)
+		return NULL;
+	return hex->edges[pos];
+}
+
+/** Traverse the map and perform processing at a each node.
  *
  * If the callback function returns TRUE, stop traversal immediately
  * and return TRUE to caller,
  */
-gboolean map_traverse(Map * map, HexFunc func, void *closure)
+gboolean map_traverse(Map * map, HexFunc func, gpointer closure)
 {
 	gint x;
 
@@ -117,7 +155,7 @@ gboolean map_traverse(Map * map, HexFunc func, void *c
 			Hex *hex;
 
 			hex = map->grid[y][x];
-			if (hex != NULL && func(map, hex, closure))
+			if (hex != NULL && func(hex, closure))
 				return TRUE;
 		}
 	}
@@ -125,6 +163,32 @@ gboolean map_traverse(Map * map, HexFunc func, void *c
 	return FALSE;
 }
 
+/** Traverse the map and perform processing at a each node.
+ * The map is unmodified.
+ *
+ * If the callback function returns TRUE, stop traversal immediately
+ * and return TRUE to caller,
+ */
+gboolean map_traverse_const(const Map * map, ConstHexFunc func,
+			    gpointer closure)
+{
+	gint x;
+
+	for (x = 0; x < map->x_size; x++) {
+		gint y;
+
+		for (y = 0; y < map->y_size; y++) {
+			const Hex *hex;
+
+			hex = map->grid[y][x];
+			if (hex != NULL && func(hex, closure))
+				return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
 /* The x.y grid of hexes are joined into a network, with adjacent
  * hexes are numbered 0 to 5.  The x and y coordinate offsets to each
  * adjacent hex depend on whether the current hex is at an even or odd
@@ -216,14 +280,13 @@ static ChainPart node_chain[] = {
 
 /* Build ring of nodes and edges around the current hex
  */
-static gboolean build_network(Map * map, Hex * hex,
-			      G_GNUC_UNUSED void *closure)
+static gboolean build_network(Hex * hex, G_GNUC_UNUSED gpointer closure)
 {
 	Hex *adjacent[6];
 	gint idx;
 	ChainPart *part;
 
-	calc_adjacent(map, hex->x, hex->y, adjacent);
+	calc_adjacent(hex->map, hex->x, hex->y, adjacent);
 
 	for (idx = 0, part = node_chain; idx < 6; idx++, part++) {
 		Node *node = NULL;
@@ -236,7 +299,7 @@ static gboolean build_network(Map * map, Hex * hex,
 			    adjacent[(idx + 1) % 6]->nodes[part->hex1_pos];
 		if (node == NULL) {
 			node = g_malloc0(sizeof(*node));
-			node->map = map;
+			node->map = hex->map;
 			node->owner = -1;
 			node->x = hex->x;
 			node->y = hex->y;
@@ -249,7 +312,7 @@ static gboolean build_network(Map * map, Hex * hex,
 			edge = adjacent[idx]->edges[opposite(idx)];
 		if (edge == NULL) {
 			edge = g_malloc0(sizeof(*edge));
-			edge->map = map;
+			edge->map = hex->map;
 			edge->owner = -1;
 			edge->x = hex->x;
 			edge->y = hex->y;
@@ -286,14 +349,13 @@ static ChainConnect node_connect[] = {
 
 /* Connect the the ring of nodes and edges to each other
  */
-static gboolean connect_network(Map * map, Hex * hex,
-				G_GNUC_UNUSED void *closure)
+static gboolean connect_network(Hex * hex, G_GNUC_UNUSED gpointer closure)
 {
 	Hex *adjacent[6];
 	gint idx;
 	ChainConnect *connect;
 
-	calc_adjacent(map, hex->x, hex->y, adjacent);
+	calc_adjacent(hex->map, hex->x, hex->y, adjacent);
 
 	for (idx = 0, connect = node_connect; idx < 6; idx++, connect++) {
 		Node *node;
@@ -530,7 +592,13 @@ Map *map_new(void)
 	return g_malloc0(sizeof(Map));
 }
 
-static Hex *copy_hex(Map * map, Hex * hex)
+/** Copy a hex.
+ * @param map The new owner
+ * @param hex The original hex
+ * @return A copy of the original hex, with the new owner. 
+ *         The copy is not connected (nodes and edges are NULL)
+*/
+static Hex *copy_hex(Map * map, const Hex * hex)
 {
 	Hex *copy;
 
@@ -551,18 +619,20 @@ static Hex *copy_hex(Map * map, Hex * hex)
 	return copy;
 }
 
-static gboolean set_nosetup_nodes(G_GNUC_UNUSED Map * map, Hex * hex,
-				  Map * copy)
+static gboolean set_nosetup_nodes(const Hex * hex, gpointer closure)
 {
 	gint idx;
+	Map *copy = closure;
 	for (idx = 0; idx < G_N_ELEMENTS(hex->nodes); ++idx) {
-		Node *node = hex->nodes[idx];
+		const Node *node = hex->nodes[idx];
 		/* only handle nodes which are owned by the hex, to
 		 * prevent doing every node three times */
 		if (hex->x != node->x || hex->y != node->y)
 			continue;
-		map_node(copy, node->x, node->y, node->pos)->no_setup
-		    = node->no_setup;
+		g_assert(map_node(copy, node->x, node->y, node->pos) !=
+			 NULL);
+		map_node(copy, node->x, node->y, node->pos)->no_setup =
+		    node->no_setup;
 	}
 	return FALSE;
 }
@@ -580,7 +650,7 @@ static GArray *copy_int_list(GArray * array)
 
 /* Make a copy of an existing map
  */
-Map *map_copy(Map * map)
+Map *map_copy(const Map * map)
 {
 	Map *copy = map_new();
 	int x, y;
@@ -593,7 +663,7 @@ Map *map_copy(Map * map)
 			copy->grid[y][x] = copy_hex(copy, map->grid[y][x]);
 	map_traverse(copy, build_network, NULL);
 	map_traverse(copy, connect_network, NULL);
-	map_traverse(map, (HexFunc) set_nosetup_nodes, copy);
+	map_traverse_const(map, set_nosetup_nodes, copy);
 	if (map->robber_hex == NULL)
 		copy->robber_hex = NULL;
 	else
@@ -882,16 +952,15 @@ gboolean map_parse_finish(Map * map)
 	return success;
 }
 
-/* Disconnect a hex from all nodes and edges that it does not "own"
+/** Disconnect a hex from all nodes and edges that it does not "own"
  */
-static gboolean disconnect_hex(G_GNUC_UNUSED Map * map, Hex * hex,
-			       G_GNUC_UNUSED void *closure)
+static gboolean disconnect_hex(Hex * hex, G_GNUC_UNUSED gpointer closure)
 {
 	gint idx;
 
 	for (idx = 0; idx < 6; idx++) {
-		const Node *node = hex->nodes[idx];
-		const Edge *edge = hex->edges[idx];
+		Node *node = hex->nodes[idx];
+		Edge *edge = hex->edges[idx];
 
 		if (node && (node->x != hex->x || node->y != hex->y))
 			hex->nodes[idx] = NULL;
@@ -902,10 +971,9 @@ static gboolean disconnect_hex(G_GNUC_UNUSED Map * map
 	return FALSE;
 }
 
-/* Free a node and all of the hexes and nodes that it is connected to.
+/** Free a node and all of the hexes and nodes that it is connected to.
  */
-static gboolean free_hex(G_GNUC_UNUSED Map * map, Hex * hex,
-			 G_GNUC_UNUSED void *closure)
+static gboolean free_hex(Hex * hex, G_GNUC_UNUSED gpointer closure)
 {
 	gint idx;
 
@@ -944,7 +1012,7 @@ Hex *map_add_hex(Map * map, gint x, gint y)
 	hex->y = y;
 	hex->x = x;
 	map->grid[y][x] = hex;
-	build_network(map, hex, NULL);
-	connect_network(map, hex, NULL);
+	build_network(hex, NULL);
+	connect_network(hex, NULL);
 	return hex;
 }
--- common/map.h.orig	Sun Aug  5 11:56:34 2007
+++ common/map.h	Mon Jan 21 09:30:47 2008
@@ -167,11 +167,17 @@ typedef enum {
 /* map.c
  */
 Hex *map_hex(Map * map, gint x, gint y);
-Hex *hex_in_direction(Map * map, const Hex * hex, HexDirection direction);
+const Hex *map_hex_const(const Map * map, gint x, gint y);
+Hex *hex_in_direction(const Hex * hex, HexDirection direction);
 Edge *map_edge(Map * map, gint x, gint y, gint pos);
+const Edge *map_edge_const(const Map * map, gint x, gint y, gint pos);
 Node *map_node(Map * map, gint x, gint y, gint pos);
-typedef gboolean(*HexFunc) (Map * map, Hex * hex, void *closure);
-gboolean map_traverse(Map * map, HexFunc func, void *closure);
+const Node *map_node_const(const Map * map, gint x, gint y, gint pos);
+typedef gboolean(*HexFunc) (Hex * hex, gpointer closure);
+gboolean map_traverse(Map * map, HexFunc func, gpointer closure);
+typedef gboolean(*ConstHexFunc) (const Hex * hex, gpointer closure);
+gboolean map_traverse_const(const Map * map, ConstHexFunc func,
+			    gpointer closure);
 void map_shuffle_terrain(Map * map);
 Hex *map_robber_hex(Map * map);
 Hex *map_pirate_hex(Map * map);
@@ -179,7 +185,7 @@ void map_move_robber(Map * map, gint x, gint y);
 void map_move_pirate(Map * map, gint x, gint y);
 
 Map *map_new(void);
-Map *map_copy(Map * map);
+Map *map_copy(const Map * map);
 gchar *map_format_line(Map * map, gboolean write_secrets, gint y);
 gboolean map_parse_line(Map * map, const gchar * line);
 gboolean map_parse_finish(Map * map);
@@ -214,33 +220,33 @@ gboolean can_city_be_built(const Node * node, int owne
 gboolean can_city_wall_be_built(const Node * node, int owner);
 gboolean can_robber_or_pirate_be_moved(const Hex * hex);
 /* map global queries */
-gboolean map_can_place_road(Map * map, int owner);
-gboolean map_can_place_ship(Map * map, int owner);
-gboolean map_can_place_bridge(Map * map, int owner);
-gboolean map_can_place_settlement(Map * map, int owner);
-gboolean map_can_place_city_wall(Map * map, int owner);
-gboolean map_can_upgrade_settlement(Map * map, int owner);
+gboolean map_can_place_road(const Map * map, gint owner);
+gboolean map_can_place_ship(const Map * map, gint owner);
+gboolean map_can_place_bridge(const Map * map, gint owner);
+gboolean map_can_place_settlement(const Map * map, gint owner);
+gboolean map_can_place_city_wall(const Map * map, gint owner);
+gboolean map_can_upgrade_settlement(const Map * map, gint owner);
 
 gboolean map_building_spacing_ok(Map * map, gint owner, BuildType type,
 				 gint x, gint y, gint pos);
-gboolean map_building_connect_ok(Map * map, gint owner, BuildType type,
-				 gint x, gint y, gint pos);
-gboolean map_building_vacant(Map * map, BuildType type,
-			     gint x, gint y, gint pos);
+gboolean map_building_connect_ok(const Map * map, gint owner, gint x,
+				 gint y, gint pos);
+gboolean map_building_vacant(Map * map, BuildType type, gint x, gint y,
+			     gint pos);
 gboolean map_road_vacant(Map * map, gint x, gint y, gint pos);
-gboolean map_road_connect_ok(Map * map, gint owner, gint x, gint y,
+gboolean map_road_connect_ok(const Map * map, gint owner, gint x, gint y,
 			     gint pos);
 gboolean map_ship_vacant(Map * map, gint x, gint y, gint pos);
-gboolean map_ship_connect_ok(Map * map, gint owner, gint x, gint y,
+gboolean map_ship_connect_ok(const Map * map, gint owner, gint x, gint y,
 			     gint pos);
 gboolean map_bridge_vacant(Map * map, gint x, gint y, gint pos);
-gboolean map_bridge_connect_ok(Map * map, gint owner, gint x, gint y,
+gboolean map_bridge_connect_ok(const Map * map, gint owner, gint x, gint y,
 			       gint pos);
 /* information gathering */
 void map_longest_road(Map * map, gint * lengths, gint num_players);
 gboolean map_is_island_discovered(Map * map, Node * node, gint owner);
-void map_maritime_info(Map * map, MaritimeInfo * info, gint owner);
-guint map_count_islands(Map * map);
+void map_maritime_info(const Map * map, MaritimeInfo * info, gint owner);
+guint map_count_islands(const Map * map);
 
 extern GRand *g_rand_ctx;
 
--- common/map_query.c.orig	Sun Aug  5 11:56:34 2007
+++ common/map_query.c	Mon Jan 21 09:30:47 2008
@@ -610,10 +610,10 @@ gboolean can_robber_or_pirate_be_moved(const Hex * hex
 
 /* Iterator function for map_can_place_road() query
  */
-static gboolean can_place_road_check(G_GNUC_UNUSED Map * map, Hex * hex,
-				     gint * owner)
+static gboolean can_place_road_check(const Hex * hex, void *closure)
 {
 	gint idx;
+	gint *owner = closure;
 
 	g_return_val_if_fail(hex != NULL, FALSE);
 	g_return_val_if_fail(owner != NULL, FALSE);
@@ -625,10 +625,10 @@ static gboolean can_place_road_check(G_GNUC_UNUSED Map
 
 /* Iterator function for map_can_place_ship() query
  */
-static gboolean can_place_ship_check(G_GNUC_UNUSED Map * map, Hex * hex,
-				     gint * owner)
+static gboolean can_place_ship_check(const Hex * hex, void *closure)
 {
 	gint idx;
+	gint *owner = closure;
 
 	g_return_val_if_fail(hex != NULL, FALSE);
 	g_return_val_if_fail(owner != NULL, FALSE);
@@ -640,10 +640,10 @@ static gboolean can_place_ship_check(G_GNUC_UNUSED Map
 
 /* Iterator function for map_can_place_bridge() query
  */
-static gboolean can_place_bridge_check(G_GNUC_UNUSED Map * map, Hex * hex,
-				       gint * owner)
+static gboolean can_place_bridge_check(const Hex * hex, void *closure)
 {
 	gint idx;
+	gint *owner = closure;
 
 	g_return_val_if_fail(hex != NULL, FALSE);
 	g_return_val_if_fail(owner != NULL, FALSE);
@@ -658,10 +658,10 @@ static gboolean can_place_bridge_check(G_GNUC_UNUSED M
  * Determine if there are any edges on the map where a player can
  * place a road.
  */
-gboolean map_can_place_road(Map * map, gint owner)
+gboolean map_can_place_road(const Map * map, gint owner)
 {
 	g_return_val_if_fail(map != NULL, FALSE);
-	return map_traverse(map, (HexFunc) can_place_road_check, &owner);
+	return map_traverse_const(map, can_place_road_check, &owner);
 }
 
 /* Query.
@@ -669,10 +669,10 @@ gboolean map_can_place_road(Map * map, gint owner)
  * Determine if there are any edges on the map where a player can
  * place a ship.
  */
-gboolean map_can_place_ship(Map * map, gint owner)
+gboolean map_can_place_ship(const Map * map, gint owner)
 {
 	g_return_val_if_fail(map != NULL, FALSE);
-	return map_traverse(map, (HexFunc) can_place_ship_check, &owner);
+	return map_traverse_const(map, can_place_ship_check, &owner);
 }
 
 /* Query.
@@ -680,18 +680,18 @@ gboolean map_can_place_ship(Map * map, gint owner)
  * Determine if there are any edges on the map where a player can
  * place a bridge.
  */
-gboolean map_can_place_bridge(Map * map, gint owner)
+gboolean map_can_place_bridge(const Map * map, gint owner)
 {
 	g_return_val_if_fail(map != NULL, FALSE);
-	return map_traverse(map, (HexFunc) can_place_bridge_check, &owner);
+	return map_traverse_const(map, can_place_bridge_check, &owner);
 }
 
 /* Iterator function for map_can_place_settlement() query
  */
-static gboolean can_place_settlement_check(G_GNUC_UNUSED Map * map,
-					   Hex * hex, gint * owner)
+static gboolean can_place_settlement_check(const Hex * hex, void *closure)
 {
 	gint idx;
+	gint *owner = (gint *) closure;
 
 	g_return_val_if_fail(hex != NULL, FALSE);
 	g_return_val_if_fail(owner != NULL, FALSE);
@@ -706,19 +706,19 @@ static gboolean can_place_settlement_check(G_GNUC_UNUS
  * Determine if there are any nodes on the map where a player can
  * place a settlement
  */
-gboolean map_can_place_settlement(Map * map, gint owner)
+gboolean map_can_place_settlement(const Map * map, gint owner)
 {
 	g_return_val_if_fail(map != NULL, FALSE);
-	return map_traverse(map, (HexFunc) can_place_settlement_check,
-			    &owner);
+	return map_traverse_const(map, can_place_settlement_check, &owner);
 }
 
 /* Iterator function for map_can_upgrade_settlement() query
  */
-static gboolean can_upgrade_settlement_check(G_GNUC_UNUSED Map * map,
-					     Hex * hex, gint * owner)
+static gboolean can_upgrade_settlement_check(const Hex * hex,
+					     void *closure)
 {
 	gint idx;
+	gint *owner = closure;
 
 	g_return_val_if_fail(hex != NULL, FALSE);
 	g_return_val_if_fail(owner != NULL, FALSE);
@@ -733,19 +733,19 @@ static gboolean can_upgrade_settlement_check(G_GNUC_UN
  * Determine if there are any nodes on the map where a player can
  * upgrade a settlement
  */
-gboolean map_can_upgrade_settlement(Map * map, gint owner)
+gboolean map_can_upgrade_settlement(const Map * map, gint owner)
 {
 	g_return_val_if_fail(map != NULL, FALSE);
-	return map_traverse(map, (HexFunc) can_upgrade_settlement_check,
-			    &owner);
+	return map_traverse_const(map, can_upgrade_settlement_check,
+				  &owner);
 }
 
 /* Iterator function for map_can_place_city_wall() query
  */
-static gboolean can_place_city_wall_check(G_GNUC_UNUSED Map * map,
-					  Hex * hex, gint * owner)
+static gboolean can_place_city_wall_check(const Hex * hex, void *closure)
 {
 	gint idx;
+	gint *owner = closure;
 
 	g_return_val_if_fail(hex != NULL, FALSE);
 	g_return_val_if_fail(owner != NULL, FALSE);
@@ -760,11 +760,10 @@ static gboolean can_place_city_wall_check(G_GNUC_UNUSE
  * Determine if there are any nodes on the map where a player can
  * place a settlement
  */
-gboolean map_can_place_city_wall(Map * map, gint owner)
+gboolean map_can_place_city_wall(const Map * map, gint owner)
 {
 	g_return_val_if_fail(map != NULL, FALSE);
-	return map_traverse(map, (HexFunc) can_place_city_wall_check,
-			    &owner);
+	return map_traverse_const(map, can_place_city_wall_check, &owner);
 }
 
 /* Ignoring road connectivity, decide whether or not a settlement/city
@@ -794,13 +793,12 @@ gboolean map_building_spacing_ok(Map * map, gint owner
 
 /* Ignoring building spacing, check if the building connects to a road.
  */
-gboolean map_building_connect_ok(Map * map, gint owner,
-				 G_GNUC_UNUSED BuildType type, gint x,
+gboolean map_building_connect_ok(const Map * map, gint owner, gint x,
 				 gint y, gint pos)
 {
-	Node *node;
+	const Node *node;
 	g_return_val_if_fail(map != NULL, FALSE);
-	node = map_node(map, x, y, pos);
+	node = map_node_const(map, x, y, pos);
 	if (node == NULL)
 		return FALSE;
 
@@ -868,12 +866,12 @@ gboolean map_bridge_vacant(Map * map, gint x, gint y, 
 /* Ignoring whether or not a road already exists at this point, check
  * that it has the right connectivity.
  */
-gboolean map_road_connect_ok(Map * map, gint owner, gint x, gint y,
+gboolean map_road_connect_ok(const Map * map, gint owner, gint x, gint y,
 			     gint pos)
 {
-	Edge *edge;
+	const Edge *edge;
 	g_return_val_if_fail(map != NULL, FALSE);
-	edge = map_edge(map, x, y, pos);
+	edge = map_edge_const(map, x, y, pos);
 	if (edge == NULL)
 		return FALSE;
 
@@ -883,12 +881,12 @@ gboolean map_road_connect_ok(Map * map, gint owner, gi
 /* Ignoring whether or not a ship already exists at this point, check
  * that it has the right connectivity.
  */
-gboolean map_ship_connect_ok(Map * map, gint owner, gint x, gint y,
+gboolean map_ship_connect_ok(const Map * map, gint owner, gint x, gint y,
 			     gint pos)
 {
-	Edge *edge;
+	const Edge *edge;
 	g_return_val_if_fail(map != NULL, FALSE);
-	edge = map_edge(map, x, y, pos);
+	edge = map_edge_const(map, x, y, pos);
 	if (edge == NULL)
 		return FALSE;
 
@@ -898,12 +896,12 @@ gboolean map_ship_connect_ok(Map * map, gint owner, gi
 /* Ignoring whether or not a bridge already exists at this point, check
  * that it has the right connectivity.
  */
-gboolean map_bridge_connect_ok(Map * map, gint owner, gint x, gint y,
+gboolean map_bridge_connect_ok(const Map * map, gint owner, gint x, gint y,
 			       gint pos)
 {
-	Edge *edge;
+	const Edge *edge;
 	g_return_val_if_fail(map != NULL, FALSE);
-	edge = map_edge(map, x, y, pos);
+	edge = map_edge_const(map, x, y, pos);
 	if (edge == NULL)
 		return FALSE;
 
@@ -965,10 +963,10 @@ static gint find_longest_road_recursive(Edge * edge)
 	return len + 1;
 }
 
-static gboolean find_longest_road(G_GNUC_UNUSED Map * map, Hex * hex,
-				  gint * lengths)
+static gboolean find_longest_road(Hex * hex, gpointer closure)
 {
 	gint idx;
+	gint *lengths = closure;
 	g_return_val_if_fail(hex != NULL, FALSE);
 	g_return_val_if_fail(lengths != NULL, FALSE);
 	for (idx = 0; idx < G_N_ELEMENTS(hex->edges); idx++) {
@@ -988,8 +986,7 @@ static gboolean find_longest_road(G_GNUC_UNUSED Map * 
 
 /* Zero the visited attribute for all edges and nodes.
  */
-static gboolean zero_visited(G_GNUC_UNUSED Map * map, Hex * hex,
-			     G_GNUC_UNUSED void *closure)
+static gboolean zero_visited(Hex * hex, G_GNUC_UNUSED gpointer closure)
 {
 	gint idx;
 
@@ -1015,9 +1012,9 @@ void map_longest_road(Map * map, gint * lengths, gint 
 	g_return_if_fail(map != NULL);
 	g_return_if_fail(lengths != NULL);
 
-	map_traverse(map, (HexFunc) zero_visited, NULL);
+	map_traverse(map, zero_visited, NULL);
 	memset(lengths, 0, num_players * sizeof(*lengths));
-	map_traverse(map, (HexFunc) find_longest_road, lengths);
+	map_traverse(map, find_longest_road, lengths);
 }
 
 static gboolean map_island_recursive(Map * map, Node * node, gint owner)
@@ -1081,15 +1078,16 @@ gboolean map_is_island_discovered(Map * map, Node * no
 {
 	g_return_val_if_fail(map != NULL, FALSE);
 	g_return_val_if_fail(node != NULL, FALSE);
-	map_traverse(map, (HexFunc) zero_visited, NULL);
+	map_traverse(map, zero_visited, NULL);
 	return map_island_recursive(map, node, owner);
 }
 
 /* Determine the maritime trading capabilities for the specified player
  */
-static gboolean find_maritime(G_GNUC_UNUSED Map * map, Hex * hex,
-			      MaritimeInfo * info)
+static gboolean find_maritime(const Hex * hex, gpointer closure)
 {
+	MaritimeInfo *info = closure;
+
 	g_return_val_if_fail(hex != NULL, FALSE);
 	g_return_val_if_fail(info != NULL, FALSE);
 
@@ -1110,13 +1108,13 @@ static gboolean find_maritime(G_GNUC_UNUSED Map * map,
 
 /* Determine the maritime trading capacity of the specified player
  */
-void map_maritime_info(Map * map, MaritimeInfo * info, gint owner)
+void map_maritime_info(const Map * map, MaritimeInfo * info, gint owner)
 {
 	g_return_if_fail(map != NULL);
 	g_return_if_fail(info != NULL);
 	memset(info, 0, sizeof(*info));
 	info->owner = owner;
-	map_traverse(map, (HexFunc) find_maritime, info);
+	map_traverse_const(map, find_maritime, info);
 }
 
 typedef struct {
@@ -1125,16 +1123,16 @@ typedef struct {
 	guint recursion_level;
 } IslandCount;
 
-static gboolean count_islands(Map * map, Hex * hex, gpointer info)
+static gboolean count_islands(const Hex * hex, gpointer info)
 {
 	IslandCount *count = info;
 	HexDirection direction;
 
-	g_return_val_if_fail(map != NULL, FALSE);
-
 	if (hex == NULL)
 		return FALSE;
 
+	g_return_val_if_fail(hex->map != NULL, FALSE);
+
 	if (count->visited[hex->y][hex->x])
 		return FALSE;
 
@@ -1144,8 +1142,7 @@ static gboolean count_islands(Map * map, Hex * hex, gp
 	count->visited[hex->y][hex->x] = TRUE;
 	count->recursion_level++;
 	for (direction = 0; direction < 6; direction++) {
-		count_islands(map, hex_in_direction(map, hex, direction),
-			      count);
+		count_islands(hex_in_direction(hex, direction), count);
 	}
 	count->recursion_level--;
 	if (count->recursion_level == 0)
@@ -1153,7 +1150,7 @@ static gboolean count_islands(Map * map, Hex * hex, gp
 	return FALSE;
 }
 
-guint map_count_islands(Map * map)
+guint map_count_islands(const Map * map)
 {
 	IslandCount island_count;
 
@@ -1163,7 +1160,7 @@ guint map_count_islands(Map * map)
 	island_count.count = 0;
 	island_count.recursion_level = 0;
 
-	map_traverse(map, count_islands, &island_count);
+	map_traverse_const(map, count_islands, &island_count);
 
 	return island_count.count;
 }
--- editor/gtk/editor.c.orig	Sun Aug  5 11:56:34 2007
+++ editor/gtk/editor.c	Mon Jan 21 09:30:47 2008
@@ -248,7 +248,7 @@ static gint button_press_map_cb(GtkWidget * area, GdkE
 {
 	GuiMap *gmap = user_data;
 	GtkWidget *menu;
-	Hex *adjacent;
+	const Hex *adjacent;
 	gboolean port_ok;
 	gint num_ports;
 	gint i;
@@ -276,8 +276,7 @@ static gint button_press_map_cb(GtkWidget * area, GdkE
 	} else if (current_hex->terrain == SEA_TERRAIN) {
 		num_ports = 0;
 		for (i = 0; i < 6; i++) {
-			adjacent = hex_in_direction(gmap->map,
-						    current_hex, i);
+			adjacent = hex_in_direction(current_hex, i);
 			port_ok = FALSE;
 			if (adjacent != NULL &&
 			    adjacent->terrain != LAST_TERRAIN &&
@@ -452,8 +451,7 @@ static gint select_terrain_cb(G_GNUC_UNUSED GtkWidget 
 		current_hex->resource = NO_RESOURCE;
 	if (terrain == SEA_TERRAIN || terrain == LAST_TERRAIN) {
 		for (i = 0; i < 6; i++) {
-			adjacent =
-			    hex_in_direction(gmap->map, current_hex, i);
+			adjacent = hex_in_direction(current_hex, i);
 			if (adjacent != NULL
 			    && adjacent->resource != NO_RESOURCE
 			    && adjacent->facing == (i + 3) % 6) {
@@ -578,10 +576,9 @@ static gint select_port_resource_cb(G_GNUC_UNUSED GtkW
 
 	if (current_hex->resource == NO_RESOURCE) {
 		for (i = 0; i < 6; i++) {
-			Hex *adjacent;
+			const Hex *adjacent;
 
-			adjacent = hex_in_direction(gmap->map,
-						    current_hex, i);
+			adjacent = hex_in_direction(current_hex, i);
 			if (adjacent != NULL &&
 			    adjacent->terrain != LAST_TERRAIN &&
 			    adjacent->terrain != SEA_TERRAIN) {
--- server/gtk/main.c.orig	Sun Aug  5 11:56:34 2007
+++ server/gtk/main.c	Mon Jan 21 09:30:47 2008
@@ -267,6 +267,7 @@ static void start_clicked_cb(G_GNUC_UNUSED GtkButton *
 		update_game_settings(params);
 
 		g_assert(server_port != NULL);
+
 		if (start_server
 		    (params, overridden_hostname, server_port,
 		     register_server, meta_server_name, random_order)) {
@@ -431,12 +432,8 @@ static void overridden_hostname_changed_cb(GtkEntry * 
 static void meta_server_changed_cb(GtkWidget * widget,
 				   G_GNUC_UNUSED gpointer user_data)
 {
-	const gchar *text;
-
-	text = gtk_entry_get_text(GTK_ENTRY(widget));
-	while (*text != '\0' && isspace(*text))
-		text++;
-	meta_server_name = text;
+	meta_server_name =
+	    g_strstrip(g_strdup(gtk_entry_get_text(GTK_ENTRY(widget))));
 }
 
 static GtkWidget *build_game_settings(GtkWidget * parent,
--- server/player.c.orig	Sun Oct  7 19:56:39 2007
+++ server/player.c	Mon Jan 21 09:32:07 2008
@@ -616,7 +616,10 @@ void player_revive(Player * newp, char *name)
 	newp->sm->stack_ptr = p->sm->stack_ptr;
 	newp->sm->current_state = p->sm->current_state;
 
-	sm_push(newp->sm, (StateFunc) mode_pre_game);
+	if (sm_current(newp->sm) != (StateFunc) mode_pre_game)
+		sm_push(newp->sm, (StateFunc) mode_pre_game);
+	else
+		sm_goto(newp->sm, (StateFunc) mode_pre_game);
 
 	/* Copy longest road and largest army */
 	if (game->longest_road == p)
--- server/pregame.c.orig	Wed Oct  3 22:33:36 2007
+++ server/pregame.c	Mon Jan 21 09:30:47 2008
@@ -57,9 +57,9 @@ static void build_add(Player * player, BuildType type,
 		/* Building a road, make sure it is next to a
 		 * settlement/road
 		 */
-		if (!buildrec_can_setup_road(player->build_list, map,
-					     map_edge(map, x, y, pos),
-					     game->double_setup)) {
+		if (!buildrec_can_setup_road
+		    (player->build_list, map_edge(map, x, y, pos),
+		     game->double_setup)) {
 			player_send(player, FIRST_VERSION, LATEST_VERSION,
 				    "ERR bad-pos\n");
 			return;
@@ -80,9 +80,9 @@ static void build_add(Player * player, BuildType type,
 		/* Building a bridge, make sure it is next to a
 		 * settlement/road
 		 */
-		if (!buildrec_can_setup_bridge(player->build_list, map,
-					       map_edge(map, x, y, pos),
-					       game->double_setup)) {
+		if (!buildrec_can_setup_bridge
+		    (player->build_list, map_edge(map, x, y, pos),
+		     game->double_setup)) {
 			player_send(player, FIRST_VERSION, LATEST_VERSION,
 				    "ERR bad-pos\n");
 			return;
@@ -103,9 +103,9 @@ static void build_add(Player * player, BuildType type,
 		/* Building a ship, make sure it is next to a
 		 * settlement/ship
 		 */
-		if (!buildrec_can_setup_ship(player->build_list, map,
-					     map_edge(map, x, y, pos),
-					     game->double_setup)) {
+		if (!buildrec_can_setup_ship
+		    (player->build_list, map_edge(map, x, y, pos),
+		     game->double_setup)) {
 			player_send(player, FIRST_VERSION, LATEST_VERSION,
 				    "ERR bad-pos\n");
 			return;
@@ -121,9 +121,9 @@ static void build_add(Player * player, BuildType type,
 	}
 	/* Build the settlement
 	 */
-	if (!buildrec_can_setup_settlement(player->build_list, map,
-					   map_node(map, x, y, pos),
-					   game->double_setup)) {
+	if (!buildrec_can_setup_settlement
+	    (player->build_list, map_node(map, x, y, pos),
+	     game->double_setup)) {
 		player_send(player, FIRST_VERSION, LATEST_VERSION,
 			    "ERR bad-pos\n");
 		return;
@@ -386,7 +386,7 @@ static void send_game_line(gpointer player, const gcha
 			     LATEST_VERSION, "%s\n", str);
 }
 
-gboolean send_gameinfo_uncached(Map * map, Hex * hex, void *data)
+gboolean send_gameinfo_uncached(const Hex * hex, void *data)
 {
 	gint i;
 	Player *player = data;
@@ -466,7 +466,7 @@ gboolean send_gameinfo_uncached(Map * map, Hex * hex, 
 				     "RO%d,%d\n", hex->x, hex->y);
 	}
 
-	if (hex == map->pirate_hex) {
+	if (hex == hex->map->pirate_hex) {
 		player_send_uncached(player, FIRST_VERSION, LATEST_VERSION,
 				     "P%d,%d\n", hex->x, hex->y);
 	}
@@ -548,7 +548,8 @@ gboolean mode_pre_game(Player * player, gint event)
 		if (sm_recv(sm, "gameinfo")) {
 			player_send_uncached(player, FIRST_VERSION,
 					     LATEST_VERSION, "gameinfo\n");
-			map_traverse(map, send_gameinfo_uncached, player);
+			map_traverse_const(map, send_gameinfo_uncached,
+					   player);
 			player_send_uncached(player, FIRST_VERSION,
 					     LATEST_VERSION, ".\n");
 
--- server/server.h.orig	Sun Aug  5 11:56:34 2007
+++ server/server.h	Mon Jan 21 09:30:47 2008
@@ -199,7 +199,7 @@ gboolean player_is_viewer(Game * game, gint player_num
 /* pregame.c */
 gboolean mode_pre_game(Player * player, gint event);
 gboolean mode_setup(Player * player, gint event);
-gboolean send_gameinfo_uncached(Map * map, Hex * hex, void *player);
+gboolean send_gameinfo_uncached(const Hex * hex, void *player);
 void next_setup_player(Game * game);
 
 /* resource.c */
--- server/trade.c.orig	Sun Aug  5 11:56:34 2007
+++ server/trade.c	Mon Jan 21 09:30:47 2008
@@ -28,7 +28,7 @@ void trade_perform_maritime(Player * player,
 			    gint ratio, Resource supply, Resource receive)
 {
 	Game *game = player->game;
-	Map *map = game->params->map;
+	const Map *map = game->params->map;
 	gint check[NO_RESOURCE];
 	MaritimeInfo info;
 
--- server/turn.c.orig	Sun Aug  5 11:56:34 2007
+++ server/turn.c	Mon Jan 21 09:30:47 2008
@@ -181,8 +181,7 @@ static void build_add(Player * player, BuildType type,
 	} else {
 		/* New building: make sure it connects to a road
 		 */
-		if (!map_building_connect_ok
-		    (map, player->num, type, x, y, pos)) {
+		if (!map_building_connect_ok(map, player->num, x, y, pos)) {
 			player_send(player, FIRST_VERSION, LATEST_VERSION,
 				    "ERR bad-pos\n");
 			return;
@@ -358,19 +357,19 @@ typedef struct {
 	int roll;
 } GameRoll;
 
-static gboolean distribute_resources(G_GNUC_UNUSED Map * map, Hex * hex,
-				     GameRoll * data)
+static gboolean distribute_resources(const Hex * hex, gpointer closure)
 {
 	int idx;
+	GameRoll *data = closure;
 
 	if (hex->roll != data->roll || hex->robber)
 		/* return false so the traverse function continues */
 		return FALSE;
 
 	for (idx = 0; idx < G_N_ELEMENTS(hex->nodes); idx++) {
-		Node *node = hex->nodes[idx];
+		const Node *node = hex->nodes[idx];
 		Player *player;
-		int num;
+		gint num;
 
 		if (node->type == BUILD_NONE)
 			continue;
@@ -440,7 +439,7 @@ gboolean mode_turn(Player * player, gint event)
 {
 	StateMachine *sm = player->sm;
 	Game *game = player->game;
-	Map *map = game->params->map;
+	const Map *map = game->params->map;
 	BuildType build_type;
 	DevelType devel_type;
 	gint x, y, pos;
@@ -497,7 +496,7 @@ gboolean mode_turn(Player * player, gint event)
 		resource_start(game);
 		data.game = game;
 		data.roll = roll;
-		map_traverse(map, (HexFunc) distribute_resources, &data);
+		map_traverse_const(map, distribute_resources, &data);
 		/* distribute resources and gold (includes resource_end) */
 		distribute_first(list_from_player(player));
 		return TRUE;
