Index: src/settings.cpp
===================================================================
--- src/settings.cpp	(revision 13552)
+++ src/settings.cpp	(working copy)
@@ -63,6 +63,8 @@
 #include "gamelog.h"
 #include "station_func.h"
 
+#include "sharedinfrastructure.h"
+
 #include "table/strings.h"
 
 ClientSettings _settings_client;
@@ -1747,7 +1749,27 @@
  SDT_CONDOMANY(GameSettings, locale.currency,                               SLE_UINT8, 97, SL_MAX_VERSION, N, 0, 0, CUSTOM_CURRENCY_ID, "GBP|USD|EUR|YEN|ATS|BEF|CHF|CZK|DEM|DKK|ESP|FIM|FRF|GRD|HUF|ISK|ITL|NLG|NOK|PLN|ROL|RUR|SIT|SEK|YTL|SKK|BRR|custom", STR_NULL, NULL, NULL),
  SDT_CONDOMANY(GameSettings, locale.units,                                  SLE_UINT8, 97, SL_MAX_VERSION, N, 0, 1, 2, "imperial|metric|si", STR_NULL, NULL, NULL),
 
+
 	/***************************************************************************/
+	/* Shared Infrastructure configure patches window */
+	SDT_CONDBOOL(GameSettings, sharing.shared_railway_stations,         123,SL_MAX_VERSION,   0, D0, false,            STR_CONFIG_PATCHES_SHARED_RAILWAY_STATIONS, SettingsEnableSharedRailwayStations),
+	SDT_CONDBOOL(GameSettings, sharing.shared_railway_tracks,           123,SL_MAX_VERSION,   0, D0, false,            STR_CONFIG_PATCHES_SHARED_RAILWAY_TRACKS, SettingsEnableSharedRailwayTracks),
+	SDT_CONDBOOL(GameSettings, sharing.shared_railway_depots,           123,SL_MAX_VERSION,   0, D0, false,            STR_CONFIG_PATCHES_SHARED_RAILWAY_DEPOTS, SettingsEnableSharedRailwayStations),
+	SDT_CONDBOOL(GameSettings, sharing.shared_road_depots,              123,SL_MAX_VERSION,   0, D0, false,            STR_CONFIG_PATCHES_SHARED_ROAD_DEPOTS, NULL),
+	SDT_CONDBOOL(GameSettings, sharing.shared_road_stops,               123,SL_MAX_VERSION,   0, D0, false,            STR_CONFIG_PATCHES_SHARED_ROAD_STOPS, NULL),
+	SDT_CONDBOOL(GameSettings, sharing.shared_water_depots,             123,SL_MAX_VERSION,   0, D0, false,            STR_CONFIG_PATCHES_SHARED_WATER_DEPOTS, NULL),
+	SDT_CONDBOOL(GameSettings, sharing.shared_harbours,                 123,SL_MAX_VERSION,   0, D0, false,            STR_CONFIG_PATCHES_SHARED_HARBOURS, NULL),
+	SDT_CONDBOOL(GameSettings, sharing.shared_airports,                 123,SL_MAX_VERSION,   0, D0, false,            STR_CONFIG_PATCHES_SHARED_AIRPORTS, NULL),
+	SDT_CONDVAR (GameSettings, sharing.shared_provision, SLE_UINT8,     123,SL_MAX_VERSION,   0, 0,  10,  0,  100,  5, STR_CONFIG_PATCHES_SHARED_PROVISION, NULL),
+	SDT_CONDVAR (GameSettings, sharing.shared_tontile_cost, SLE_UINT16, 123,SL_MAX_VERSION,   0, CR, 30,  0,  250,  5, STR_CONFIG_PATCHES_SHARED_TONTILE_COST, NULL),
+	SDT_CONDVAR (GameSettings, sharing.shared_landing_fee, SLE_UINT16,  123,SL_MAX_VERSION,   0, CR, 50,  0, 1000, 20, STR_CONFIG_PATCHES_SHARED_LANDING_FEE, NULL),
+	SDT_CONDVAR (GameSettings, sharing.shared_road_stops_fee, SLE_UINT8, 123,SL_MAX_VERSION,  0, CR,  5,  0,   50,  1, STR_CONFIG_PATCHES_SHARED_ROAD_STOPS_FEE, NULL),
+	SDT_CONDVAR (GameSettings, sharing.shared_harbours_fee,  SLE_UINT8, 123,SL_MAX_VERSION,   0, CR, 10,  0,  200,  5, STR_CONFIG_PATCHES_SHARED_HARBOURS_FEE, NULL),
+	SDT_CONDBOOL(GameSettings, sharing.shared_player_level,             123,SL_MAX_VERSION,   0, D0, false,            STR_CONFIG_PATCHES_SHARED_PLAYER_LEVEL, NULL),
+	SDT_CONDVAR (GameSettings, sharing.shared_delay, SLE_UINT8,         123,SL_MAX_VERSION,   0, 0,  6,   0,   60,  1, STR_CONFIG_PATCHES_SHARED_DELAY, NULL),
+
+
+	/***************************************************************************/
 	/* Unsaved patch variables. */
 	SDTC_OMANY(gui.autosave,                  SLE_UINT8, S,  0, 1, 4, "off|monthly|quarterly|half year|yearly", STR_NULL,                     NULL),
 	 SDTC_BOOL(gui.vehicle_speed,                        S,  0,  true,                        STR_CONFIG_PATCHES_VEHICLESPEED,                NULL),
@@ -1818,7 +1840,6 @@
 	  SDTC_STR(network.last_host,              SLE_STRB, S,  0, "0.0.0.0",                    STR_NULL,                                       NULL),
 	  SDTC_VAR(network.last_port,            SLE_UINT16, S,  0,     0,     0,  UINT16_MAX, 0, STR_NULL,                                       NULL),
 #endif /* ENABLE_NETWORK */
-
 	/*
 	 * Since the network code (CmdChangePatchSetting and friends) use the index in this array to decide
 	 * which patch the server is talking about all conditional compilation of this array must be at the
@@ -1830,7 +1851,6 @@
 	/* We might need to emulate a right mouse button on mac */
 	 SDTC_VAR(gui.right_mouse_btn_emulation, SLE_UINT8, S, MS, 0, 0, 2, 0, STR_CONFIG_PATCHES_RIGHT_MOUSE_BTN_EMU, NULL),
 #endif
-
 	SDT_END()
 };
 
Index: src/depot_base.h
===================================================================
--- src/depot_base.h	(revision 13552)
+++ src/depot_base.h	(working copy)
@@ -27,6 +27,8 @@
 	return index < GetDepotPoolSize() && GetDepot(index)->IsValid();
 }
 
+static const DepotID INVALID_DEPOT = 0xFFFF;
+
 Depot *GetDepotByTile(TileIndex tile);
 
 #define FOR_ALL_DEPOTS_FROM(d, start) for (d = GetDepot(start); d != NULL; d = (d->index + 1U < GetDepotPoolSize()) ? GetDepot(d->index + 1U) : NULL) if (d->IsValid())
Index: src/lang/english.txt
===================================================================
--- src/lang/english.txt	(revision 13552)
+++ src/lang/english.txt	(working copy)
@@ -2247,10 +2247,12 @@
 STR_7015_AIRCRAFT_RUNNING_COSTS                                 :{GOLD}Aircraft Running Costs
 STR_7016_SHIP_RUNNING_COSTS                                     :{GOLD}Ship Running Costs
 STR_7017_PROPERTY_MAINTENANCE                                   :{GOLD}Property Maintenance
+STR_7017_SHARED_INF_COSTS                                       :{GOLD}Shared Structure Costs
 STR_7018_TRAIN_INCOME                                           :{GOLD}Train Income
 STR_7019_ROAD_VEHICLES_INCOME                                   :{GOLD}Road Vehicle Income
 STR_701A_AIRCRAFT_INCOME                                        :{GOLD}Aircraft Income
 STR_701B_SHIP_INCOME                                            :{GOLD}Ship Income
+STR_701B_SHARED_INF_INCOME                                      :{GOLD}Shared Structure Income
 STR_701C_LOAN_INTEREST                                          :{GOLD}Loan Interest
 STR_701D_OTHER                                                  :{GOLD}Other
 STR_701E                                                        :{BLACK}-{CURRENCY}
@@ -2359,7 +2361,10 @@
 STR_707D_OWNED_BY                                               :{WHITE}({COMMA}% owned by {COMPANY})
 STR_707F_HAS_BEEN_TAKEN_OVER_BY                                 :{BLACK}{BIGFONT}{COMPANY} has been taken over by {COMPANY}!
 STR_PROTECTED                                                   :{WHITE}This company is not old enough to trade shares yet...
+STR_COMPANY_SHARING                                             :{BLACK}Sharing
+STR_SET_COMPANY_SHARING                                         :{BLACK}Settings for shared infrastructures.
 
+
 STR_LIVERY_DEFAULT                                              :Standard Livery
 STR_LIVERY_STEAM                                                :Steam Engine
 STR_LIVERY_DIESEL                                               :Diesel Engine
@@ -3568,3 +3573,63 @@
 STR_NOISE_IN_TOWN                                               :{BLACK}Noise limit in town: {ORANGE}{COMMA}{BLACK}  max: {ORANGE}{COMMA}
 STR_STATION_NOISE                                               :{BLACK}Noise generated: {GOLD}{COMMA}
 ########
+
+############ Sharing
+STR_CONFIG_PATCHES_SHARED_RAILWAY_STATIONS                      :{LTBLUE}Enable shared railway stations: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_SHARED_RAILWAY_TRACKS                        :{LTBLUE}Enable shared railway tracks: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_SHARED_RAILWAY_DEPOTS                        :{LTBLUE}Enable shared railway depots: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_SHARED_ROAD_DEPOTS                           :{LTBLUE}Enable shared road depots: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_SHARED_ROAD_STOPS                            :{LTBLUE}Enable shared road stops: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_SHARED_WATER_DEPOTS                          :{LTBLUE}Enable shared water depots: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_SHARED_HARBOURS                              :{LTBLUE}Enable shared harbours: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_SHARED_AIRPORTS                              :{LTBLUE}Enable shared airports: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_SHARED_PROVISION                             :{LTBLUE}Enable depot owner provision: {ORANGE}{STRING1}%
+STR_CONFIG_PATCHES_SHARED_TONTILE_COST                          :{LTBLUE}Cost of 1000 tontiles on shared track: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_SHARED_LANDING_FEE                           :{LTBLUE}Landing fee per tons of cargo capacity : {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_SHARED_ROAD_STOPS_FEE                        :{LTBLUE}Road stops fee per tons of cargo capacity : {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_SHARED_HARBOURS_FEE                          :{LTBLUE}Harbours fee per tons of cargo capacity : {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_SHARED_PLAYER_LEVEL                          :{LTBLUE}Enable individual sharing settings: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_SHARED                                       :{BLACK}Sharing
+STR_CONFIG_PATCHES_SHARED_DELAY                                 :{LTBLUE}Delay for individual settings:{ORANGE}{STRING1} month(s)
+
+STR_SHARED_INFRASTRUCTURE_SELECTION                             :{WHITE}Shared Infrastructure
+
+STR_SHARED_RAILWAY_STATIONS                                     :{BLACK}Share railway stations
+STR_SHARED_RAILWAY_TRACKS                                       :{BLACK}Share railway tracks
+STR_SHARED_RAILWAY_DEPOTS                                       :{BLACK}Share railway depots
+STR_SHARED_ROAD_DEPOTS                                          :{BLACK}Share road depots
+STR_SHARED_ROAD_STOPS                                           :{BLACK}Share road stops
+STR_SHARED_WATER_DEPOTS                                         :{BLACK}Share water depots
+STR_SHARED_HARBOURS                                             :{BLACK}Share harbours
+STR_SHARED_AIRPORTS                                             :{BLACK}Share airports
+STR_SHARED_DEPOT_PROVISION                                      :{BLACK}Depot provision (building cost %)
+STR_SHARED_TONTILE_COST                                         :{BLACK}Cost of 1000 tontiles on shared track
+STR_SHARED_LANDING_FEE                                          :{BLACK}Landing fee per tons of cargo capacity
+STR_SHARED_ROAD_STOPS_FEE                                       :{BLACK}Road stops fee per tons of cargo capacity
+STR_SHARED_HARBOURS_FEE                                         :{BLACK}Harbours fee per tons of cargo capacity
+STR_SHARED_ACCEPT                                               :{BLACK}Accept new settings (will reset previous counter if any)
+
+STR_SHARED_CHANGE_INT_VALUE                                     :{BLACK}{BIGFONT}{PLAYERNAME} has set new access prices ! check {COMPANY} for details.
+STR_SHARED_CHANGE_BOOL_VALUE                                    :{BLACK}{BIGFONT}{PLAYERNAME} has set new access conditions ! check {COMPANY} for details.
+
+STR_CONFIG_PLAYER_SHARED_RAILWAY_STATIONS                       :{GOLD}Railway stations:
+STR_CONFIG_PLAYER_SHARED_RAILWAY_TRACKS                         :{GOLD}Railway tracks:
+STR_CONFIG_PLAYER_SHARED_RAILWAY_DEPOTS                         :{GOLD}Railway depots:
+STR_CONFIG_PLAYER_SHARED_ROAD_DEPOTS                            :{GOLD}Road depots:
+STR_CONFIG_PLAYER_SHARED_ROAD_STOPS                             :{GOLD}Road stops:
+STR_CONFIG_PLAYER_SHARED_WATER_DEPOTS                           :{GOLD}Water depots:
+STR_CONFIG_PLAYER_SHARED_HARBOURS                               :{GOLD}Harbours:
+STR_CONFIG_PLAYER_SHARED_AIRPORTS                               :{GOLD}Airports:
+STR_CONFIG_PLAYER_SHARED_DEPOT_PROVISION                        :{GOLD}Depot provision: 
+STR_CONFIG_PLAYER_SHARED_TONTILE_COST                           :{GOLD}Tracks renting:
+STR_CONFIG_PLAYER_SHARED_LANDING_FEE                            :{GOLD}Landing fee:
+STR_CONFIG_PLAYER_SHARED_ROAD_STOPS_FEE                         :{GOLD}Road stops fee:
+STR_CONFIG_PLAYER_SHARED_HARBOURS_FEE                           :{GOLD}Harbours fee:
+STR_CONFIG_PLAYER_SHARED_NO_CHANGE                              :{GOLD}No change recorded for next {WHITE}{NUM}{GOLD} month(s)
+STR_CONFIG_PLAYER_SHARED_CHANGE_MONTHS                          :{GOLD}Change recorded and planned in {WHITE}{NUM}{GOLD} month(s)
+
+STR_JUST_VELOCITY												:{VELOCITY}
+STR_JUST_CURRENCY												:{CURRENCY}
+STR_JUST_PERCENT                                                :{NUM}%
+########
+
Index: src/settings_gui.cpp
===================================================================
--- src/settings_gui.cpp	(revision 13552)
+++ src/settings_gui.cpp	(working copy)
@@ -704,6 +704,24 @@
 	"vehicle.dynamic_engines",
 };
 
+static const char *_patches_shared_infrastructure[] = {
+		"shared_railway_stations",
+		"shared_railway_tracks",
+		"shared_railway_depots",
+		"shared_road_stops",
+		"shared_road_depots",
+		"shared_harbours",
+		"shared_water_depots",
+		"shared_airports",
+		"shared_provision",
+		"shared_tontile_cost",
+		"shared_landing_fee",
+		"shared_road_stops_fee",
+		"shared_harbours_fee",
+		"shared_player_level",
+		"shared_delay",
+};
+
 struct PatchEntry {
 	const SettingDesc *setting;
 	uint index;
@@ -725,6 +743,7 @@
 	{_patches_stations,     NULL, lengthof(_patches_stations)},
 	{_patches_economy,      NULL, lengthof(_patches_economy)},
 	{_patches_ai,           NULL, lengthof(_patches_ai)},
+	{_patches_shared_infrastructure, NULL, lengthof(_patches_shared_infrastructure)},
 };
 
 enum PatchesSelectionWidgets {
@@ -734,7 +753,8 @@
 	PATCHSEL_VEHICLES,
 	PATCHSEL_STATIONS,
 	PATCHSEL_ECONOMY,
-	PATCHSEL_COMPETITORS
+	PATCHSEL_COMPETITORS,
+	PATCHSEL_SHARING
 };
 
 struct PatchesSelectionWindow : Window {
@@ -930,6 +950,7 @@
 
 			case PATCHSEL_INTERFACE: case PATCHSEL_CONSTRUCTION: case PATCHSEL_VEHICLES:
 			case PATCHSEL_STATIONS:  case PATCHSEL_ECONOMY:      case PATCHSEL_COMPETITORS:
+			case PATCHSEL_SHARING:
 				this->RaiseWidget(this->page + PATCHSEL_INTERFACE);
 				this->page = widget - PATCHSEL_INTERFACE;
 				this->LowerWidget(this->page + PATCHSEL_INTERFACE);
@@ -976,6 +997,7 @@
 {    WWT_TEXTBTN,   RESIZE_NONE,     3,   271,   357,    16,    27, STR_CONFIG_PATCHES_STATIONS,     STR_NULL},
 {    WWT_TEXTBTN,   RESIZE_NONE,     3,    10,    96,    28,    39, STR_CONFIG_PATCHES_ECONOMY,      STR_NULL},
 {    WWT_TEXTBTN,   RESIZE_NONE,     3,    97,   183,    28,    39, STR_CONFIG_PATCHES_AI,           STR_NULL},
+{    WWT_TEXTBTN,   RESIZE_NONE,     3,   184,   270,    28,    39, STR_CONFIG_PATCHES_SHARED,       STR_NULL},
 {   WIDGETS_END},
 };
 
Index: src/npf.cpp
===================================================================
--- src/npf.cpp	(revision 13552)
+++ src/npf.cpp	(working copy)
@@ -24,6 +24,7 @@
 #include "vehicle_base.h"
 #include "settings_type.h"
 #include "tunnelbridge.h"
+#include "sharedinfrastructure.h"
 
 static AyStar _npf_aystar;
 
@@ -465,25 +466,37 @@
  */
 static bool CanEnterTileOwnerCheck(Owner owner, TileIndex tile, DiagDirection enterdir)
 {
-	if (IsTileType(tile, MP_RAILWAY) ||             /* Rail tile (also rail depot) */
-			IsRailwayStationTile(tile) ||   /* Rail station tile */
-			IsRoadDepotTile(tile) ||        /* Road depot tile */
-			IsStandardRoadStopTile(tile)) { /* Road station tile (but not drive-through stops) */
-		return IsTileOwner(tile, owner); /* You need to own these tiles entirely to use them */
-	}
+	unsigned char tileOwner = IsTileOwner(tile,owner);
+	if(IsTileType(tile, MP_RAILWAY) && !IsRailwayStation(tile))
+		return ( tileOwner || SharedTracks(tile,owner));
 
+	if (IsRailwayStation(tile))
+	  	return ( tileOwner || SharedRailwayStations(tile,owner));
+
+	if (IsDepotTypeTile(tile, TRANSPORT_RAIL))
+		return ( tileOwner || SharedRailwayDepots(tile,owner));
+
+	if (IsDepotTypeTile(tile, TRANSPORT_ROAD))
+		return ( tileOwner || SharedRoadDepots(tile,owner));
+
+	if (IsStandardRoadStopTile(tile))
+		return ( tileOwner || SharedRoadStops(tile,owner));
+
+	if (IsDepotTypeTile(tile, TRANSPORT_WATER))
+		return ( tileOwner || SharedWaterDepots(tile,owner));
+
 	switch (GetTileType(tile)) {
 		case MP_ROAD:
 			/* rail-road crossing : are we looking at the railway part? */
 			if (IsLevelCrossing(tile) &&
 					DiagDirToAxis(enterdir) != GetCrossingRoadAxis(tile)) {
-				return IsTileOwner(tile, owner); /* Railway needs owner check, while the street is public */
+ 				return (tileOwner || SharedTracks(tile,owner)); /* Railway needs owner check, while the street is public */
 			}
 			break;
 
 		case MP_TUNNELBRIDGE:
 			if (GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL) {
-				return IsTileOwner(tile, owner);
+ 				return (tileOwner || SharedTracks(tile,owner));
 			}
 			break;
 
@@ -880,7 +893,7 @@
 	FOR_ALL_DEPOTS(depot) {
 		/* Check if this is really a valid depot, it is of the needed type and
 		 * owner */
-		if (IsDepotTypeTile(depot->xy, type) && IsTileOwner(depot->xy, owner))
+		if (IsDepotTypeTile(depot->xy, type) && ((IsTileOwner(depot->xy, owner)||SharedDepotTransport(depot->xy,owner,type))))
 			/* If so, let's add it to the queue, sorted by distance */
 			depots.push(&depots, depot, DistanceManhattan(tile, depot->xy));
 	}
Index: src/saveload.cpp
===================================================================
--- src/saveload.cpp	(revision 13552)
+++ src/saveload.cpp	(working copy)
@@ -36,7 +36,7 @@
 
 #include "table/strings.h"
 
-extern const uint16 SAVEGAME_VERSION = 98;
+extern const uint16 SAVEGAME_VERSION = 97;
 
 SavegameType _savegame_type; ///< type of savegame we are loading
 
Index: src/rail_cmd.cpp
===================================================================
--- src/rail_cmd.cpp	(revision 13552)
+++ src/rail_cmd.cpp	(working copy)
@@ -2285,7 +2285,16 @@
 	byte fract_coord_leave;
 	DiagDirection dir;
 	int length;
+	Owner trackowner;
 
+	/* Account for use of shared tracks */
+	if (v->tile != tile && IsFrontEngine(v)) {
+		trackowner = GetTileOwner(tile);
+		if (trackowner != v->owner) {
+			v->shared_tontiles[trackowner] += v->u.rail.cached_weight;
+		}
+	}
+
 	/* this routine applies only to trains in depot tiles */
 	if (v->type != VEH_TRAIN || !IsRailDepotTile(tile)) return VETSB_CONTINUE;
 
Index: src/date.cpp
===================================================================
--- src/date.cpp	(revision 13552)
+++ src/date.cpp	(working copy)
@@ -175,6 +175,8 @@
 extern void TownsMonthlyLoop();
 extern void IndustryMonthlyLoop();
 extern void StationMonthlyLoop();
+extern void SharedTracksPayment();
+extern void SharedSettingDelay();
 
 extern void PlayersYearlyLoop();
 extern void TrainsYearlyLoop();
@@ -270,6 +272,9 @@
 #ifdef ENABLE_NETWORK
 		if (_network_server) NetworkServerMonthlyLoop();
 #endif /* ENABLE_NETWORK */
+ 		SharedTracksPayment();
+ 		SharedSettingDelay();
+
 	}
 
 	/* check if we entered a new year? */
Index: src/station_cmd.cpp
===================================================================
--- src/station_cmd.cpp	(revision 13552)
+++ src/station_cmd.cpp	(working copy)
@@ -3252,10 +3252,10 @@
 				cp->source          = (CheckSavegameVersion(7) && _cargo_source == 0xFF) ? INVALID_STATION : _cargo_source;
 				cp->count           = GB(_waiting_acceptance, 0, 12);
 				cp->days_in_transit = _cargo_days;
-				cp->feeder_share    = _cargo_feeder_share;
+				cp->feeder_share[0] = _cargo_feeder_share;
 				cp->source_xy       = _cargo_source_xy;
 				cp->days_in_transit = _cargo_days;
-				cp->feeder_share    = _cargo_feeder_share;
+				cp->feeder_share[0] = _cargo_feeder_share;
 				SB(ge->acceptance_pickup, GoodsEntry::PICKUP, 1, 1);
 				ge->cargo.Append(cp);
 			}
Index: src/news_type.h
===================================================================
--- src/news_type.h	(revision 13552)
+++ src/news_type.h	(working copy)
@@ -42,6 +42,7 @@
 	NS_COMPANY_MERGER,   ///< NT_COMPANY_INFO (merger)
 	NS_COMPANY_BANKRUPT, ///< NT_COMPANY_INFO (bankrupt)
 	NS_COMPANY_NEW,      ///< NT_COMPANY_INFO (new company)
+	NS_COMPANY_SHARING,  ///< NT_COMPANY_INFO (change sharing)
 	NS_OPENCLOSE,        ///< NT_OPENCLOSE
 	NS_ECONOMY,          ///< NT_ECONOMY
 	NS_INDUSTRY_PLAYER,  ///< NT_INDUSTRY_PLAYER
Index: src/ship_cmd.cpp
===================================================================
--- src/ship_cmd.cpp	(revision 13552)
+++ src/ship_cmd.cpp	(working copy)
@@ -41,6 +41,7 @@
 #include "settings_type.h"
 #include "order_func.h"
 #include "effectvehicle_func.h"
+#include "sharedinfrastructure.h"
 
 #include "table/strings.h"
 
@@ -342,6 +343,9 @@
 
 static void ShipArrivesAt(const Vehicle* v, Station* st)
 {
+	/* check station fee for shared harbours */
+	if (st->owner != v->owner) SharedStationFee(st->owner, v->index);
+
 	/* Check if station was ever visited before */
 	if (!(st->had_vehicle_of_type & HVOT_SHIP)) {
 		st->had_vehicle_of_type |= HVOT_SHIP;
@@ -764,7 +768,7 @@
 	/* The ai_new queries the vehicle cost before building the route,
 	 * so we must check against cheaters no sooner than now. --pasky */
 	if (!IsShipDepotTile(tile)) return CMD_ERROR;
-	if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
+	if (!IsTileOwner(tile, _current_player) && !SharedWaterDepots(tile, _current_player)) return CMD_ERROR;
 
 	unit_num = HasBit(p2, 0) ? 0 : GetFreeUnitNumber(VEH_SHIP);
 
@@ -834,6 +838,8 @@
 		GetPlayer(_current_player)->num_engines[p1]++;
 	}
 
+	SharedDepotProvision(value, GetTileOwner(tile), flags);
+
 	return value;
 }
 
Index: src/order_cmd.cpp
===================================================================
--- src/order_cmd.cpp	(revision 13552)
+++ src/order_cmd.cpp	(working copy)
@@ -27,6 +27,7 @@
 #include "vehicle_func.h"
 #include "oldpool_func.h"
 #include "depot_base.h"
+#include "sharedinfrastructure.h"
 
 #include "table/strings.h"
 
@@ -330,7 +331,7 @@
 
 			const Station *st = GetStation(new_order.GetDestination());
 
-			if (st->owner != OWNER_NONE && !CheckOwnership(st->owner)) {
+			if (st->owner != OWNER_NONE && ((!CheckOwnership(st->owner))&&!SharedStation(st->xy,v->owner,v->type))) {
 				return CMD_ERROR;
 			}
 
@@ -385,18 +386,18 @@
 
 					const Station *st = GetStation(new_order.GetDestination());
 
-					if (!CheckOwnership(st->owner) ||
-							!(st->facilities & FACIL_AIRPORT) ||
-							st->Airport()->nof_depots == 0 ||
-							!CanAircraftUseStation(v->engine_type, st)) {
-						return CMD_ERROR;
-					}
-				} else {
+				if (((!CheckOwnership(st->owner))&&(!SharedAirports(st->xy,v->owner))) ||
+						!(st->facilities & FACIL_AIRPORT) ||
+						st->Airport()->nof_depots == 0 ||
+						!CanAircraftUseStation(v->engine_type, st)) {
+					return CMD_ERROR;
+				}
+			} else {
 					if (!IsValidDepotID(new_order.GetDestination())) return CMD_ERROR;
 
 					const Depot *dp = GetDepot(new_order.GetDestination());
 
-					if (!CheckOwnership(GetTileOwner(dp->xy))) return CMD_ERROR;
+				if ((!CheckOwnership(GetTileOwner(dp->xy)))&&(!SharedDepotVehicleType(dp->xy,v->owner,v->type))) return CMD_ERROR;
 
 					switch (v->type) {
 						case VEH_TRAIN:
@@ -431,7 +432,7 @@
 			if (!IsValidWaypointID(new_order.GetDestination())) return CMD_ERROR;
 			const Waypoint *wp = GetWaypoint(new_order.GetDestination());
 
-			if (!CheckOwnership(GetTileOwner(wp->xy))) return CMD_ERROR;
+			if ((!CheckOwnership(GetTileOwner(wp->xy)))&&(!SharedTracks(wp->xy,v->owner))) return CMD_ERROR;
 
 			/* Order flags can be any of the following for waypoints:
 			 * [non-stop]
Index: src/window_type.h
===================================================================
--- src/window_type.h	(revision 13552)
+++ src/window_type.h	(working copy)
@@ -94,6 +94,7 @@
 	WC_BUILD_SIGNAL,
 	WC_COMPANY_PASSWORD_WINDOW,
 	WC_OSK,
+	WC_SHARED_INFRASTRUCTURE,
 
 	WC_INVALID = 0xFFFF
 };
Index: src/sharedinfrastructure.cpp
===================================================================
--- src/sharedinfrastructure.cpp	(revision 0)
+++ src/sharedinfrastructure.cpp	(revision 0)
@@ -0,0 +1,941 @@
+/* $Id: sharedinfrastructure.cpp $ */
+
+/** @file sharedinfrastructure.cpp
+ * This file deals with using shared infrastructures and relative cost/income */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "bridge_map.h"
+#include "debug.h"
+#include "functions.h"
+#include "landscape.h"
+#include "npf.h"
+#include "aystar.h"
+#include "pathfind.h"
+#include "station_map.h"
+#include "tile_type.h"
+#include "depot_base.h"
+#include "tunnel_map.h"
+#include "network/network.h"
+#include "water_map.h"
+#include "sharedinfrastructure.h"
+#include "variables.h"
+#include "settings_type.h"
+#include "player_func.h"
+#include "player_base.h"
+#include "vehicle_base.h"
+#include "cargotype.h"
+#include "newgrf_cargo.h"
+#include "aircraft.h"
+#include "news_func.h"
+#include "strings_func.h"
+#include "station_base.h"
+#include "depot_map.h"
+#include "window_func.h"
+#include "command_func.h"
+#include "vehicle_func.h"
+#include "train.h"
+
+#include "table/strings.h"
+
+/* variables for player's shared infrastructure GUI */
+bool _si_railway_tracks;
+bool _si_railway_stations;
+bool _si_railway_depots;
+bool _si_airports;
+bool _si_road_depots;
+bool _si_road_stops;
+bool _si_water_depots;
+bool _si_harbours;
+uint16 _si_tontile_cost;
+uint16 _si_landing_fee;
+uint8 _si_provision;
+uint8 _si_road_stops_fee;
+uint8 _si_harbours_fee;
+
+/** Fonctions to check if vehicle can enter tiles
+ * @param tile Tile to enter
+ * @param owner Vehicle's owner
+ */
+
+bool SharedTracks(TileIndex tile, Owner owner)
+{
+	Owner player = GetTileOwner(tile);
+	if (!IsValidPlayer (player)) return true;  // no owner ? just go then, and don't assert on next line
+	Player *p = GetPlayer(player);
+
+	return _settings_game.sharing.shared_player_level ? p->shared_railway_tracks[0] : _settings_game.sharing.shared_railway_tracks;
+}
+
+bool SharedRailwayStations(TileIndex tile, Owner owner)
+{
+	Owner player = GetTileOwner(tile);
+	if (!IsValidPlayer (player)) return true;
+	Player *p = GetPlayer(player);
+	return _settings_game.sharing.shared_player_level ? p->shared_railway_stations[0] : _settings_game.sharing.shared_railway_stations;
+}
+
+bool SharedRailwayDepots(TileIndex tile, Owner owner)
+{
+	Owner player = GetTileOwner(tile);
+	if (!IsValidPlayer (player)) return true;
+	Player *p = GetPlayer(player);
+	return _settings_game.sharing.shared_player_level ? p->shared_railway_depots[0] : _settings_game.sharing.shared_railway_depots;
+}
+
+bool SharedRoadDepots(TileIndex tile, Owner owner)
+{
+	Owner player = GetTileOwner(tile);
+	if (!IsValidPlayer (player)) return true;
+	Player *p = GetPlayer(player);
+	return _settings_game.sharing.shared_player_level ? p->shared_road_depots[0] : _settings_game.sharing.shared_road_depots;
+}
+
+bool SharedRoadStops(TileIndex tile, Owner owner)
+{
+	Owner player = GetTileOwner(tile);
+	if (!IsValidPlayer (player)) return true;
+	Player *p = GetPlayer(player);
+	return _settings_game.sharing.shared_player_level ? p->shared_road_stops[0] : _settings_game.sharing.shared_road_stops;
+}
+
+bool SharedWaterDepots(TileIndex tile, Owner owner)
+{
+	Owner player = GetTileOwner(tile);
+	if (!IsValidPlayer (player)) return true;
+	Player *p = GetPlayer(player);
+	return _settings_game.sharing.shared_player_level ? p->shared_water_depots[0] : _settings_game.sharing.shared_water_depots;
+}
+
+bool SharedHarbours(TileIndex tile, Owner owner)
+{
+	Owner player = GetTileOwner(tile);
+	if (!IsValidPlayer (player)) return true;
+	Player *p = GetPlayer(player);
+	return _settings_game.sharing.shared_player_level ? p->shared_harbours[0] : _settings_game.sharing.shared_harbours;
+}
+
+bool SharedAirports(TileIndex tile, Owner owner)
+{
+	Owner player = GetTileOwner(tile);
+	if (!IsValidPlayer (player)) return true;
+	Player *p = GetPlayer(player);
+	return _settings_game.sharing.shared_player_level ? p->shared_airports[0] : _settings_game.sharing.shared_airports;
+}
+
+bool SharedDepotTransport(TileIndex tile, Owner owner, TransportType type)
+{
+  switch (type) {
+	  case TRANSPORT_RAIL: return SharedRailwayDepots(tile,owner);
+			       break;
+	  case TRANSPORT_ROAD: return SharedRoadDepots(tile,owner);
+			       break;
+	  case TRANSPORT_WATER: return SharedWaterDepots(tile,owner);
+				break;
+	  default:
+		  return false;
+		  break;
+  }
+  return false;
+}
+
+bool SharedDepotVehicleType(TileIndex tile, Owner owner, VehicleType type)
+{
+  switch (type) {
+	  case VEH_TRAIN: return SharedRailwayDepots(tile,owner);
+			       break;
+	  case VEH_ROAD: return SharedRoadDepots(tile,owner);
+			       break;
+	  case VEH_SHIP: return SharedWaterDepots(tile,owner);
+				break;
+	  case VEH_AIRCRAFT: return SharedAirports(tile,owner);
+				break;
+	  default: return 0;
+  }
+  return 0;
+}
+
+
+bool SharedStation(TileIndex tile, Owner owner, VehicleType type)
+{
+  switch (type) {
+	  case VEH_TRAIN: return SharedRailwayStations(tile,owner);
+			       break;
+	  case VEH_ROAD: return SharedRoadStops(tile,owner);
+			       break;
+	  case VEH_SHIP: return SharedHarbours(tile,owner);
+				break;
+	  case VEH_AIRCRAFT: return SharedAirports(tile,owner);
+				break;
+	  default: return 0;
+  }
+  return 0;
+}
+
+/** Calculate provision for action in shared depots.
+ * @param cost Command cost
+ * @param owner Depot owner
+ * @param flags Command flag
+ */
+void SharedDepotProvision(CommandCost cost, Owner owner, uint32 flags)
+{	
+	if ((_current_player != owner) && (!(flags & DC_QUERY_COST)) && (flags & DC_EXEC)) {
+	  	PlayerByte curr = _current_player;
+		if (IsValidPlayer (owner)) {
+			Player *p = GetPlayer(owner);
+
+			uint16 provision_percent = _settings_game.sharing.shared_player_level ? p->shared_provision[0] : _settings_game.sharing.shared_provision;
+			OverflowSafeInt64 provision = (cost.GetCost() * (int64)provision_percent) / 100;
+
+			_current_player = owner;
+			SubtractMoneyFromPlayer(CommandCost(EXPENSES_SHARED_INF_INC,-provision));
+
+			_current_player = curr;
+			SubtractMoneyFromPlayer(CommandCost(EXPENSES_SHARED_INF_RUN,provision));
+		}
+	}
+}
+
+/** Fonctions to activate/desactivate simultaneously railway tracks and stations sharing.
+ * used in patch setting menu
+ */
+int32 SettingsEnableSharedRailwayStations(int32 p1)
+{
+  GameSettings *ptc = (_game_mode == GM_MENU) ? &_settings_newgame : &_settings_game;
+  if(p1)
+    ptc->sharing.shared_railway_tracks=1;
+  return 0;
+}
+
+int32 SettingsEnableSharedRailwayTracks(int32 p1)
+{
+  GameSettings *ptc = (_game_mode == GM_MENU) ? &_settings_newgame : &_settings_game;
+  if(!p1)
+  {
+  	 ptc->sharing.shared_railway_stations=0;
+  	 ptc->sharing.shared_railway_depots=0;
+  }
+  return 0;
+}
+
+/** Calculate track sharing cost & income for all players
+ * called each month
+ */
+void SharedTracksPayment()
+{	
+	Vehicle *v;
+	Player *p;
+	OverflowSafeInt64 tontile_total_income[MAX_PLAYERS]={ 0 };
+	OverflowSafeInt64 tontile_total_cost[MAX_PLAYERS]={ 0 };
+	
+	FOR_ALL_VEHICLES(v) {
+		PlayerID old_player = _current_player;
+		FOR_ALL_PLAYERS(p) {
+			OverflowSafeInt64 cost = 0;
+			if (v->shared_tontiles[p->index] > 0) {
+				uint16 ton_cost = _settings_game.sharing.shared_player_level ? p->shared_tontile_cost[0] : _settings_game.sharing.shared_tontile_cost;
+				cost = max (((v->shared_tontiles[p->index] * ton_cost) / 1000), (OverflowSafeInt64)ton_cost);
+
+				v->profit_this_year -= cost << 8;
+
+				_current_player = v->owner;
+				SubtractMoneyFromPlayer(CommandCost(EXPENSES_SHARED_INF_RUN,cost));
+				tontile_total_cost[v->owner]+=cost;
+
+				_current_player = p->index;
+				SubtractMoneyFromPlayer(CommandCost(EXPENSES_SHARED_INF_INC,-cost));
+				tontile_total_income[p->index]+=cost;
+
+				v->shared_tontiles[p->index] = 0;
+			}
+		}
+		_current_player = old_player;
+	}
+
+	PlayerID old_player = _current_player;
+	FOR_ALL_PLAYERS(p) {
+		/* Show total shared tracks cost & income animation above HQ */
+		if (p->location_of_house != 0) {
+			_current_player = p->index;
+			TileIndex tile = p->location_of_house;
+			uint hq_x = TileX(tile) * 16;
+			uint hq_y = TileY(tile) * 16;
+			uint hq_z= GetSlopeZ(TileX(tile), TileX(tile)) + 80; // show animation above HQ, not inside.
+			if (tontile_total_income[p->index] > 0)
+				ShowCostOrIncomeAnimation( hq_x, hq_y, hq_z, -tontile_total_income[p->index]);
+			if (tontile_total_cost[p->index] > 0)
+				ShowCostOrIncomeAnimation( hq_x, hq_y + 10 , hq_z, tontile_total_cost[p->index]); // show cost under income
+		}
+		_current_player = old_player;
+	}
+}
+
+/** Calculate station entrance fee for vehicle
+ * @param station_owner Station owner
+ * @param vehicle_owner Vehicle owner
+ * @param cargo_capacity maximum cargo of vehicle
+ */
+void SharedStationFee(Owner station_owner, VehicleID vehicle)
+{	
+	PlayerID old_player = _current_player;	
+	if (IsValidPlayer (station_owner)) {
+		Player *p = GetPlayer(station_owner);
+		Vehicle *v = GetVehicle(vehicle);
+		uint16 ton_cost = 0, cargo_capacity = 0;
+		const AircraftVehicleInfo *avi;
+
+		switch (v->type) {
+			case VEH_TRAIN:
+				break;
+			case VEH_ROAD:
+				/* count 10 passengers for 1 ton of cargo */
+				cargo_capacity = (IsCargoInClass(v->cargo_type, CC_PASSENGERS)) ? (v->cargo_cap / 10) : v->cargo_cap;
+				ton_cost = _settings_game.sharing.shared_player_level ? p->shared_road_stops_fee[0] : _settings_game.sharing.shared_road_stops_fee;
+				break;
+			case VEH_SHIP: 
+				cargo_capacity = v->cargo_cap;
+				ton_cost = _settings_game.sharing.shared_player_level ? p->shared_harbours_fee[0] : _settings_game.sharing.shared_harbours_fee;
+				break;
+			case VEH_AIRCRAFT:
+				/* count cargo capacity relative to goods */
+				avi = AircraftVehInfo(v->engine_type);
+				cargo_capacity = AircraftDefaultCargoCapacity(CT_GOODS, avi);
+				ton_cost = _settings_game.sharing.shared_player_level ? p->shared_landing_fee[0] : _settings_game.sharing.shared_landing_fee;
+				break;
+			default: break;
+		}
+
+		OverflowSafeInt64 station_fee = (cargo_capacity * ton_cost);
+	
+		_current_player = station_owner;
+		SubtractMoneyFromPlayer(CommandCost(EXPENSES_SHARED_INF_INC, -station_fee));
+	
+		_current_player = v->owner;
+		SubtractMoneyFromPlayer(CommandCost(EXPENSES_SHARED_INF_RUN, station_fee));
+
+		_current_player = old_player;
+
+		if (station_fee > 0) {
+			/* remove station fee from vehicle profit */
+			v->profit_this_year -= station_fee << 8;
+
+			/** show vehicle cost animation for every player
+			 * (do not show it as income animation, even for station owner
+			 * as it can be confusing)
+			 */
+			ShowCostOrIncomeAnimation(v->x_pos, v->y_pos + 10 , v->z_pos, station_fee);
+		}
+	}
+}
+
+/* return closing infrastructure as bitmask */
+uint GetSharedCloseBits(PlayerID player)
+{
+	Player *p = GetPlayer(player);
+	uint close_bits = 0;
+	if ((p->shared_railway_tracks[0]) && !(p->shared_railway_tracks[1])) close_bits |= SHARED_RAILWAY_TRACKS;
+	if ((p->shared_railway_stations[0]) && !(p->shared_railway_stations[1])) close_bits |= SHARED_RAILWAY_STATIONS;
+	if ((p->shared_railway_depots[0]) && !(p->shared_railway_depots[1])) close_bits |= SHARED_RAILWAY_DEPOTS;
+	if ((p->shared_airports[0]) && !(p->shared_airports[1])) close_bits |= SHARED_AIRPORTS;
+	if ((p->shared_road_depots[0]) && !(p->shared_road_depots[1])) close_bits |= SHARED_ROAD_DEPOTS;
+	if ((p->shared_road_stops[0]) && !(p->shared_road_stops[1])) close_bits |= SHARED_ROAD_STOPS;
+	if ((p->shared_water_depots[0]) && !(p->shared_water_depots[1])) close_bits |= SHARED_WATER_DEPOTS;
+	if ((p->shared_harbours[0]) && !(p->shared_harbours[1])) close_bits |= SHARED_HARBOURS;
+	return close_bits;
+}
+
+/* set player sharing settings at end of activation delay */
+void SharedSettingDelay()
+{	
+	Player *p;
+	uint close_bits = 0;
+	
+	FOR_ALL_PLAYERS(p) {
+		switch (p->shared_change_months) {
+			case 0:
+				break;
+
+			case 1:
+				/* get closing infrastructure(s) */
+				close_bits = GetSharedCloseBits(p->index);
+				/* remove vehicle from closing infrastructure(s) */
+				OnSharedClose(p->index, close_bits);
+				/* time to change settings ! */
+				p->shared_railway_tracks[0] = p->shared_railway_tracks[1];
+				p->shared_railway_stations[0] = p->shared_railway_stations[1];
+				p->shared_railway_depots[0] = p->shared_railway_depots[1];
+				p->shared_tontile_cost[0] = p->shared_tontile_cost[1];
+				p->shared_road_stops_fee[0] = p->shared_road_stops_fee[1];
+				p->shared_harbours_fee[0] = p->shared_harbours_fee[1];
+				p->shared_airports[0] = p->shared_airports[1];
+				p->shared_landing_fee[0] = p->shared_landing_fee[1];
+				p->shared_road_depots[0] = p->shared_road_depots[1];
+				p->shared_road_stops[0] = p->shared_road_stops[1];
+				p->shared_water_depots[0] = p->shared_water_depots[1];
+				p->shared_harbours[0] = p->shared_harbours[1];
+				p->shared_provision[0] = p->shared_provision[1];
+
+				p->shared_change_months = 0;
+				break;
+
+			default :
+				p->shared_change_months--;
+				break;
+		}
+	}
+}
+
+/** Change player shared bool setting.
+ * @param tile unused
+ * @param flags unused
+ * @param p1 packed new boolean values
+ * @param p2 unused
+ */
+CommandCost CmdSetSharedBoolValues(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+	Player *p = GetPlayer(_current_player);
+
+	/* fix : do not send news twice if values are already updated */
+	uint32 check = (uint)p->shared_railway_tracks[1] | (uint)p->shared_railway_stations[1] << 1 | (uint)p->shared_railway_depots[1] << 2
+		 | (uint)p->shared_airports[1] << 3 | (uint)p->shared_road_depots[1] << 4 | (uint)p->shared_road_stops[1] << 5
+		 | (uint)p->shared_water_depots[1] << 6 | (uint)p->shared_harbours[1] << 7;
+	
+	/* set new value */
+	p->shared_railway_tracks[1]= HasBit(p1, 0);
+	p->shared_railway_stations[1]= HasBit(p1, 1);
+	p->shared_railway_depots[1]= HasBit(p1, 2);
+	p->shared_airports[1]= HasBit(p1, 3);
+	p->shared_road_depots[1]= HasBit(p1, 4);
+	p->shared_road_stops[1]= HasBit(p1, 5);
+	p->shared_water_depots[1]= HasBit(p1, 6);
+	p->shared_harbours[1]= HasBit(p1, 7);
+
+	/* reset timer for setting sharing value */
+	p->shared_change_months = _settings_game.sharing.shared_delay;
+
+	/* immediatly apply setting if patch delay is set to 0 */
+	if (_settings_game.sharing.shared_delay == 0) {
+		/* get closing infrastructure and remove vehicle */
+		if (check != p1) {
+			uint close_bits = GetSharedCloseBits(p->index);
+			OnSharedClose(p->index, close_bits);
+		}
+		/* update settings */
+		p->shared_railway_tracks[0]= HasBit(p1, 0);
+		p->shared_railway_stations[0]= HasBit(p1, 1);
+		p->shared_railway_depots[0]= HasBit(p1, 2);
+		p->shared_airports[0]= HasBit(p1, 3);
+		p->shared_road_depots[0]= HasBit(p1, 4);
+		p->shared_road_stops[0]= HasBit(p1, 5);
+		p->shared_water_depots[0]= HasBit(p1, 6);
+		p->shared_harbours[0]= HasBit(p1, 7);
+	}
+
+	/* send a news message to all players about this change */
+	if (check != p1) {
+		TileIndex t_news = p->location_of_house > 0 ? p->location_of_house : p->last_build_coordinate;
+		SetDParam(0, p->index);
+		SetDParam(1, p->index);
+		AddNewsItem(STR_SHARED_CHANGE_BOOL_VALUE,
+			NS_COMPANY_SHARING,
+			t_news,
+			0);
+	}
+
+	return CommandCost();
+}
+
+/** Change player shared int setting.
+ * @param tile unused
+ * @param flags unused
+ * @param p1 packed new int values (tontile_cost, road_stops_fee, harbours_fee)
+ * @param p2 packed new int values (landing_fee, depot_provision)
+ */
+CommandCost CmdSetSharedIntValues(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
+{
+	Player *p = GetPlayer(_current_player);
+
+	/* fix : do not send news twice if values are already updated */
+	uint32 check = p->shared_tontile_cost[1] | p->shared_road_stops_fee[1] << 16 | p->shared_harbours_fee[1] << 24;
+	uint32 check2 = p->shared_landing_fee[1] | p->shared_provision[1] << 16;
+
+	/* set new value from p1 */
+	p->shared_tontile_cost[1] = GB(p1, 0, 16);
+	p->shared_road_stops_fee[1] = GB(p1, 16, 8);
+	p->shared_harbours_fee[1] = GB(p1, 24, 8);
+	/* set new value from p2 */
+	p->shared_landing_fee[1] = GB(p2, 0, 16);
+	p->shared_provision[1] = GB(p2, 16, 8);
+
+	/* reset timer for setting sharing value */
+	p->shared_change_months = _settings_game.sharing.shared_delay;
+
+	/* immediatly apply setting if patch delay is set to 0 */
+	if (_settings_game.sharing.shared_delay == 0) {
+		p->shared_tontile_cost[0] = GB(p1, 0, 16);
+		p->shared_road_stops_fee[0] = GB(p1, 16, 8);
+		p->shared_harbours_fee[0] = GB(p1, 24, 8);
+		p->shared_landing_fee[0] = GB(p2, 0, 16);
+		p->shared_provision[0] = GB(p2, 16, 8);
+	}
+
+	/* send a news message to all players about this change */
+	if (check != p1 || check2 != p2) {
+		TileIndex t_news = p->location_of_house > 0 ? p->location_of_house : p->last_build_coordinate;
+		SetDParam(0, p->index);
+		SetDParam(1, p->index);
+		AddNewsItem(STR_SHARED_CHANGE_INT_VALUE,
+			NS_COMPANY_SHARING,
+			t_news,
+			0);
+	}
+
+	return CommandCost();
+}
+
+/* borrowed */
+static const byte _vehicle_initial_x_fract[4] = {10, 8, 4,  8};
+static const byte _vehicle_initial_y_fract[4] = { 8, 4, 8, 10};
+static void TrainMovedChangeSignals(TileIndex tile, DiagDirection dir)
+{
+	if (IsTileType(tile, MP_RAILWAY) &&
+			GetRailTileType(tile) == RAIL_TILE_SIGNALS) {
+		TrackdirBits tracks = TrackBitsToTrackdirBits(GetTrackBits(tile)) & DiagdirReachesTrackdirs(dir);
+		Trackdir trackdir = FindFirstTrackdir(tracks);
+		UpdateSignalsOnSegment(tile, TrackdirToExitdir(trackdir), GetTileOwner(tile));
+	}
+}
+
+bool SharedCloseDepotTeleport (VehicleID vehicle, DepotID depot)
+{
+	if (IsValidDepotID(depot)) {
+		Vehicle *v = GetVehicle(vehicle);
+		Depot *d = GetDepot(depot);
+		/* max train lenght = 100 */ 
+		TileIndex old_tile[100];
+		DiagDirection old_dir[100];
+		uint counter;
+		uint x;
+		uint y;
+		switch (v->type) {
+			case VEH_TRAIN:
+				//old_tile[] = v->tile;
+				//old_dir[] = DirToDiagDir(v->direction);
+				counter = 0;
+				for (; v != NULL; v = GetNextVehicle(v)) {					
+					old_tile[counter] = v->tile;
+					old_dir[counter] = DirToDiagDir(v->direction);
+					counter++;
+
+					DiagDirection dir = GetRailDepotDirection(d->xy);
+					MarkSingleVehicleDirty(v);
+					v->direction = DiagDirToDir(dir);
+					v->tile = d->xy;
+					x = TileX(d->xy) * TILE_SIZE | _vehicle_initial_x_fract[dir];
+					y = TileY(d->xy) * TILE_SIZE | _vehicle_initial_y_fract[dir];
+					v->x_pos = x;
+					v->y_pos = y;
+					v->z_pos = GetSlopeZ(x, y);
+					v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
+					v->u.rail.track = TRACK_BIT_DEPOT;
+					v->cur_speed = 0;
+
+					DEBUG (misc, 4, "3- Teleport v %d in depot %d", v->index, d->index);
+				}
+				/* now that vehicle is removed, clear signal */
+				for (uint i = 0; i < counter; i++) {
+					DEBUG(misc, 4, "3- update signal (dir : %d) at tile %d,%d", old_dir[i], TileX(old_tile[i]), TileY(old_tile[i]) );
+					if (i != counter) {
+						TrainMovedChangeSignals(old_tile[i], old_dir[i]);
+						//UpdateSignalsOnSegment(old_tile[i], old_dir[i], GetTileOwner(old_tile[i]));
+					} else {
+						//UpdateSignalsOnSegment(old_tile[i], ReverseDiagDir(old_dir[i]), GetTileOwner(old_tile[i]));
+						TrainMovedChangeSignals(old_tile[i], ReverseDiagDir(old_dir[i]));
+					}
+				}
+				break;
+			case VEH_ROAD:
+				MarkSingleVehicleDirty(v);
+				v->tile = d->xy;
+				x = TileX(d->xy) * TILE_SIZE + TILE_SIZE / 2;
+				y = TileY(d->xy) * TILE_SIZE + TILE_SIZE / 2;
+				v->x_pos = x;
+				v->y_pos = y;
+				v->z_pos = GetSlopeZ(x, y);
+				v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
+				v->u.road.state = RVSB_IN_DEPOT;	
+				v->cur_speed = 0;
+				DEBUG (misc, 4, "3- Teleport v %d in depot %d", v->index, d->index);
+				InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
+				break;
+			case VEH_SHIP:
+				v->tile = d->xy;
+				x = TileX(d->xy) * TILE_SIZE + TILE_SIZE / 2;
+				y = TileY(d->xy) * TILE_SIZE + TILE_SIZE / 2;
+				v->x_pos = x;
+				v->y_pos = y;
+				v->z_pos = GetSlopeZ(x, y);
+				v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
+				v->u.ship.state = TRACK_BIT_DEPOT;	
+				v->cur_speed = 0;
+				DEBUG (misc, 4, "3- Teleport v %d in depot %d", v->index, d->index);
+				InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
+				break;
+			default: break;
+		}
+		return true;
+	}
+	return false;
+}
+
+bool SharedCloseHangarTeleport (VehicleID vehicle, StationID station)
+{
+	if (IsValidStationID(station)) {
+		Vehicle *v = GetVehicle(vehicle);
+		Station *st = GetStation(station);
+		const AirportFTAClass *apc = st->Airport();
+		uint x;
+		uint y;
+
+		/* get tile of first hangar */
+		TileIndex tile = st->airport_tile + ToTileIndexDiff(apc->airport_depots[0]);
+		
+		/* we need to handle shadow & rotor */
+		Vehicle *u = v->next;
+
+		v->direction = DIR_SE;
+		v->tile = tile;
+
+		x = TileX(tile) * TILE_SIZE + 5;
+		y = TileY(tile) * TILE_SIZE + 3;
+
+		v->x_pos = u->x_pos = x;
+		v->y_pos = u->y_pos = y;
+		u->z_pos = GetSlopeZ(x, y);
+		v->z_pos = u->z_pos + 1;
+
+		v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
+		u->vehstatus |= VS_HIDDEN;
+		v->UpdateDeltaXY(INVALID_DIR);
+		u->UpdateDeltaXY(INVALID_DIR);
+
+		/* set v position to first hangar */
+		v->u.air.pos = apc->layout[0].position;
+		v->u.air.state = HANGAR;
+		v->u.air.previous_pos = v->u.air.pos;
+		v->u.air.targetairport = GetStationIndex(tile);
+
+		/* handle rotor */
+		u = u->Next();
+		if (u != NULL) {
+			u->vehstatus |= VS_HIDDEN;
+			u->cur_speed = 0;
+		}
+		InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
+		return true;
+	}
+	return false;
+}
+
+DepotID SharedCloseGetFirstDepot (PlayerID old_player, VehicleID vehicle, bool just_old_player)
+{
+	Vehicle *v = GetVehicle(vehicle);
+	Depot *depot;
+	DEBUG (misc, 4, "1- Starting search of depot for v %d", v->index);
+	FOR_ALL_DEPOTS(depot) {
+		bool owner_check = just_old_player ? (GetTileOwner(depot->xy) == old_player) : (GetTileOwner(depot->xy) != old_player);
+		switch (v->type) {
+			case VEH_TRAIN:
+				/* and check rail type */
+				if (owner_check && IsRailDepotTile(depot->xy) &&
+					(IsFreeWagon(v) || IsFrontEngine(v)) &&
+					(HasBit(v->u.rail.compatible_railtypes, GetRailType(depot->xy)))) {
+					DEBUG (misc, 4, "1- Check if v %d can access depot %d", v->index, depot->index);
+					if (SharedRailwayDepots(depot->xy, v->owner)) return depot->index;
+				}
+				break;
+			case VEH_ROAD:
+				/* tram use special depot */
+				if (owner_check && IsRoadDepotTile(depot->xy) &&
+					(HasTileRoadType(depot->xy, ROADTYPE_TRAM) == HasBit(EngInfo(v->engine_type)->misc_flags, EF_ROAD_TRAM))) {
+					DEBUG (misc, 4, "1- Check if v %d can access depot %d", v->index, depot->index);
+					if (SharedRoadDepots(depot->xy, v->owner)) return depot->index;
+				}
+				break;
+			case VEH_SHIP:
+				/* tram use special depot */
+				if (owner_check && IsShipDepotTile(depot->xy)) {
+					DEBUG (misc, 4, "1- Check if v %d can access depot %d", v->index, depot->index);
+					if (SharedWaterDepots(depot->xy, v->owner)) return depot->index;
+				}
+				break;
+			default: break;
+		}
+	}
+	DEBUG (misc, 4, "1- No valid depot for v %d", v->index);
+	return INVALID_DEPOT;
+}
+
+StationID SharedCloseGetFirstHangar(PlayerID old_player, VehicleID vehicle, bool check_player)
+{	
+	Vehicle *v = GetVehicle(vehicle);
+	Station *st;
+	DEBUG (misc, 4, "1- Starting search of hangar for v %d", v->index);
+	FOR_ALL_STATIONS(st) {
+		if (((st->owner == old_player) || (!SharedAirports(st->xy, v->owner))) || !(st->facilities & FACIL_AIRPORT)) continue;
+		DEBUG (misc, 4, "1- Check if airport %d is compatible with v %d", st->index, v->owner);
+		const AirportFTAClass *afc = st->Airport();
+		if (afc->flags & (v->subtype == AIR_HELICOPTER ? AirportFTAClass::HELICOPTERS : AirportFTAClass::AIRPLANES) &&
+			afc->nof_depots > 0) return st->index;
+	}
+	return INVALID_STATION;
+}
+
+void UpdateSharedOnRemove(VehicleID vehicle)
+{
+	Vehicle *v = GetVehicle(vehicle);
+	switch (v->type) {
+		case VEH_TRAIN:
+			if (v->current_order.IsType(OT_LOADING)) {
+				DEBUG (misc, 4, "2- v %d was loading, clear station", v->index);
+				v->LeaveStation();
+				v->load_unload_time_rem = 0;
+			}
+			break;
+		case VEH_ROAD:
+			if (v->current_order.IsType(OT_LOADING)) {
+				DEBUG (misc, 4, "2- v %d was loading, clear station", v->index);
+				v->LeaveStation();
+			}
+			ClearSlot(v);
+			break;
+		case VEH_SHIP:
+			/* ship does not block station */
+			break;			
+		case VEH_AIRCRAFT:
+			if (v->u.air.state != FLYING && v->u.air.state != HANGAR) {
+				DEBUG (misc, 4, "2- v %d was on ground, clear station", v->index);
+				Station *old_st = GetStation (v->u.air.targetairport);
+				const AirportFTAClass *apc = old_st->Airport();
+				CLRBITS(old_st->airport_flags, apc->layout[v->u.air.pos].block);
+			}
+			break;
+		default: NOT_REACHED();
+	}
+
+}
+
+void SharedCloseOnLand (PlayerID old_player, VehicleID vehicle)
+{
+	DEBUG (misc, 4, "1- find first available depot for v %d", vehicle);
+	DepotID depot = SharedCloseGetFirstDepot (old_player, vehicle, false);
+	Vehicle *v = GetVehicle(vehicle);
+	PlayerID curr = _current_player;
+	bool handled = false;
+	DEBUG (misc, 4, "1- save vehicle position : tile %d", v->tile);
+	TileIndex old_tile = v->tile;
+	uint command;
+
+	/* vehicle and infrastructure need some resetting */
+	UpdateSharedOnRemove(vehicle);
+
+	DEBUG (misc, 4, "2- start handling of v %d (type : %d) for depot %d", v->index, v->type, depot);
+
+	if (IsValidDepotID(depot)) {
+		/* try to send vehicle to new depot, on fail try another way */
+		DEBUG (misc, 4, "2- try to send v %d to depot %d", v->index, depot);
+		handled = SharedCloseDepotTeleport(vehicle, depot);
+	} else {
+		/* sell vehicle */
+		int sell_cmd = 0;
+		switch (v->type) {
+			case VEH_TRAIN:
+				if (IsFrontEngine(v)) sell_cmd = 1;
+				command = CMD_SELL_RAIL_WAGON;
+				break;
+			case VEH_ROAD:
+				command = CMD_SELL_ROAD_VEH;
+				break;
+			case VEH_SHIP:
+				command = CMD_SELL_SHIP;
+				break;
+			default:
+				NOT_REACHED();
+				command = 0;
+		}
+		_current_player = v->owner;
+		/* already in old_player depot ? then sell vehicle */
+		if (v->IsStoppedInDepot()) {		
+			DEBUG (misc, 4, "3- sending to shared depot failed, v %d already in closing depot, trying to sell", v->index, depot);	
+			CommandCost cost = DoCommand(0, v->index, sell_cmd, DC_EXEC, command);
+			SubtractMoneyFromPlayer(cost);
+			if (v->owner == _local_player && cost.GetCost() != 0) {
+				ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost.GetCost());
+			}
+			handled = CmdSucceeded(cost);
+		} else {
+			/* We have already tested all depots except old_player's. do it now */ 
+			DEBUG (misc, 4, "3- sending to shared depot failed for v %d, trying closing depot", v->index, depot);
+			DepotID depot = SharedCloseGetFirstDepot (old_player, vehicle, true);
+			if (SharedCloseDepotTeleport(vehicle, depot)) {
+				/* vehicule finally in depot now ? sell it */
+				DEBUG (misc, 4, "3- try to sell v %d in closing depot", v->index, depot);
+				CommandCost cost = DoCommand(0, v->index, sell_cmd, DC_EXEC, command);
+				SubtractMoneyFromPlayer(cost);
+				if (v->owner == _local_player && cost.GetCost() != 0) {
+					ShowCostOrIncomeAnimation(v->x_pos, v->y_pos, v->z_pos, cost.GetCost());
+				}
+				handled = CmdSucceeded(cost);
+			}
+		}
+	}
+	if (!handled) {
+		/* tried everything possible to save it, without success, now just delete this vehicle */
+		DEBUG (misc, 4, "4- tried anything, deleting v %d (subtype %d)", v->index, v->subtype);
+		DeleteWindowById(WC_VEHICLE_VIEW, v->index);
+		DeleteWindowById(WC_VEHICLE_DETAILS, v->index);
+		DeleteWindowById(WC_VEHICLE_ORDERS, v->index);
+		switch (v->type) {
+			case VEH_TRAIN:
+				if (IsFrontEngine(v)) for (; v != NULL; v = GetNextVehicle(v)) {
+					DEBUG (misc, 4, "4- tried anything, deleting v %d in chain", v->index);
+					old_tile = v->tile;
+					DiagDirection old_dir = DirToDiagDir(v->direction);
+					delete v;
+					/* now that vehicle is removed, clear signal */
+					DEBUG(misc, 4, "dir : %d", old_dir);
+					UpdateSignalsOnSegment(old_tile, old_dir, GetTileOwner(old_tile));
+					DEBUG (misc, 4, "4- tried anything, v %d deleted in chain", v->index);
+				} else {
+					DEBUG (misc, 4, "4- tried anything, deleting v %d alone", v->index);
+					old_tile = v->tile;
+					DiagDirection old_dir = DirToDiagDir(v->direction);
+					delete v;
+					/* now that vehicle is removed, clear signal */
+					DEBUG(misc, 4, "dir : %d", old_dir);
+					UpdateSignalsOnSegment(old_tile, old_dir, GetTileOwner(old_tile));
+					DEBUG (misc, 4, "4- tried anything, v %d deleted alone", v->index);
+				}
+				break;
+			case VEH_ROAD:
+			case VEH_SHIP:
+				DEBUG (misc, 4, "4- tried anything, deleting v %d", v->index);
+				delete v;
+				DEBUG (misc, 4, "4- tried anything, v %d deleted", v->index);
+				break;
+			default: NOT_REACHED(); command = 0;
+		}
+
+	}
+	_current_player = curr;
+	/* clean some more infrastructure */
+
+	DEBUG (misc, 4, "5- end of handling v %d", vehicle);
+}
+
+void SharedCloseOnAir (PlayerID old_player, VehicleID vehicle)
+{
+	DEBUG (misc, 4, "1- find first available hangar for v %d", vehicle);
+	StationID airport = SharedCloseGetFirstHangar(old_player, vehicle, false);
+	Vehicle *v = GetVehicle(vehicle);
+	PlayerID curr = _current_player;
+	bool handled = false;
+
+	/* vehicle on airport need some resetting */
+	UpdateSharedOnRemove(vehicle);
+
+	DEBUG (misc, 4, "2- start handling of v %d (type : %d) for airport %d", v->index, v->type, airport);
+
+	if (IsValidStationID(airport)) {
+		/* try to send vehicle to new depot, on fail try another way */
+		DEBUG (misc, 4, "2- try to send v %d to airport %d", v->index, airport);
+		handled = SharedCloseHangarTeleport(vehicle, airport);
+	} else {
+		/* sell vehicle */
+		_current_player = v->owner;
+		/* already in old_player depot ? then sell vehicle */
+		if (v->IsStoppedInDepot()) {		
+			DEBUG (misc, 4, "3- sending to shared hangar failed, v %d already in closing hangar, trying to sell", v->index, airport);	
+			handled = CmdSucceeded(DoCommand(0, v->index, 0, DC_EXEC, CMD_SELL_AIRCRAFT));
+		} else {
+			/* We have already tested all depots except old_player's. do it now */ 
+			DEBUG (misc, 4, "3- sending to shared hangar failed for v %d, trying closing hangar", v->index, airport);
+			airport = SharedCloseGetFirstHangar (old_player, vehicle, true);
+			if (SharedCloseHangarTeleport(vehicle, airport)) {
+				/* vehicule finally in depot now ? sell it */
+				DEBUG (misc, 4, "3- try to sell v %d in closing hangar", v->index, airport);
+				handled = CmdSucceeded(DoCommand(0, v->index, 0, DC_EXEC, CMD_SELL_AIRCRAFT));
+			}
+		}
+	}
+	if (!handled) {
+		/* tried everything possible to save it, without success, now just delete this vehicle */
+		DEBUG (misc, 4, "4- tried anything, deleting v %d (subtype %d)", v->index, v->subtype);
+		DeleteWindowById(WC_VEHICLE_VIEW, v->index);
+		DeleteWindowById(WC_VEHICLE_DETAILS, v->index);
+		DeleteWindowById(WC_VEHICLE_ORDERS, v->index);
+
+		DEBUG (misc, 4, "4- tried anything, deleting v %d", v->index);
+		DeleteVehicleChain(v);
+		DEBUG (misc, 4, "4- tried anything, v %d deleted", v->index);
+
+	} else {
+		/* post-teleport */
+
+	}
+	_current_player = curr;
+	DEBUG (misc, 4, "5- end of handling v %d", vehicle);
+
+}
+
+/** Take care of vehicle on closed shared infrastructure.
+ * @param old_player bankrupt player
+ */
+void OnSharedClose(PlayerID old_player, uint close_bits)
+{	
+	DEBUG (misc, 4, "0- player %d is closing those bits : %d", old_player, close_bits);
+	Vehicle *v;	
+	Station *st = NULL;
+	FOR_ALL_VEHICLES(v) {
+		switch (v->type){
+			case VEH_TRAIN:
+				/* attached wagons are handled with front engines later */
+				if (GetTileOwner(v->tile) == old_player && (IsFrontEngine(v) || IsFreeWagon(v)) &&
+					((HASBITS(close_bits, SHARED_RAILWAY_TRACKS))
+					|| (HASBITS(close_bits, SHARED_RAILWAY_STATIONS) && IsTileType(v->tile, MP_STATION))
+					|| (HASBITS(close_bits, SHARED_RAILWAY_DEPOTS) && IsDepotTypeTile(v->tile, TRANSPORT_RAIL) ))) {
+					DEBUG (misc, 4, "0- v %d is TRAIN, owned by player %d in tile %d,%d", v->index, v->owner, TileX(v->tile),TileY(v->tile));
+					SharedCloseOnLand (old_player, v->index);
+				}
+				break;
+			case VEH_ROAD:
+				/* road won't be removed, check only in depot and stations */
+				if (GetTileOwner(v->tile) == old_player && 
+					((IsDepotTypeTile(v->tile, TRANSPORT_ROAD) && HASBITS(close_bits, SHARED_ROAD_DEPOTS))
+					|| ((IsTileType(v->tile, MP_STATION)) && HASBITS(close_bits, SHARED_ROAD_STOPS)))) {
+					DEBUG (misc, 4, "0- v %d is ROAD, owned by player %d in tile %d,%d", v->index, v->owner, TileX(v->tile),TileY(v->tile));
+					SharedCloseOnLand (old_player, v->index);
+				}
+				break;
+			case VEH_SHIP: 
+				/* remove ships in shared depots */
+				if (GetTileOwner(v->tile) == old_player && (IsDepotTypeTile(v->tile, TRANSPORT_WATER))
+					&& HASBITS(close_bits, SHARED_WATER_DEPOTS)) {
+					DEBUG (misc, 4, "0- v %d is SHIP, owned by player %d in tile %d,%d", v->index, v->owner, TileX(v->tile),TileY(v->tile));
+					SharedCloseOnLand (old_player, v->index); // TODO : find another name to this function
+				}
+				break;
+			case VEH_AIRCRAFT:
+				/* don't land on closing airports */
+				st = GetStation(v->u.air.targetairport);
+				if (((v->u.air.state == LANDING && st->owner == old_player) ||
+					(v->u.air.state != FLYING && (GetTileOwner(v->tile) == old_player)))
+					&& HASBITS(close_bits, SHARED_AIRPORTS)) {
+					DEBUG (misc, 4, "0- v %d is AIRCRAFT, owned by player %d in tile %d,%d", v->index, v->owner, TileX(v->tile),TileY(v->tile));
+					SharedCloseOnAir (old_player, v->index);
+				}
+				break;
+			default: break;
+		}
+	}
+}
\ No newline at end of file
Index: src/train_cmd.cpp
===================================================================
--- src/train_cmd.cpp	(revision 13552)
+++ src/train_cmd.cpp	(working copy)
@@ -39,6 +39,7 @@
 #include "tunnelbridge_map.h"
 #include "strings_func.h"
 #include "functions.h"
+#include "sharedinfrastructure.h"
 #include "window_func.h"
 #include "date_func.h"
 #include "vehicle_func.h"
@@ -51,6 +52,7 @@
 #include "order_func.h"
 #include "newgrf_station.h"
 #include "effectvehicle_func.h"
+#include <stack>
 
 #include "table/strings.h"
 #include "table/train_cmd.h"
@@ -697,15 +699,22 @@
 	 * to the player. Doesn't matter if only the cost is queried */
 	if (!(flags & DC_QUERY_COST)) {
 		if (!IsRailDepotTile(tile)) return CMD_ERROR;
-		if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
+		if (!IsTileOwner(tile, _current_player) && !SharedRailwayDepots(tile, _current_player)) return CMD_ERROR;
 	}
 
 	const RailVehicleInfo *rvi = RailVehInfo(p1);
 
-	if (rvi->railveh_type == RAILVEH_WAGON) return CmdBuildRailWagon(p1, tile, flags);
+	CommandCost value;
+	if (rvi->railveh_type == RAILVEH_WAGON) {
+		value = CmdBuildRailWagon(p1, tile, flags);
+		SharedDepotProvision(value, GetTileOwner(tile), flags);
 
-	CommandCost value = EstimateTrainCost(p1, rvi);
+		return value;
+	}
 
+	value = EstimateTrainCost(p1, rvi);
+
+
 	uint num_vehicles =
 		(rvi->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1) +
 		CountArticulatedParts(p1, false);
@@ -812,7 +821,7 @@
 			GetPlayer(_current_player)->num_engines[p1]++;
 		}
 	}
-
+	SharedDepotProvision(value, GetTileOwner(tile), flags);
 	return value;
 }
 
@@ -1290,7 +1299,7 @@
 
 	Vehicle *v = GetVehicle(p1);
 
-	if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
+	if (v->type != VEH_TRAIN || !IsTileOwner(tile, _current_player)) return CMD_ERROR;
 
 	/* Check if this train can be started/stopped. The callback will fail or
 	 * return 0xFF if it can. */
@@ -1858,7 +1867,8 @@
 
 	Vehicle *v = GetVehicle(p1);
 
-	if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
+	/* In order to sort out jams on your tracks you have to be able to turn trains */
+	if (v->type != VEH_TRAIN || !IsTileOwner(tile, _current_player)) return CMD_ERROR;
 
 	if (p2 != 0) {
 		/* turn a single unit around */
@@ -1907,7 +1917,10 @@
 
 	Vehicle *v = GetVehicle(p1);
 
-	if (v->type != VEH_TRAIN || !CheckOwnership(v->owner)) return CMD_ERROR;
+	/** A track owner must stay in control of his tracks so others cannot 
+	 *  produce forcefully crashes there
+	 */
+	if (v->type != VEH_TRAIN || !IsTileOwner(tile, _current_player)) return CMD_ERROR;
 
 	if (flags & DC_EXEC) v->u.rail.force_proceed = 0x50;
 
@@ -2731,7 +2744,8 @@
 static inline bool CheckCompatibleRail(const Vehicle *v, TileIndex tile)
 {
 	return
-		IsTileOwner(tile, v->owner) && (
+		(IsTileOwner(tile, v->owner) || 
+			(SharedTracks(tile, v->owner))) && (
 			!IsFrontEngine(v) ||
 			HasBit(v->u.rail.compatible_railtypes, GetRailType(tile))
 		);
@@ -3623,7 +3637,6 @@
 					v->index,
 					0);
 			}
-
 			v->profit_last_year = v->profit_this_year;
 			v->profit_this_year = 0;
 			InvalidateWindow(WC_VEHICLE_DETAILS, v->index);
Index: src/command.cpp
===================================================================
--- src/command.cpp	(revision 13552)
+++ src/command.cpp	(working copy)
@@ -198,6 +198,9 @@
 DEF_COMMAND(CmdChangeTimetable);
 DEF_COMMAND(CmdSetVehicleOnTime);
 DEF_COMMAND(CmdAutofillTimetable);
+
+DEF_COMMAND(CmdSetSharedBoolValues);
+DEF_COMMAND(CmdSetSharedIntValues);
 #undef DEF_COMMAND
 
 /**
@@ -346,6 +349,9 @@
 	{CmdChangeTimetable,                     0}, /* CMD_CHANGE_TIMETABLE */
 	{CmdSetVehicleOnTime,                    0}, /* CMD_SET_VEHICLE_ON_TIME */
 	{CmdAutofillTimetable,                   0}, /* CMD_AUTOFILL_TIMETABLE */
+
+	{CmdSetSharedBoolValues,                 0}, /* CMD_SET_SHARED_BOOL_VALUES */
+	{CmdSetSharedIntValues,                  0}, /* CMD_SET_SHARED_INT_VALUES */
 };
 
 /*!
Index: src/player_base.h
===================================================================
--- src/player_base.h	(revision 13552)
+++ src/player_base.h	(working copy)
@@ -71,6 +71,26 @@
 	int16 engine_renew_months;
 	uint32 engine_renew_money;
 	uint16 *num_engines; ///< caches the number of engines of each type the player owns (no need to save this)
+
+	/** Shared infrastructure
+	 * first element is actual value
+	 * second is value to be set at end of shared_change_months counter
+	 * (see patch value of shared_delay)
+	 */
+	bool shared_railway_tracks[2];
+	bool shared_railway_stations[2];
+	bool shared_railway_depots[2];
+	uint16 shared_tontile_cost[2];
+	uint8 shared_road_stops_fee[2];
+	uint8 shared_harbours_fee[2];
+	bool shared_airports[2];
+	uint16 shared_landing_fee[2];
+	bool shared_road_depots[2];
+	bool shared_road_stops[2];
+	bool shared_water_depots[2];
+	bool shared_harbours[2];
+	uint8 shared_provision[2];
+	uint8 shared_change_months;
 };
 
 struct PlayerMoneyBackup {
Index: src/settings_type.h
===================================================================
--- src/settings_type.h	(revision 13552)
+++ src/settings_type.h	(working copy)
@@ -304,6 +304,25 @@
 	byte   station_spread;                   ///< amount a station may spread
 };
 
+ /** Shared Infrastructure **/
+struct SharingSettings {
+  	bool shared_railway_stations;          ///< allow railway stations sharing
+  	bool shared_railway_tracks;            ///< allow railway tracks sharing
+  	bool shared_railway_depots;            ///< allow railway depots sharing
+  	bool shared_road_depots;               ///< allow road depots sharing
+  	bool shared_road_stops;                ///< allow road stops sharing
+  	bool shared_water_depots;              ///< allow water depots sharing
+  	bool shared_harbours;                  ///< allow harbours sharing
+  	bool shared_airports;                  ///< allow airports sharing
+  	int8 shared_provision;                 ///< default value for depots provision (buy cost %)
+  	uint16 shared_tontile_cost;            ///< default value for tracks sharing payment (per 1000 tons per tiles)
+  	uint16 shared_landing_fee;             ///< default value for airports landing fee (per tons of cargo capacity)
+  	int8 shared_road_stops_fee;            ///< default value for entering road stops (per tons of cargo capacity)
+  	int8 shared_harbours_fee;              ///< default value for entering harbours (per tons of cargo capacity)
+  	bool shared_player_level;              ///< allow players to set individual sharing settings
+  	uint8 shared_delay;                    ///< delay before activating individual sharing settings 
+};  
+
 /** All settings together for the game. */
 struct GameSettings {
 	DifficultySettings   difficulty;         ///< settings related to the difficulty
@@ -315,6 +334,7 @@
 	VehicleSettings      vehicle;            ///< options for vehicles
 	EconomySettings      economy;            ///< settings to change the economy
 	StationSettings      station;            ///< settings related to station management
+ 	SharingSettings		 sharing;            ///< settings related to infrastructure sharing
 	LocaleSettings       locale;             ///< settings related to used currency/unit system in the current game
 };
 
Index: src/depot_gui.cpp
===================================================================
--- src/depot_gui.cpp	(revision 13552)
+++ src/depot_gui.cpp	(working copy)
@@ -27,6 +27,7 @@
 #include "tilehighlight_func.h"
 #include "window_gui.h"
 #include "vehiclelist.h"
+#include "sharedinfrastructure.h"
 
 #include "table/strings.h"
 #include "table/sprites.h"
@@ -314,7 +315,7 @@
 		uint16 boxes_in_each_row = this->widget[DEPOT_WIDGET_MATRIX].data & 0xFF;
 
 		/* setup disabled buttons */
-		this->SetWidgetsDisabledState(!IsTileOwner(tile, _local_player),
+		this->SetWidgetsDisabledState(!IsTileOwner(tile, _local_player) && !SharedDepotVehicleType(tile,_local_player, this->type),
 			DEPOT_WIDGET_STOP_ALL,
 			DEPOT_WIDGET_START_ALL,
 			DEPOT_WIDGET_SELL,
Index: src/command_type.h
===================================================================
--- src/command_type.h	(revision 13552)
+++ src/command_type.h	(working copy)
@@ -278,6 +278,8 @@
 	CMD_CHANGE_TIMETABLE,             ///< change the timetable for a vehicle
 	CMD_SET_VEHICLE_ON_TIME,          ///< set the vehicle on time feature (timetable)
 	CMD_AUTOFILL_TIMETABLE,           ///< autofill the timetable
+	CMD_SET_SHARED_BOOL_VALUES,       ///< set shared infrastructure player bool value
+	CMD_SET_SHARED_INT_VALUES,        ///< set shared infrastructure player int value
 };
 
 /**
Index: src/order_gui.cpp
===================================================================
--- src/order_gui.cpp	(revision 13552)
+++ src/order_gui.cpp	(working copy)
@@ -31,6 +31,7 @@
 #include "string_func.h"
 #include "depot_base.h"
 #include "tilehighlight_func.h"
+#include "sharedinfrastructure.h"
 
 #include "table/sprites.h"
 #include "table/strings.h"
@@ -271,7 +272,7 @@
 	if (_settings_game.order.gotodepot) {
 		switch (GetTileType(tile)) {
 			case MP_RAILWAY:
-				if (v->type == VEH_TRAIN && IsTileOwner(tile, _local_player)) {
+ 				if (v->type == VEH_TRAIN && (IsTileOwner(tile, _local_player) || SharedRailwayDepots(tile, _local_player))) {
 					if (IsRailDepot(tile)) {
 						order.MakeGoToDepot(GetDepotByTile(tile)->index, ODTFB_PART_OF_ORDERS);
 						if (_settings_client.gui.new_nonstop) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
@@ -281,7 +282,7 @@
 				break;
 
 			case MP_ROAD:
-				if (IsRoadDepot(tile) && v->type == VEH_ROAD && IsTileOwner(tile, _local_player)) {
+				if (IsRoadDepot(tile) && v->type == VEH_ROAD && (IsTileOwner(tile, _local_player) || SharedRoadDepots(tile, _local_player))) {
 					order.MakeGoToDepot(GetDepotByTile(tile)->index, ODTFB_PART_OF_ORDERS);
 					if (_settings_client.gui.new_nonstop) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
 					return order;
@@ -290,7 +291,7 @@
 
 			case MP_STATION:
 				if (v->type != VEH_AIRCRAFT) break;
-				if (IsHangar(tile) && IsTileOwner(tile, _local_player)) {
+				if (IsHangar(tile) && (IsTileOwner(tile, _local_player) || SharedAirports(tile, _local_player))) {
 					order.MakeGoToDepot(GetStationIndex(tile), ODTFB_PART_OF_ORDERS);
 					return order;
 				}
@@ -298,9 +299,8 @@
 
 			case MP_WATER:
 				if (v->type != VEH_SHIP) break;
-				if (IsShipDepot(tile) && IsTileOwner(tile, _local_player)) {
+				if (IsShipDepot(tile) && (IsTileOwner(tile, _local_player)||SharedWaterDepots(tile, _local_player))) {
 					TileIndex tile2 = GetOtherShipDepotTile(tile);
-
 					order.MakeGoToDepot(GetDepotByTile(tile < tile2 ? tile : tile2)->index, ODTFB_PART_OF_ORDERS);
 					return order;
 				}
@@ -313,7 +313,7 @@
 	/* check waypoint */
 	if (IsTileType(tile, MP_RAILWAY) &&
 			v->type == VEH_TRAIN &&
-			IsTileOwner(tile, _local_player) &&
+			(IsTileOwner(tile, _local_player)||SharedTracks(tile, _local_player)) &&
 			IsRailWaypoint(tile)) {
 		order.MakeGoToWaypoint(GetWaypointByTile(tile)->index);
 		if (_settings_client.gui.new_nonstop) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
@@ -324,19 +324,22 @@
 		StationID st_index = GetStationIndex(tile);
 		const Station *st = GetStation(st_index);
 
-		if (st->owner == _current_player || st->owner == OWNER_NONE) {
 			byte facil;
 			(facil = FACIL_DOCK, v->type == VEH_SHIP) ||
 			(facil = FACIL_TRAIN, v->type == VEH_TRAIN) ||
 			(facil = FACIL_AIRPORT, v->type == VEH_AIRCRAFT) ||
 			(facil = FACIL_BUS_STOP, v->type == VEH_ROAD && IsCargoInClass(v->cargo_type, CC_PASSENGERS)) ||
 			(facil = FACIL_TRUCK_STOP, 1);
-			if (st->facilities & facil) {
-				order.MakeGoToStation(st_index);
-				if (_settings_client.gui.new_nonstop && (v->type == VEH_TRAIN || v->type == VEH_ROAD)) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
-				return order;
+			if(((facil==FACIL_DOCK) && ((st->owner == _current_player) || SharedHarbours(tile, _current_player))) ||
+  			   ((facil==FACIL_TRAIN) && ((st->owner == _current_player) || SharedRailwayStations(tile, _current_player))) ||
+  			   ((facil==FACIL_AIRPORT) && ((st->owner == _current_player) || SharedAirports(tile, _current_player))) ||
+  			   (((facil==FACIL_BUS_STOP)||(facil==FACIL_TRUCK_STOP)) && ((st->owner == _current_player) || SharedRoadStops(tile, _current_player)))) {
+  					if (st->facilities & facil) {
+  						order.MakeGoToStation(st_index);
+  						if (_settings_client.gui.new_nonstop && (v->type == VEH_TRAIN || v->type == VEH_ROAD)) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
+  						return order;
+  					}
 			}
-		}
 	}
 
 	/* not found */
Index: src/cargopacket.h
===================================================================
--- src/cargopacket.h	(revision 13552)
+++ src/cargopacket.h	(working copy)
@@ -7,6 +7,7 @@
 
 #include "oldpool.h"
 #include "economy_type.h"
+#include "player_type.h"
 #include "tile_type.h"
 #include "station_type.h"
 #include <list>
@@ -24,7 +25,7 @@
  * Container for cargo from the same location and time
  */
 struct CargoPacket : PoolItem<CargoPacket, CargoPacketID, &_CargoPacket_pool> {
-	Money feeder_share;     ///< Value of feeder pickup to be paid for on delivery of cargo
+	Money feeder_share[MAX_PLAYERS];     ///< Value of feeder pickup to be paid for on delivery of cargo
 	TileIndex source_xy;    ///< The origin of the cargo (first station in feeder chain)
 	TileIndex loaded_at_xy; ///< Location where this cargo has been loaded into the vehicle
 	StationID source;       ///< The station where the cargo came from first
Index: src/economy.cpp
===================================================================
--- src/economy.cpp	(revision 13552)
+++ src/economy.cpp	(working copy)
@@ -45,6 +45,7 @@
 #include "gfx_func.h"
 #include "autoreplace_func.h"
 #include "player_gui.h"
+#include "sharedinfrastructure.h"
 
 #include "table/strings.h"
 #include "table/sprites.h"
@@ -383,6 +384,8 @@
 					DeleteWindowById(WC_VEHICLE_VIEW, v->index);
 					DeleteWindowById(WC_VEHICLE_DETAILS, v->index);
 					DeleteWindowById(WC_VEHICLE_ORDERS, v->index);
+					/* clean shared infrastructure */
+					UpdateSharedOnRemove(v->index);
 
 					if (v->IsPrimaryVehicle() || (v->type == VEH_TRAIN && IsFreeWagon(v))) {
 						switch (v->type) {
@@ -392,7 +395,11 @@
 								Vehicle *u = v;
 								do {
 									Vehicle *next = GetNextVehicle(u);
+									TileIndex old_tile = v->tile;
+									DiagDirection old_dir = DirToDiagDir(v->direction);
 									delete u;
+									/* now that vehicle is removed, clear signal */
+									UpdateSignalsOnSegment(old_tile, old_dir, GetTileOwner(old_tile));
 									u = next;
 								} while (u != NULL);
 							} break;
@@ -423,6 +430,12 @@
 			}
 		}
 	}
+	
+	/** take care of other players vehicles on bankrupt company's shared structure
+	 * at this point, there should be no vehicle left to old_player */
+	if (new_player == PLAYER_SPECTATOR) {
+		OnSharedClose(old_player, SHARED_ALL);
+	}
 
 	/*  Change ownership of tiles */
 	{
@@ -1362,8 +1375,10 @@
 	int result = 0;
 
 	Money vehicle_profit = 0; // Money paid to the train
-	Money route_profit   = 0; // The grand total amount for the route. A-D of transfer chain A-B-C-D
+	Money route_profit[MAX_PLAYERS] = {0};  // The grand total amount for the route. A-D of transfer chain A-B-C-D
+	bool route_profit_change = false;
 	Money virtual_profit = 0; // The virtual profit for entire vehicle chain
+	const Player* p;
 
 	StationID last_visited = front_v->last_station_visited;
 	Station *st = GetStation(last_visited);
@@ -1403,8 +1418,13 @@
 				/* handle end of route payment */
 				Money profit = DeliverGoods(cp->count, v->cargo_type, cp->source, last_visited, cp->source_xy, cp->days_in_transit);
 				cp->paid_for = true;
-				route_profit   += profit; // display amount paid for final route delivery, A-D of a chain A-B-C-D
-				vehicle_profit += profit - cp->feeder_share;                    // whole vehicle is not payed for transfers picked up earlier
+				FOR_ALL_PLAYERS(p) {   // display amount paid for final route delivery, A-D of a chain A-B-C-D
+					route_profit[p->index] += cp->feeder_share[p->index];
+					profit -= cp->feeder_share[p->index]; // whole vehicle is not payed for transfers picked up earlier
+				}
+				route_profit[v->owner] += profit;
+				vehicle_profit += profit;
+				route_profit_change = true;
 
 				result |= 1;
 
@@ -1420,7 +1440,7 @@
 
 					front_v->profit_this_year += profit << 8;
 					virtual_profit   += profit; // accumulate transfer profits for whole vehicle
-					cp->feeder_share += profit; // account for the (virtual) profit already made for the cargo packet
+					cp->feeder_share[front_v->owner] += profit; // account for the (virtual) profit already made for the cargo packet
 					cp->paid_for      = true;   // record that the cargo has been paid for to eliminate double counting
 				}
 				result |= 2;
@@ -1435,9 +1455,13 @@
 		ShowFeederIncomeAnimation(front_v->x_pos, front_v->y_pos, front_v->z_pos, virtual_profit);
 	}
 
-	if (route_profit != 0) {
+	if (route_profit_change) {
 		front_v->profit_this_year += vehicle_profit << 8;
-		SubtractMoneyFromPlayer(CommandCost(front_v->GetExpenseType(true), -route_profit));
+		FOR_ALL_PLAYERS(p) {
+			_current_player = p->index;
+			SubtractMoneyFromPlayer(CommandCost(front_v->GetExpenseType(true), -route_profit[p->index]));
+		}
+		_current_player = front_v->owner;
 
 		if (IsLocalPlayer() && !PlayVehicleSound(front_v, VSE_LOAD_UNLOAD)) {
 			SndPlayVehicleFx(SND_14_CASHTILL, front_v);
Index: src/news_gui.cpp
===================================================================
--- src/news_gui.cpp	(revision 13552)
+++ src/news_gui.cpp	(working copy)
@@ -133,6 +133,7 @@
 	{ NT_COMPANY_INFO,    NM_NORMAL,   NF_NONE,                DrawNewsBankrupcy       }, ///< NS_COMPANY_BANKRUPT
 	{ NT_COMPANY_INFO,    NM_NORMAL,   NF_TILE,                DrawNewsBankrupcy       }, ///< NS_COMPANY_NEW
 	{ NT_OPENCLOSE,       NM_THIN,     NF_VIEWPORT|NF_TILE,    NULL                    }, ///< NS_OPENCLOSE
+	{ NT_COMPANY_INFO,    NM_NORMAL,   NF_VIEWPORT | NF_TILE,  NULL                    }, ///< NS_COMPANY_SHARING
 	{ NT_ECONOMY,         NM_NORMAL,   NF_NONE,                NULL                    }, ///< NS_ECONOMY
 	{ NT_INDUSTRY_PLAYER, NM_THIN,     NF_VIEWPORT|NF_TILE,    NULL                    }, ///< NS_INDUSTRY_PLAYER
 	{ NT_INDUSTRY_OTHER,  NM_THIN,     NF_VIEWPORT|NF_TILE,    NULL                    }, ///< NS_INDUSTRY_OTHER
Index: src/cargopacket.cpp
===================================================================
--- src/cargopacket.cpp	(revision 13552)
+++ src/cargopacket.cpp	(working copy)
@@ -8,6 +8,7 @@
 #include "cargopacket.h"
 #include "saveload.h"
 #include "oldpool_func.h"
+#include "player_base.h"
 
 /* Initialize the cargopacket-pool */
 DEFINE_OLD_POOL_GENERIC(CargoPacket, CargoPacket)
@@ -21,6 +22,8 @@
 
 CargoPacket::CargoPacket(StationID source, uint16 count)
 {
+	const Player* p;
+
 	if (source != INVALID_STATION) assert(count != 0);
 
 	this->source          = source;
@@ -29,7 +32,8 @@
 
 	this->count           = count;
 	this->days_in_transit = 0;
-	this->feeder_share    = 0;
+	FOR_ALL_PLAYERS(p)
+		this->feeder_share[p->index]= 0;
 	this->paid_for        = false;
 }
 
@@ -49,7 +53,8 @@
 	SLE_VAR(CargoPacket, loaded_at_xy,    SLE_UINT32),
 	SLE_VAR(CargoPacket, count,           SLE_UINT16),
 	SLE_VAR(CargoPacket, days_in_transit, SLE_UINT8),
-	SLE_VAR(CargoPacket, feeder_share,    SLE_INT64),
+	SLE_CONDVAR(CargoPacket, feeder_share[0], SLE_INT64, 0, 95),
+	SLE_CONDARR(CargoPacket, feeder_share,    SLE_INT64, MAX_PLAYERS, 95, SL_MAX_VERSION),
 	SLE_VAR(CargoPacket, paid_for,        SLE_BOOL),
 
 	SLE_END()
@@ -142,13 +147,16 @@
 
 void CargoList::Append(CargoPacket *cp)
 {
+	const Player* p;
+
 	assert(cp != NULL);
 	assert(cp->IsValid());
 
 	for (List::iterator it = packets.begin(); it != packets.end(); it++) {
 		if ((*it)->SameSource(cp) && (*it)->count + cp->count <= 65535) {
 			(*it)->count        += cp->count;
-			(*it)->feeder_share += cp->feeder_share;
+			FOR_ALL_PLAYERS(p)
+				(*it)->feeder_share[p->index] += cp->feeder_share[p->index];
 			delete cp;
 
 			InvalidateCache();
@@ -189,6 +197,7 @@
 {
 	assert(mta == MTA_FINAL_DELIVERY || dest != NULL);
 	CargoList tmp;
+	const Player* p;
 
 	while (!packets.empty() && count > 0) {
 		CargoPacket *cp = *packets.begin();
@@ -223,14 +232,16 @@
 				cp_new->loaded_at_xy    = (mta == MTA_CARGO_LOAD) ? data : cp->loaded_at_xy;
 
 				cp_new->days_in_transit = cp->days_in_transit;
-				cp_new->feeder_share    = cp->feeder_share / count;
+				FOR_ALL_PLAYERS(p)
+					cp_new->feeder_share[p->index] = cp->feeder_share[p->index] / count;
 				/* When cargo is moved into another vehicle you have *always* paid for it */
 				cp_new->paid_for        = (mta == MTA_CARGO_LOAD) ? false : cp->paid_for;
 
 				cp_new->count = count;
 				dest->packets.push_back(cp_new);
 
-				cp->feeder_share /= cp->count - count;
+				FOR_ALL_PLAYERS(p)
+					cp->feeder_share[p->index] /= cp->count - count;
 			}
 			cp->count -= count;
 
@@ -260,6 +271,7 @@
 	feeder_share = 0;
 	source = INVALID_STATION;
 	days_in_transit = 0;
+	const Player* p;
 
 	if (empty) return;
 
@@ -268,7 +280,8 @@
 		count        += (*it)->count;
 		unpaid_cargo |= !(*it)->paid_for;
 		dit          += (*it)->days_in_transit * (*it)->count;
-		feeder_share += (*it)->feeder_share;
+		FOR_ALL_PLAYERS(p)
+			feeder_share += (*it)->feeder_share[p->index];
 	}
 	days_in_transit = dit / count;
 	source = (*packets.begin())->source;
Index: src/vehicle_gui.cpp
===================================================================
--- src/vehicle_gui.cpp	(revision 13552)
+++ src/vehicle_gui.cpp	(working copy)
@@ -1846,16 +1846,17 @@
 		const Vehicle *v = GetVehicle(this->window_number);
 		StringID str;
 		bool is_localplayer = v->owner == _local_player;
+		TileIndex tile = v->tile;
+		bool is_trackowner  = IsTileOwner(tile,_local_player);
 		bool refitable_and_stopped_in_depot = IsVehicleRefitable(v);
 
 		this->SetWidgetDisabledState(VVW_WIDGET_GOTO_DEPOT, !is_localplayer);
-		this->SetWidgetDisabledState(VVW_WIDGET_REFIT_VEH,
-																!refitable_and_stopped_in_depot || !is_localplayer);
+		this->SetWidgetDisabledState(VVW_WIDGET_REFIT_VEH, !refitable_and_stopped_in_depot || !is_localplayer);
 		this->SetWidgetDisabledState(VVW_WIDGET_CLONE_VEH, !is_localplayer);
 
 		if (v->type == VEH_TRAIN) {
-			this->SetWidgetDisabledState(VVW_WIDGET_FORCE_PROCEED, !is_localplayer);
-			this->SetWidgetDisabledState(VVW_WIDGET_TURN_AROUND, !is_localplayer);
+			this->SetWidgetDisabledState(VVW_WIDGET_FORCE_PROCEED, !is_trackowner);
+			this->SetWidgetDisabledState(VVW_WIDGET_TURN_AROUND, !is_trackowner);
 
 			/* Cargo refit button is disabled, until we know we can enable it below. */
 
Index: src/pathfind.cpp
===================================================================
--- src/pathfind.cpp	(revision 13552)
+++ src/pathfind.cpp	(working copy)
@@ -17,6 +17,7 @@
 #include "core/random_func.hpp"
 #include "core/alloc_type.hpp"
 #include "tunnelbridge.h"
+#include "sharedinfrastructure.h"
 
 /* remember which tiles we have already visited so we don't visit them again. */
 static bool TPFSetTileBit(TrackPathFinder *tpf, TileIndex tile, int dir)
Index: src/yapf/follow_track.hpp
===================================================================
--- src/yapf/follow_track.hpp	(revision 13552)
+++ src/yapf/follow_track.hpp	(working copy)
@@ -6,7 +6,9 @@
 #define  FOLLOW_TRACK_HPP
 
 #include "yapf.hpp"
+#include "../rail_map.h"
 #include "../depot_map.h"
+#include "../sharedinfrastructure.h"
 
 /** Track follower helper template class (can serve pathfinders and vehicle
  *  controllers). See 6 different typedefs below for 3 different transport
@@ -217,12 +219,13 @@
 				return false;
 			}
 		}
-
-		/* single tram bits can only be entered from one direction */
-		DiagDirection single_tram = GetSingleTramBit(m_new_tile);
-		if (single_tram != INVALID_DIAGDIR && single_tram != ReverseDiagDir(m_exitdir)) {
-			m_err = EC_NO_WAY;
-			return false;
+		
+		// waypoints are not accessible to other companies
+		if ( IsTileType(m_new_tile, MP_RAILWAY) && IsRailTT() && (GetTileOwner(m_new_tile) != m_veh->owner)) {
+			if (GetRailTileType(m_new_tile) == RAIL_TILE_WAYPOINT) {
+				m_err = EC_NO_WAY;
+				return false;
+			}
 		}
 
 		// road and rail depots can also be entered from one direction only
@@ -233,25 +236,35 @@
 				return false;
 			}
 			// don't try to enter other player's depots
-			if (GetTileOwner(m_new_tile) != m_veh->owner) {
+			if ((GetTileOwner(m_new_tile) != m_veh->owner)&&(!SharedRoadDepots(m_new_tile,m_veh->owner))) {
 				m_err = EC_OWNER;
 				return false;
 			}
 		}
 		if (IsRailTT() && IsDepotTypeTile(m_new_tile, TT())) {
 			DiagDirection exitdir = GetRailDepotDirection(m_new_tile);
-			if (ReverseDiagDir(exitdir) != m_exitdir) {
+			if ((ReverseDiagDir(exitdir) != m_exitdir)||
+					(((GetTileOwner(m_new_tile) != m_veh->owner)&&
+					  (!SharedRailwayDepots(m_new_tile,m_veh->owner))))) {
 				m_err = EC_NO_WAY;
 				return false;
 			}
 		}
 
 		// rail transport is possible only on tiles with the same owner as vehicle
-		if (IsRailTT() && GetTileOwner(m_new_tile) != m_veh->owner) {
+		if (IsRailTT() && (GetTileOwner(m_new_tile) != m_veh->owner) &&
+				(GetTileOwner(m_old_tile) != GetTileOwner(m_new_tile)) && (!SharedTracks(m_new_tile,m_veh->owner))) {
 			// different owner
 			m_err = EC_NO_WAY;
 			return false;
 		}
+		
+		/* single tram bits can only be entered from one direction */
+		DiagDirection single_tram = GetSingleTramBit(m_new_tile);
+		if (single_tram != INVALID_DIAGDIR && single_tram != ReverseDiagDir(m_exitdir)) {
+			m_err = EC_NO_WAY;
+			return false;
+		}
 
 		// rail transport is possible only on compatible rail types
 		if (IsRailTT()) {
@@ -286,6 +299,11 @@
 
 		// special handling for rail stations - get to the end of platform
 		if (IsRailTT() && m_is_station) {
+			if((GetTileOwner(m_new_tile) != m_veh->owner) && (!SharedRailwayStations(m_new_tile,m_veh->owner)))
+			{
+				m_err = EC_NO_WAY;
+				return false;
+			}
 			// entered railway station
 			// get platform length
 			uint length = GetStationByTile(m_new_tile)->GetPlatformLength(m_new_tile, TrackdirToExitdir(m_old_td));
Index: src/players.cpp
===================================================================
--- src/players.cpp	(revision 13552)
+++ src/players.cpp	(working copy)
@@ -241,13 +241,15 @@
 	if (HasBit(1 << EXPENSES_TRAIN_INC    |
 	           1 << EXPENSES_ROADVEH_INC  |
 	           1 << EXPENSES_AIRCRAFT_INC |
-	           1 << EXPENSES_SHIP_INC, cost.GetExpensesType())) {
+	           1 << EXPENSES_SHIP_INC |
+	           1 << EXPENSES_SHARED_INF_INC, cost.GetExpensesType())) {
 		p->cur_economy.income -= cost.GetCost();
 	} else if (HasBit(1 << EXPENSES_TRAIN_RUN    |
 	                  1 << EXPENSES_ROADVEH_RUN  |
 	                  1 << EXPENSES_AIRCRAFT_RUN |
 	                  1 << EXPENSES_SHIP_RUN     |
 	                  1 << EXPENSES_PROPERTY     |
+	                  1 << EXPENSES_SHARED_INF_RUN |
 	                  1 << EXPENSES_LOAN_INT, cost.GetExpensesType())) {
 		p->cur_economy.expenses -= cost.GetCost();
 	}
@@ -558,6 +560,21 @@
 	free(p->num_engines);
 	p->num_engines = CallocT<uint16>(GetEnginePoolSize());
 
+	p->shared_railway_tracks[0] = p->shared_railway_tracks[1] =_settings_game.sharing.shared_railway_tracks;
+	p->shared_railway_stations[0] = p->shared_railway_stations[1] = _settings_game.sharing.shared_railway_stations;
+	p->shared_railway_depots[0] = p->shared_railway_depots[1] = _settings_game.sharing.shared_railway_depots;
+	p->shared_tontile_cost[0] = p->shared_tontile_cost[1] = _settings_game.sharing.shared_tontile_cost;
+	p->shared_road_stops_fee[0] = p->shared_road_stops_fee[1] = 0; // no limit
+	p->shared_harbours_fee[0] = p->shared_harbours_fee[1] = 0; // no limit
+	p->shared_airports[0] = p->shared_airports[1] = _settings_game.sharing.shared_airports;
+	p->shared_landing_fee[0] = p->shared_landing_fee[1] = _settings_game.sharing.shared_landing_fee;
+	p->shared_road_depots[0] = p->shared_road_depots[1] = _settings_game.sharing.shared_road_depots;
+	p->shared_road_stops[0] = p->shared_road_stops[1] = _settings_game.sharing.shared_road_stops;
+	p->shared_water_depots[0] = p->shared_water_depots[1] = _settings_game.sharing.shared_water_depots;
+	p->shared_harbours[0] = p->shared_harbours[1] = _settings_game.sharing.shared_harbours;
+	p->shared_provision[0] = p->shared_provision[1] = _settings_game.sharing.shared_provision;
+	p->shared_change_months = 0;
+
 	return p;
 }
 
@@ -1184,6 +1201,21 @@
 	SLE_CONDVAR(Player, engine_renew_money,    SLE_UINT32,                 16, SL_MAX_VERSION),
 	SLE_CONDVAR(Player, renew_keep_length,     SLE_BOOL,                    2, SL_MAX_VERSION), // added with 16.1, but was blank since 2
 
+	SLE_CONDARR(Player, shared_railway_tracks,   SLE_BOOL,  2,                96, SL_MAX_VERSION),
+	SLE_CONDARR(Player, shared_railway_stations, SLE_BOOL,  2,                96, SL_MAX_VERSION),
+	SLE_CONDARR(Player, shared_railway_depots,   SLE_BOOL,  2,                96, SL_MAX_VERSION),
+	SLE_CONDARR(Player, shared_airports,         SLE_BOOL,  2,                96, SL_MAX_VERSION),
+	SLE_CONDARR(Player, shared_road_depots,      SLE_BOOL,  2,                96, SL_MAX_VERSION),
+	SLE_CONDARR(Player, shared_road_stops,       SLE_BOOL,  2,                96, SL_MAX_VERSION),
+	SLE_CONDARR(Player, shared_water_depots,     SLE_BOOL,  2,                96, SL_MAX_VERSION),
+	SLE_CONDARR(Player, shared_harbours,         SLE_BOOL,  2,                96, SL_MAX_VERSION),
+	SLE_CONDARR(Player, shared_tontile_cost,     SLE_INT16, 2,                96, SL_MAX_VERSION),
+	SLE_CONDARR(Player, shared_road_stops_fee,   SLE_INT8,  2,                96, SL_MAX_VERSION),
+	SLE_CONDARR(Player, shared_harbours_fee,     SLE_INT8,  2,                96, SL_MAX_VERSION),
+	SLE_CONDARR(Player, shared_landing_fee,      SLE_INT16, 2,                96, SL_MAX_VERSION),
+	SLE_CONDARR(Player, shared_provision,        SLE_INT8,  2,                96, SL_MAX_VERSION),
+	SLE_CONDVAR(Player, shared_change_months,    SLE_INT8,                    96, SL_MAX_VERSION),
+
 	/* reserve extra space in savegame here. (currently 63 bytes) */
 	SLE_CONDNULL(63, 2, SL_MAX_VERSION),
 
Index: src/roadveh_cmd.cpp
===================================================================
--- src/roadveh_cmd.cpp	(revision 13552)
+++ src/roadveh_cmd.cpp	(working copy)
@@ -43,6 +43,7 @@
 #include "depot_base.h"
 #include "depot_func.h"
 #include "effectvehicle_func.h"
+#include "sharedinfrastructure.h"
 
 #include "table/strings.h"
 
@@ -187,7 +188,7 @@
 	/* The ai_new queries the vehicle cost before building the route,
 	 * so we must check against cheaters no sooner than now. --pasky */
 	if (!IsRoadDepotTile(tile)) return CMD_ERROR;
-	if (!IsTileOwner(tile, _current_player)) return CMD_ERROR;
+	if (!IsTileOwner(tile, _current_player) && !SharedRoadDepots(tile, _current_player)) return CMD_ERROR;
 
 	if (HasTileRoadType(tile, ROADTYPE_TRAM) != HasBit(EngInfo(p1)->misc_flags, EF_ROAD_TRAM)) return_cmd_error(STR_DEPOT_WRONG_DEPOT_TYPE);
 
@@ -288,6 +289,7 @@
 		GetPlayer(_current_player)->num_engines[p1]++;
 	}
 
+	SharedDepotProvision(cost, GetTileOwner(tile), flags);
 	return cost;
 }
 
@@ -823,6 +825,7 @@
 
 static void RoadVehArrivesAt(const Vehicle* v, Station* st)
 {
+	if (st->owner != v->owner) SharedStationFee(st->owner, v->index);
 	if (IsCargoInClass(v->cargo_type, CC_PASSENGERS)) {
 		/* Check if station was ever visited before */
 		if (!(st->had_vehicle_of_type & HVOT_BUS)) {
@@ -834,7 +837,7 @@
 				v->index,
 				0);
 		}
-	} else {
+	} else {		
 		/* Check if station was ever visited before */
 		if (!(st->had_vehicle_of_type & HVOT_TRUCK)) {
 			st->had_vehicle_of_type |= HVOT_TRUCK;
@@ -1066,14 +1069,14 @@
 	TrackdirBits trackdirs = TrackStatusToTrackdirBits(ts);
 
 	if (IsTileType(tile, MP_ROAD)) {
-		if (IsRoadDepot(tile) && (!IsTileOwner(tile, v->owner) || GetRoadDepotDirection(tile) == enterdir || (GetRoadTypes(tile) & v->u.road.compatible_roadtypes) == 0)) {
+		if (IsRoadDepot(tile) && ((!IsTileOwner(tile, v->owner) && !SharedRoadDepots(tile,v->owner)) || GetRoadDepotDirection(tile) == enterdir || (GetRoadTypes(tile) & v->u.road.compatible_roadtypes) == 0)) {
 			/* Road depot owned by another player or with the wrong orientation */
 			trackdirs = TRACKDIR_BIT_NONE;
 		}
 	} else if (IsTileType(tile, MP_STATION) && IsStandardRoadStopTile(tile)) {
 		/* Standard road stop (drive-through stops are treated as normal road) */
 
-		if (!IsTileOwner(tile, v->owner) || GetRoadStopDir(tile) == enterdir || RoadVehHasArticPart(v)) {
+		if (((!IsTileOwner(tile, v->owner))&& !SharedRoadStops(tile,v->owner)) || GetRoadStopDir(tile) == enterdir || RoadVehHasArticPart(v)) {
 			/* different station owner or wrong orientation or the vehicle has articulated parts */
 			trackdirs = TRACKDIR_BIT_NONE;
 		} else {
Index: src/economy_type.h
===================================================================
--- src/economy_type.h	(revision 13552)
+++ src/economy_type.h	(working copy)
@@ -118,10 +118,12 @@
 	EXPENSES_AIRCRAFT_RUN,
 	EXPENSES_SHIP_RUN,
 	EXPENSES_PROPERTY,
+	EXPENSES_SHARED_INF_RUN,
 	EXPENSES_TRAIN_INC,
 	EXPENSES_ROADVEH_INC,
 	EXPENSES_AIRCRAFT_INC,
 	EXPENSES_SHIP_INC,
+	EXPENSES_SHARED_INF_INC,
 	EXPENSES_LOAN_INT,
 	EXPENSES_OTHER,
 	EXPENSES_END,
Index: src/sharedinfrastructure.h
===================================================================
--- src/sharedinfrastructure.h	(revision 0)
+++ src/sharedinfrastructure.h	(revision 0)
@@ -0,0 +1,71 @@
+/* $Id: sharedinfrastructure.h $ */
+
+/** @file sharedinfrastructure.h Various declarations for shared infrastructures */
+
+#ifndef SHAREDINFRASTRUCTURE_H
+#define SHAREDINFRASTRUCTURE_H
+
+#include "openttd.h"
+#include "tile_type.h"
+#include "vehicle_type.h"
+
+/* bitmask of shared infrastructure */
+enum {
+	SHARED_NONE             =  0,             ///< No sharing
+	SHARED_RAILWAY_TRACKS   = (1 << 0),       ///< Railway tracks sharing 
+	SHARED_RAILWAY_STATIONS = (1 << 1),       ///< Railway station sharing
+	SHARED_RAILWAY_DEPOTS   = (1 << 2),       ///< Railway depots sharing
+	SHARED_AIRPORTS         = (1 << 3),       ///< Airports sharing
+	SHARED_ROAD_DEPOTS      = (1 << 4),       ///< Road depots sharing
+	SHARED_ROAD_STOPS       = (1 << 5),       ///< Road stops sharing
+	SHARED_WATER_DEPOTS     = (1 << 6),       ///< Water depots sharing
+	SHARED_HARBOURS         = (1 << 7),       ///< Road depots sharing
+	SHARED_ALL              = SHARED_RAILWAY_TRACKS | SHARED_RAILWAY_STATIONS | SHARED_RAILWAY_DEPOTS | SHARED_AIRPORTS
+					| SHARED_ROAD_DEPOTS | SHARED_ROAD_STOPS | SHARED_WATER_DEPOTS | SHARED_HARBOURS, ///< All sharing
+};
+
+/* variables for player's shared infrastructure GUI */
+extern bool _si_railway_tracks;               ///< allow railway tracks sharing
+extern bool _si_railway_stations;             ///< allow railway stations sharing
+extern bool _si_railway_depots;               ///< allow railway depots sharing
+extern bool _si_airports;                     ///< allow airports sharing
+extern bool _si_road_depots;                  ///< allow road depots sharing
+extern bool _si_road_stops;                   ///< allow road stops sharing
+extern bool _si_water_depots;                 ///< allow water depots sharing
+extern bool _si_harbours;                     ///< allow harbours sharing
+extern uint16 _si_tontile_cost;               ///< cost for tracks sharing payment (per 1000 tons per tiles)
+extern uint16 _si_landing_fee;                ///< cost for airports landing fee (per tons of cargo capacity)
+extern uint8 _si_provision;                   ///< value for depots provision (buy cost %)
+extern uint8 _si_road_stops_fee;              ///< cost for entering road stops (per tons of cargo capacity)
+extern uint8 _si_harbours_fee;                ///< cost for entering harbours (per tons of cargo capacity)
+
+/* shared infrastructure functions */
+bool SharedTracks(TileIndex tile, Owner owner);                               ///< check if tracks on tile are shared
+bool SharedRailwayStations(TileIndex tile, Owner owner);                      ///< check if railway station is shared
+bool SharedRailwayDepots(TileIndex tile, Owner owner);                        ///< check if railway depot is shared
+bool SharedRoadDepots(TileIndex tile, Owner owner);                           ///< check if road depot is shared
+bool SharedRoadStops(TileIndex tile, Owner owner);                            ///< check if road stops is shared
+bool SharedWaterDepots(TileIndex tile, Owner owner);                          ///< check if water depot is shared
+bool SharedHarbours(TileIndex tile, Owner owner);                             ///< check if harbour is shared
+bool SharedAirports(TileIndex tile, Owner owner);                             ///< check if airport is shared
+bool SharedDepotTransport(TileIndex tile, Owner owner, TransportType type);   ///< check if depot for this transport type is shared
+bool SharedDepotVehicleType(TileIndex tile, Owner owner, VehicleType type);   ///< check if depot for this vehicle type is shared
+bool SharedStation(TileIndex tile, Owner owner, VehicleType type);            ///< check if station is shared
+void SharedDepotProvision(CommandCost cost, Owner owner, uint32 flags);       ///< calculate depot provision
+void SharedStationFee(Owner station_owner, VehicleID vehicle);                ///< calculate station fee for this vehicle
+int32 SettingsEnableSharedRailwayStations(int32 p1);                          ///< activate railway tracks sharing when activating railway station sharing
+int32 SettingsEnableSharedRailwayTracks(int32 p1);                            ///< desactivate railway stations and depots sharing when removing tracks sharing
+void UpdateSharedOnRemove(VehicleID vehicle);                                 ///< clean infrastructure when removing vehicle
+void OnSharedClose(PlayerID old_player, uint closing_bit);                    ///< take care of vehicles on closing shared infrastructure
+void SharedCloseOnRoad (PlayerID p, VehicleID v);                             ///< remove road vehicles on closing shared infrastructure
+void SharedCloseOnRail (PlayerID p, VehicleID v);                             ///< remove rail vehicles on closing shared infrastructure
+void SharedCloseOnAir (PlayerID p, VehicleID v);                              ///< remove aircraft on closing shared airports 
+bool SharedCloseDepotTeleport (VehicleID v, uint16 depot);                    ///< teleport vehicle to depot, return false if failed
+bool SharedCloseHangarTeleport (VehicleID v, uint16 depot);                   ///< teleport vehicle to hangar, return false if failed
+uint16 SharedCloseGetFirstDepot (PlayerID p, VehicleID v, bool check_player); ///< get fist available depot to move vehicle on bankrupt company's shared infrastructure
+uint16 SharedCloseGetFirstHangar(PlayerID p, VehicleID v, bool check_player); ///< get fist available hangar to move aircraft on bankrupt company's shared airports
+
+CommandCost CmdSetSharedBoolValues(TileIndex tile, uint32 flags, uint32 p1, uint32 p2);  ///< set shared settings for player
+CommandCost CmdSetSharedIntValues(TileIndex tile, uint32 flags, uint32 p1, uint32 p2);   ///< set int shared settings for player
+
+#endif //SHAREDINFRASTRCUTURE_H
\ No newline at end of file
Index: src/signal.cpp
===================================================================
--- src/signal.cpp	(revision 13552)
+++ src/signal.cpp	(working copy)
@@ -18,6 +18,7 @@
 #include "track_func.h"
 #include "signal_func.h"
 #include "player_func.h"
+#include "sharedinfrastructure.h"
 
 
 /** these are the maximums used for updating signal blocks */
@@ -280,7 +281,7 @@
 
 		switch (GetTileType(tile)) {
 			case MP_RAILWAY: {
-				if (GetTileOwner(tile) != owner) continue; // do not propagate signals on others' tiles (remove for tracksharing)
+				if ((GetTileOwner(tile) != owner) && !SharedTracks(GetTileOwner(tile), owner)) continue; // do not propagate signals on tiles of those with whom you are not sharing track
 
 				if (IsRailDepot(tile)) {
 					if (enterdir == INVALID_DIAGDIR) { // from 'inside' - train just entered or left the depot
@@ -353,7 +354,7 @@
 
 			case MP_STATION:
 				if (!IsRailwayStation(tile)) continue;
-				if (GetTileOwner(tile) != owner) continue;
+				if ((GetTileOwner(tile) != owner) && !SharedTracks(GetTileOwner(tile), owner)) continue;
 				if (DiagDirToAxis(enterdir) != GetRailStationAxis(tile)) continue; // different axis
 				if (IsStationTileBlocked(tile)) continue; // 'eye-candy' station tile
 
@@ -363,7 +364,7 @@
 
 			case MP_ROAD:
 				if (!IsLevelCrossing(tile)) continue;
-				if (GetTileOwner(tile) != owner) continue;
+				if ((GetTileOwner(tile) != owner) && (!SharedTracks(GetTileOwner(tile), owner))) continue;
 				if (DiagDirToAxis(enterdir) == GetCrossingRoadAxis(tile)) continue; // different axis
 
 				if (!(flags & SF_TRAIN) && VehicleFromPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN;
@@ -371,7 +372,7 @@
 				break;
 
 			case MP_TUNNELBRIDGE: {
-				if (GetTileOwner(tile) != owner) continue;
+				if ((GetTileOwner(tile) != owner) && (!SharedTracks(GetTileOwner(tile), owner))) continue;
 				if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) continue;
 				DiagDirection dir = GetTunnelBridgeDirection(tile);
 
Index: src/vehicle.cpp
===================================================================
--- src/vehicle.cpp	(revision 13552)
+++ src/vehicle.cpp	(working copy)
@@ -1964,6 +1964,7 @@
 	SLE_CONDNULL(5,                                                         0, 57),
 	    SLE_VAR(Vehicle, engine_type,          SLE_UINT16),
 
+	    SLE_CONDARR(Vehicle, shared_tontiles,  SLE_UINT64, MAX_PLAYERS,     85, SL_MAX_VERSION),
 	    SLE_VAR(Vehicle, max_speed,            SLE_UINT16),
 	    SLE_VAR(Vehicle, cur_speed,            SLE_UINT16),
 	    SLE_VAR(Vehicle, subspeed,             SLE_UINT8),
@@ -2252,7 +2253,7 @@
 			cp->source_xy       = _cargo_source_xy;
 			cp->count           = _cargo_count;
 			cp->days_in_transit = _cargo_days;
-			cp->feeder_share    = _cargo_feeder_share;
+			cp->feeder_share[0] = _cargo_feeder_share;
 			cp->loaded_at_xy    = _cargo_loaded_at_xy;
 			v->cargo.Append(cp);
 		}
Index: src/vehicle_base.h
===================================================================
--- src/vehicle_base.h	(revision 13552)
+++ src/vehicle_base.h	(working copy)
@@ -193,6 +193,7 @@
 extern void AfterLoadVehicles(bool clear_te_id);
 struct LoadgameState;
 extern bool LoadOldVehicle(LoadgameState *ls, int num);
+// extern bool SharedCloseHangarTeleport (VehicleID vehicle, StationID station);
 
 struct Vehicle : PoolItem<Vehicle, VehicleID, &_Vehicle_pool>, BaseVehicle {
 private:
@@ -203,6 +204,7 @@
 	friend const SaveLoad *GetVehicleDescription(VehicleType vt); ///< So we can use private/protected variables in the saveload code
 	friend void AfterLoadVehicles(bool clear_te_id);              ///< So we can set the previous and first pointers while loading
 	friend bool LoadOldVehicle(LoadgameState *ls, int num);       ///< So we can set the proper next pointer while loading
+	friend bool SharedCloseHangarTeleport (VehicleID vehicle, StationID station); ///< So we can set the proper next pointer while teleporting an air vehicle
 
 	Vehicle *depot_list;     ///< NOSAVE: linked list to tell what vehicles entered a depot during the last tick. Used by autoreplace
 
@@ -264,6 +266,8 @@
 	int8 y_offs;             // y offset for vehicle sprite
 	EngineID engine_type;
 
+	OverflowSafeInt64 shared_tontiles[MAX_PLAYERS];  //Amount of tons*tiles traveled on shared tracks
+
 	TextEffectID fill_percent_te_id; // a text-effect id to a loading indicator object
 	UnitID unitnumber;       // unit number, for display purposes only
 
Index: src/player_gui.cpp
===================================================================
--- src/player_gui.cpp	(revision 13552)
+++ src/player_gui.cpp	(working copy)
@@ -29,6 +29,7 @@
 #include "widgets/dropdown_func.h"
 #include "widgets/dropdown_type.h"
 #include "tilehighlight_func.h"
+#include "sharedinfrastructure.h"
 
 #include "table/sprites.h"
 #include "table/strings.h"
@@ -1036,7 +1037,436 @@
 	new SelectPlayerFaceWindow(adv ? &_select_player_face_adv_desc : &_select_player_face_desc, parent, adv, top, left); // simple or advanced window
 }
 
+/** Widget description for the shared infrastructure selection dialog */
+static const Widget _shared_infrastructure_widgets[] = {
+{   WWT_CLOSEBOX,   RESIZE_NONE,   14,     0,   10,     0,   13, STR_00C5,                            STR_018B_CLOSE_WINDOW},              // SI_WIDGET_CLOSEBOX
+{    WWT_CAPTION,   RESIZE_NONE,   14,    11,  269,     0,   13, STR_SHARED_INFRASTRUCTURE_SELECTION, STR_018C_WINDOW_TITLE_DRAG_THIS},    // SI_WIDGET_CAPTION
+{      WWT_PANEL,   RESIZE_NONE,   14,     0,  269,    14,   64, 0x0,                                 STR_NULL},                           // SI_WIDGET_SELECT_SHARING_TRAIN
+{      WWT_PANEL,   RESIZE_NONE,   14,     0,  269,    65,   91, 0x0,                                 STR_NULL},                           // SI_WIDGET_SELECT_SHARING_AIR
+{      WWT_PANEL,   RESIZE_NONE,   14,     0,  269,    92,  130, 0x0,                                 STR_NULL},                           // SI_WIDGET_SELECT_SHARING_ROAD
+{      WWT_PANEL,   RESIZE_NONE,   14,     0,  269,   131,  169, 0x0,                                 STR_NULL},                           // SI_WIDGET_SELECT_SHARING_SHIP
+{      WWT_PANEL,   RESIZE_NONE,   14,     0,  269,   170,  206, 0x0,                                 STR_NULL},                           // SI_WIDGET_SELECT_SHARING_GENERAL
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   14,     0,   94,   195,  206, STR_012E_CANCEL,                     STR_NULL},                           // SI_WIDGET_CANCEL
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   14,    95,  269,   195,  206, STR_012F_OK,                         STR_SHARED_ACCEPT},                  // SI_WIDGET_ACCEPT
+{     WWT_IMGBTN,   RESIZE_NONE,   14,     2,   23,    16,   37, SPR_IMG_TRAINLIST,                   STR_NULL},                           // SI_WIDGET_TRAIN
+{     WWT_IMGBTN,   RESIZE_NONE,   14,     2,   23,    67,   88, SPR_IMG_AIRPLANESLIST,               STR_NULL},                           // SI_WIDGET_PLANE
+{     WWT_IMGBTN,   RESIZE_NONE,   14,     2,   23,    94,  115, SPR_IMG_TRUCKLIST,                   STR_NULL},                           // SI_WIDGET_ROAD
+{     WWT_IMGBTN,   RESIZE_NONE,   14,     2,   23,   133,  154, SPR_IMG_SHIPLIST,                    STR_NULL},                           // SI_WIDGET_SHIP
+{     WWT_IMGBTN,   RESIZE_NONE,   14,     2,   23,   172,  193, SPR_IMG_COMPANY_GENERAL,             STR_NULL},                           // SI_WIDGET_GENERAL
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   14,   175,  267,    16,   27, STR_EMPTY,                           STR_SHARED_RAILWAY_TRACKS},          // SI_WIDGET_SHARED_RAILWAY_TRACKS
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   14,   175,  267,    28,   39, STR_EMPTY,                           STR_SHARED_RAILWAY_STATIONS},        // SI_WIDGET_SHARED_RAILWAY_STATION
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   14,   175,  267,    40,   51, STR_EMPTY,                           STR_SHARED_RAILWAY_DEPOTS},          // SI_WIDGET_SHARED_RAILWAY_DEPOTS
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   14,   175,  267,    67,   78, STR_EMPTY,                           STR_SHARED_AIRPORTS},                // SI_WIDGET_SHARED_AIRPORTS
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   14,   175,  267,    94,  105, STR_EMPTY,                           STR_SHARED_ROAD_DEPOTS},             // SI_WIDGET_SHARED_ROAD_DEPOTS
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   14,   175,  267,   106,  117, STR_EMPTY,                           STR_SHARED_ROAD_STOPS},              // SI_WIDGET_SHARED_ROAD_STOPS
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   14,   175,  267,   133,  144, STR_EMPTY,                           STR_SHARED_WATER_DEPOTS},            // SI_WIDGET_SHARED_WATER_DEPOTS
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   14,   175,  267,   145,  156, STR_EMPTY,                           STR_SHARED_HARBOURS},                // SI_WIDGET_SHARED_HARBOURS
+{ WWT_PUSHIMGBTN,   RESIZE_NONE,   14,   175,  183,    52,   63, SPR_ARROW_LEFT,                      STR_SHARED_TONTILE_COST},            // SI_WIDGET_SHARED_TONTILE_COST_L
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   14,   184,  258,    52,   63, STR_EMPTY,                           STR_SHARED_TONTILE_COST},            // SI_WIDGET_SHARED_TONTILE_COST
+{ WWT_PUSHIMGBTN,   RESIZE_NONE,   14,   259,  267,    52,   63, SPR_ARROW_RIGHT,                     STR_SHARED_TONTILE_COST},            // SI_WIDGET_SHARED_TONTILE_COST_R
+{ WWT_PUSHIMGBTN,   RESIZE_NONE,   14,   175,  183,   118,  129, SPR_ARROW_LEFT,                      STR_SHARED_ROAD_STOPS_FEE},          // SI_WIDGET_SHARED_ROAD_STOPS_FEE_L
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   14,   184,  258,   118,  129, STR_EMPTY,                           STR_SHARED_ROAD_STOPS_FEE},          // SI_WIDGET_SHARED_ROAD_STOPS_FEE
+{ WWT_PUSHIMGBTN,   RESIZE_NONE,   14,   259,  267,   118,  129, SPR_ARROW_RIGHT,                     STR_SHARED_ROAD_STOPS_FEE},          // SI_WIDGET_SHARED_ROAD_STOPS_FEE_R
+{ WWT_PUSHIMGBTN,   RESIZE_NONE,   14,   175,  183,   157,  168, SPR_ARROW_LEFT,                      STR_SHARED_HARBOURS_FEE},         // SI_WIDGET_SHARED_HARBOURS_FEE_L
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   14,   184,  258,   157,  168, STR_EMPTY,                           STR_SHARED_HARBOURS_FEE},         // SI_WIDGET_SHARED_HARBOURS_FEE
+{ WWT_PUSHIMGBTN,   RESIZE_NONE,   14,   259,  267,   157,  168, SPR_ARROW_RIGHT,                     STR_SHARED_HARBOURS_FEE},         // SI_WIDGET_SHARED_HARBOURS_FEE_R
+{ WWT_PUSHIMGBTN,   RESIZE_NONE,   14,   175,  183,    79,   90, SPR_ARROW_LEFT,                      STR_SHARED_LANDING_FEE},             // SI_WIDGET_SHARED_LANDING_FEE_L
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   14,   184,  258,    79,   90, STR_EMPTY,                           STR_SHARED_LANDING_FEE},             // SI_WIDGET_SHARED_LANDING_FEE
+{ WWT_PUSHIMGBTN,   RESIZE_NONE,   14,   259,  267,    79,   90, SPR_ARROW_RIGHT,                     STR_SHARED_LANDING_FEE},             // SI_WIDGET_SHARED_LANDING_FEE_R
+{ WWT_PUSHIMGBTN,   RESIZE_NONE,   14,   175,  183,   172,  183, SPR_ARROW_LEFT,                      STR_SHARED_DEPOT_PROVISION},         // SI_WIDGET_SHARED_DEPOT_PROVISION_L
+{ WWT_PUSHTXTBTN,   RESIZE_NONE,   14,   184,  258,   172,  183, STR_EMPTY,                           STR_SHARED_DEPOT_PROVISION},         // SI_WIDGET_SHARED_DEPOT_PROVISION
+{ WWT_PUSHIMGBTN,   RESIZE_NONE,   14,   259,  267,   172,  183, SPR_ARROW_RIGHT,                     STR_SHARED_DEPOT_PROVISION},         // SI_WIDGET_SHARED_DEPOT_PROVISION_R
+{   WIDGETS_END},
+};
 
+class SelectSharedInfrastructureWindow : public Window
+{
+	/* check for variable recording */
+	uint32 new_value;
+	uint32 old_value;
+	uint32 new_value2;
+	uint32 old_value2;
+
+	/**
+	 * Shared infrastructure player settings
+	 * Widgets section. Keep them in the same order in the widget array
+	 */
+	enum SharedInfrastructureWindowWidgets {
+		SI_WIDGET_CLOSEBOX = 0,
+		SI_WIDGET_CAPTION,	
+		SI_WIDGET_SELECT_SHARING_TRAIN,
+		SI_WIDGET_SELECT_SHARING_AIR,
+		SI_WIDGET_SELECT_SHARING_ROAD,
+		SI_WIDGET_SELECT_SHARING_SHIP,
+		SI_WIDGET_SELECT_SHARING_GENERAL,
+		SI_WIDGET_CANCEL,
+		SI_WIDGET_ACCEPT,
+		SI_WIDGET_TRAIN,
+		SI_WIDGET_PLANE,
+		SI_WIDGET_ROAD,
+		SI_WIDGET_SHIP,
+		SI_WIDGET_GENERAL,
+		SI_WIDGET_SHARED_RAILWAY_TRACKS,
+		SI_WIDGET_SHARED_RAILWAY_STATIONS,
+		SI_WIDGET_SHARED_RAILWAY_DEPOTS,
+		SI_WIDGET_SHARED_AIRPORTS,
+		SI_WIDGET_SHARED_ROAD_DEPOTS,
+		SI_WIDGET_SHARED_ROAD_STOPS,
+		SI_WIDGET_SHARED_WATER_DEPOTS,
+		SI_WIDGET_SHARED_HARBOURS,
+		SI_WIDGET_SHARED_TONTILE_COST_L,
+		SI_WIDGET_SHARED_TONTILE_COST,
+		SI_WIDGET_SHARED_TONTILE_COST_R,
+		SI_WIDGET_SHARED_ROAD_STOPS_FEE_L,
+		SI_WIDGET_SHARED_ROAD_STOPS_FEE,
+		SI_WIDGET_SHARED_ROAD_STOPS_FEE_R,
+		SI_WIDGET_SHARED_HARBOURS_FEE_L,
+		SI_WIDGET_SHARED_HARBOURS_FEE,
+		SI_WIDGET_SHARED_HARBOURS_FEE_R,
+		SI_WIDGET_SHARED_LANDING_FEE_L,
+		SI_WIDGET_SHARED_LANDING_FEE,
+		SI_WIDGET_SHARED_LANDING_FEE_R,
+		SI_WIDGET_SHARED_DEPOT_PROVISION_L,
+		SI_WIDGET_SHARED_DEPOT_PROVISION,
+		SI_WIDGET_SHARED_DEPOT_PROVISION_R,
+	};
+
+	enum {
+		SI_SETTING_DEFAULT,
+		SI_SETTING_VELOCITY,
+		SI_SETTING_CURRENCY
+	};
+
+	/**
+	 * Draw dynamic a label to the left of the button and a value in the button
+	 *
+	 * @param widget_index   index of this widget in the window
+	 * @param val            the value which will be draw
+	 * @param is_bool_widget is it a bool button
+	 * @param special        value is special (currency, velocity)
+	 */
+	void DrawSharedinfrastructureLabel(byte widget_index, uint16 val, bool is_bool_widget, byte special)
+	{
+		StringID str;
+
+		if (is_bool_widget) {
+			/* if it a bool button write yes or no */
+			str = (val != 0) ? STR_FACE_YES : STR_FACE_NO;
+		} else {
+			/* else write the value */
+			SetDParam(0, val);
+			switch (special) {
+				case SI_SETTING_VELOCITY : str = STR_JUST_VELOCITY; break;
+				case SI_SETTING_CURRENCY : str = STR_JUST_CURRENCY; break;
+				default : str = STR_JUST_INT;
+			}
+		}
+
+		/* Draw the value/bool in white (0xC). If the button clicked adds 1px to x and y text coordinates (IsWindowWidgetLowered()). */
+		DrawStringCentered(this->widget[widget_index].left + (this->widget[widget_index].right - this->widget[widget_index].left) / 2 +
+			this->IsWidgetLowered(widget_index), this->widget[widget_index].top + 1 + this->IsWidgetLowered(widget_index), str, TC_WHITE);
+	}
+
+public:
+	SelectSharedInfrastructureWindow(const WindowDesc *desc, Window *parent) : Window(desc, parent->window_number)
+	{
+		this->parent = parent;
+		this->FindWindowPlacementAndResize(desc);
+		this->caption_color = this->window_number;
+
+		const Player *p = GetPlayer((PlayerID)this->window_number);
+		bool local = this->window_number == _local_player;
+		
+		this->new_value = 0;
+		this->old_value = 0;
+		this->new_value2 = 0;
+		this->old_value2 = 0;
+
+		/* Check if repositioning from default is required */
+		if (top != FIRST_GUI_CALL && left != FIRST_GUI_CALL) {
+			this->top = top;
+			this->left = left;
+		}
+		
+		if (local) {
+			_si_railway_tracks = p->shared_railway_tracks[1];
+			_si_railway_stations = p->shared_railway_stations[1];
+			_si_railway_depots = p->shared_railway_depots[1];
+			_si_tontile_cost = p->shared_tontile_cost[1];
+			_si_road_stops_fee = p->shared_road_stops_fee[1];
+			_si_harbours_fee = p->shared_harbours_fee[1];
+			_si_airports = p->shared_airports[1];
+			_si_landing_fee = p->shared_landing_fee[1];
+			_si_road_depots = p->shared_road_depots[1];
+			_si_road_stops = p->shared_road_stops[1];
+			_si_water_depots = p->shared_water_depots[1];
+			_si_harbours = p->shared_harbours[1];
+			_si_provision = p->shared_provision[1];
+		}	
+	}
+
+	virtual void OnPaint()
+	{
+		const Player *p = GetPlayer((PlayerID)this->window_number);
+		bool local = this->window_number == _local_player;
+
+		uint i;
+
+		/* hide and disabled widget for non-local players */
+		for (i = SI_WIDGET_SHARED_TONTILE_COST_L; i <= SI_WIDGET_SHARED_DEPOT_PROVISION_R; i++) {
+			this->SetWidgetDisabledState(i, !local);
+		}
+		this->SetWidgetHiddenState(SI_WIDGET_CANCEL, !local);
+		this->SetWidgetHiddenState(SI_WIDGET_ACCEPT, !local);
+			
+		/* disabled widget from general (patch) settings */
+		this->SetWidgetDisabledState(SI_WIDGET_SHARED_RAILWAY_TRACKS, !local || !_settings_game.sharing.shared_railway_tracks);
+		this->SetWidgetDisabledState(SI_WIDGET_SHARED_RAILWAY_STATIONS, !local || !_settings_game.sharing.shared_railway_stations);
+		this->SetWidgetDisabledState(SI_WIDGET_SHARED_RAILWAY_DEPOTS, !local || !_settings_game.sharing.shared_railway_depots);
+		this->SetWidgetDisabledState(SI_WIDGET_SHARED_AIRPORTS, !local || !_settings_game.sharing.shared_airports);
+		this->SetWidgetDisabledState(SI_WIDGET_SHARED_ROAD_DEPOTS, !local || !_settings_game.sharing.shared_road_depots);
+		this->SetWidgetDisabledState(SI_WIDGET_SHARED_ROAD_STOPS, !local || !_settings_game.sharing.shared_road_stops);
+		this->SetWidgetDisabledState(SI_WIDGET_SHARED_WATER_DEPOTS, !local || !_settings_game.sharing.shared_water_depots);
+		this->SetWidgetDisabledState(SI_WIDGET_SHARED_HARBOURS, !local || !_settings_game.sharing.shared_harbours);
+
+		this->DrawWidgets();
+
+		/* "shared tracks:" */
+		DrawString(26, 16, STR_CONFIG_PLAYER_SHARED_RAILWAY_TRACKS, TC_FROMSTRING);
+		DrawStringCentered(140, 16, p->shared_railway_tracks[0] ? STR_FACE_YES : STR_FACE_NO, TC_WHITE);
+
+		/* "shared stations:" */
+		DrawString(26, 28, STR_CONFIG_PLAYER_SHARED_RAILWAY_STATIONS, TC_FROMSTRING);
+		DrawStringCentered(140, 28, p->shared_railway_stations[0] ? STR_FACE_YES : STR_FACE_NO, TC_WHITE);
+
+		/* "shared rail depots:" */
+		DrawString(26, 40, STR_CONFIG_PLAYER_SHARED_RAILWAY_DEPOTS, TC_FROMSTRING);
+		DrawStringCentered(140, 40, p->shared_railway_depots[0] ? STR_FACE_YES : STR_FACE_NO, TC_WHITE);
+
+		/* "shared rail tontile:" */
+		DrawString(26, 52, STR_CONFIG_PLAYER_SHARED_TONTILE_COST, TC_FROMSTRING);
+		SetDParam(0, p->shared_tontile_cost[0]);
+		DrawStringCentered(140, 52, STR_JUST_CURRENCY, TC_WHITE);
+
+		/* "shared road stops fee:" */
+		DrawString(26, 118, STR_CONFIG_PLAYER_SHARED_ROAD_STOPS_FEE, TC_FROMSTRING);
+		SetDParam(0, p->shared_road_stops_fee[0]);
+		DrawStringCentered(140, 118, STR_JUST_CURRENCY, TC_WHITE);
+
+		/* "shared harbours fee:" */
+		DrawString(26, 157, STR_CONFIG_PLAYER_SHARED_HARBOURS_FEE, TC_FROMSTRING);
+		SetDParam(0, p->shared_harbours_fee[0]);
+		DrawStringCentered(140, 157, STR_JUST_CURRENCY, TC_WHITE);
+
+		/* "shared airports:" */
+		DrawString(26, 67, STR_CONFIG_PLAYER_SHARED_AIRPORTS, TC_FROMSTRING);
+		DrawStringCentered(140, 67, p->shared_airports[0] ? STR_FACE_YES : STR_FACE_NO, TC_WHITE);
+
+		/* "shared landing fee:" */
+		DrawString(26, 79, STR_CONFIG_PLAYER_SHARED_LANDING_FEE, TC_FROMSTRING);
+		SetDParam(0, p->shared_landing_fee[0]);
+		DrawStringCentered(140, 79, STR_JUST_CURRENCY, TC_WHITE);
+
+		/* "shared road depots:" */
+		DrawString(26, 94, STR_CONFIG_PLAYER_SHARED_ROAD_DEPOTS, TC_FROMSTRING);
+		DrawStringCentered(140, 94, p->shared_road_depots[0] ? STR_FACE_YES : STR_FACE_NO, TC_WHITE);
+
+		/* "shared road stops:" */
+		DrawString(26, 106, STR_CONFIG_PLAYER_SHARED_ROAD_STOPS, TC_FROMSTRING);
+		DrawStringCentered(140, 106, p->shared_road_stops[0] ? STR_FACE_YES : STR_FACE_NO, TC_WHITE);
+
+		/* "shared water depots:" */
+		DrawString(26, 133, STR_CONFIG_PLAYER_SHARED_WATER_DEPOTS, TC_FROMSTRING);
+		DrawStringCentered(140, 133, p->shared_water_depots[0] ? STR_FACE_YES : STR_FACE_NO, TC_WHITE);
+
+		/* "shared harbours:" */
+		DrawString(26, 145, STR_CONFIG_PLAYER_SHARED_HARBOURS, TC_FROMSTRING);
+		DrawStringCentered(140, 145, p->shared_harbours[0] ? STR_FACE_YES : STR_FACE_NO, TC_WHITE);
+
+		/* "shared depot provision:" */
+		DrawString(26, 172, STR_CONFIG_PLAYER_SHARED_DEPOT_PROVISION, TC_FROMSTRING);
+		SetDParam(0, p->shared_provision[0]);
+		DrawStringCentered(140, 172, STR_JUST_PERCENT, TC_WHITE);
+
+		/* "shared planned change:" */
+		if (_settings_game.sharing.shared_delay > 0) {
+			if (p->shared_change_months > 0) {
+				SetDParam(0, p->shared_change_months);
+				DrawString(26, 184, STR_CONFIG_PLAYER_SHARED_CHANGE_MONTHS, TC_FROMSTRING);
+			} else {
+				SetDParam(0, _settings_game.sharing.shared_delay);
+				DrawString(26, 184, STR_CONFIG_PLAYER_SHARED_NO_CHANGE, TC_FROMSTRING);
+			}
+		}
+
+		/**
+		 * Draw value
+		 * use variables for local change
+		 */
+
+		if (local) {
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_RAILWAY_TRACKS, _si_railway_tracks, true, SI_SETTING_DEFAULT );
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_RAILWAY_STATIONS, _si_railway_stations, true, SI_SETTING_DEFAULT );
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_RAILWAY_DEPOTS, _si_railway_depots, true, SI_SETTING_DEFAULT );
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_TONTILE_COST, _si_tontile_cost, false, SI_SETTING_CURRENCY );
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_ROAD_STOPS_FEE, _si_road_stops_fee, false, SI_SETTING_CURRENCY );
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_HARBOURS_FEE, _si_harbours_fee, false , SI_SETTING_CURRENCY);
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_AIRPORTS, _si_airports, true, SI_SETTING_DEFAULT );
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_LANDING_FEE, _si_landing_fee, false , SI_SETTING_CURRENCY);
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_ROAD_DEPOTS, _si_road_depots, true, SI_SETTING_DEFAULT );
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_ROAD_STOPS, _si_road_stops, true, SI_SETTING_DEFAULT );
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_WATER_DEPOTS, _si_water_depots, true, SI_SETTING_DEFAULT );
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_HARBOURS, _si_harbours, true, SI_SETTING_DEFAULT );
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_DEPOT_PROVISION, _si_provision, false, SI_SETTING_DEFAULT );
+		} else {
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_RAILWAY_TRACKS, p->shared_railway_tracks[1], true, SI_SETTING_DEFAULT );
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_RAILWAY_STATIONS, p->shared_railway_stations[1], true, SI_SETTING_DEFAULT );
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_RAILWAY_DEPOTS, p->shared_railway_depots[1], true, SI_SETTING_DEFAULT );
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_TONTILE_COST, p->shared_tontile_cost[1], false, SI_SETTING_CURRENCY );
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_ROAD_STOPS_FEE, p->shared_road_stops_fee[1], false, SI_SETTING_CURRENCY );
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_HARBOURS_FEE, p->shared_harbours_fee[1], false , SI_SETTING_CURRENCY);
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_AIRPORTS, p->shared_airports[1], true, SI_SETTING_DEFAULT );
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_LANDING_FEE, p->shared_landing_fee[1], false , SI_SETTING_CURRENCY);
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_ROAD_DEPOTS, p->shared_road_depots[1], true, SI_SETTING_DEFAULT );
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_ROAD_STOPS, p->shared_road_stops[1], true, SI_SETTING_DEFAULT );
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_WATER_DEPOTS, p->shared_water_depots[1], true, SI_SETTING_DEFAULT );
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_HARBOURS, p->shared_harbours[1], true, SI_SETTING_DEFAULT );
+			this->DrawSharedinfrastructureLabel(SI_WIDGET_SHARED_DEPOT_PROVISION, p->shared_provision[1], false, SI_SETTING_DEFAULT );
+		}
+	}
+
+	virtual void OnClick(Point pt, int widget)
+	{
+		const Player *p = GetPlayer((PlayerID)this->window_number);
+		switch (widget) {
+
+			/* Cancel button */
+			case SI_WIDGET_CANCEL:
+				delete this;
+				break;
+
+			/* OK button */
+			case SI_WIDGET_ACCEPT:
+				/**
+				 * record changed values
+				 * first pack boolean variables
+				 * and check for change before sending command
+				 */
+				new_value = (uint)_si_railway_tracks | (uint)_si_railway_stations << 1 | (uint)_si_railway_depots << 2
+					| (uint)_si_airports << 3 | (uint)_si_road_depots << 4 | (uint)_si_road_stops << 5
+					 | (uint)_si_water_depots << 6 | (uint)_si_harbours << 7;
+				old_value = (uint)p->shared_railway_tracks[1] | (uint)p->shared_railway_stations[1] << 1 | (uint)p->shared_railway_depots[1] << 2
+					 | (uint)p->shared_airports[1] << 3 | (uint)p->shared_road_depots[1] << 4 | (uint)p->shared_road_stops[1] << 5
+					 | (uint)p->shared_water_depots[1] << 6 | (uint)p->shared_harbours[1] << 7;
+
+				if (new_value != old_value) {
+					DoCommandP(0, new_value, 0, NULL, CMD_SET_SHARED_BOOL_VALUES);
+				}
+
+				/* pack other variables and check for change before sending command */
+				new_value = _si_tontile_cost | _si_road_stops_fee << 16 |  _si_harbours_fee << 24;
+				old_value = p->shared_tontile_cost[1] | p->shared_road_stops_fee[1] << 16 | p->shared_harbours_fee[1] << 24;
+
+				new_value2 = _si_landing_fee | _si_provision << 16;
+				old_value2 = p->shared_landing_fee[1] | p->shared_provision[1] << 16;
+
+				if (new_value != old_value || new_value2 != old_value2) {
+					DoCommandP(0, new_value, new_value2, NULL, CMD_SET_SHARED_INT_VALUES);
+				}
+
+				delete this;
+				break;
+
+			default:
+				if (widget >= SI_WIDGET_SHARED_RAILWAY_TRACKS && widget <= SI_WIDGET_SHARED_DEPOT_PROVISION_R) {
+						
+					if (widget < SI_WIDGET_SHARED_TONTILE_COST_L) { 
+						/* Bool buttons */
+						switch (widget - SI_WIDGET_SHARED_RAILWAY_TRACKS) {
+							default: NOT_REACHED();
+							case 0: 
+								_si_railway_tracks = !_si_railway_tracks;
+								/* close railway stations and depots if tracks are closed */
+								if (!_si_railway_tracks) {
+									_si_railway_stations = false;
+									_si_railway_depots = false;
+								}
+								break; 
+							case 1:
+								_si_railway_stations = !_si_railway_stations;
+								/* open tracks when opening railway stations */
+								if (_si_railway_stations) {
+									_si_railway_tracks = true;
+								}
+								break; 
+							case 2:
+								_si_railway_depots = !_si_railway_depots;
+								/* open tracks when opening railway depots */
+								if (_si_railway_depots) {
+									_si_railway_tracks = true;
+								}
+								break; 
+							case 3: _si_airports = !_si_airports; break; 
+							case 4: _si_road_depots = !_si_road_depots; break; 
+							case 5: _si_road_stops = !_si_road_stops; break; 
+							case 6: _si_water_depots = !_si_water_depots; break; 
+							case 7: _si_harbours = !_si_harbours; break; 
+						}
+					} else {
+						/** Value buttons
+						 * - get widget line
+						 * - get button click : 0 == left (_L), 1 == middle or 2 == right (_R)
+						 */
+						int line = (widget - SI_WIDGET_SHARED_TONTILE_COST_L) / 3;
+						bool add = (((widget - SI_WIDGET_SHARED_TONTILE_COST_L) % 3) != 0);
+						switch (line) {
+							default: NOT_REACHED();
+							/* "magic" step and max values based on those in settings.cpp */
+							case 0:
+								_si_tontile_cost += add ? 5 : -5;
+								if (_si_tontile_cost > 250) _si_tontile_cost = _si_tontile_cost > 255 ? 0 : 250;
+								break;
+							case 1:
+								_si_road_stops_fee += add ? 1 : -1;
+								if (_si_road_stops_fee > 50) _si_road_stops_fee = _si_road_stops_fee > 51 ? 0 : 100;
+								break;
+							case 2:
+								_si_harbours_fee += add ? 5 : -5;
+								if (_si_harbours_fee > 200) _si_harbours_fee = _si_harbours_fee > 205 ? 0 : 200;
+								break;
+							case 3:
+								_si_landing_fee += add ? 20 : -20;
+								if (_si_landing_fee > 1000) _si_landing_fee = _si_landing_fee > 1020 ? 0 : 1000;
+								break;
+							case 4:
+								_si_provision += add ? 5 : -5;
+								if (_si_provision > 100) _si_provision = _si_provision > 105 ? 0 : 100;
+								break;
+						}
+					}
+				}
+				this->SetDirty();
+				break;
+			}
+	}
+};
+
+static const WindowDesc _shared_infrastructure_desc = {
+	WDP_AUTO, WDP_AUTO, 270, 207, 270, 207,
+	WC_SHARED_INFRASTRUCTURE, WC_NONE,
+	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS, 
+	_shared_infrastructure_widgets, 
+};
+
+
+static void ShowPlayerSharedInfrastructure(Window *parent)
+{
+	if (!IsValidPlayer((PlayerID)parent->window_number)) return;
+
+	if (BringWindowToFrontById(WC_SHARED_INFRASTRUCTURE, parent->window_number)) return;
+	new SelectSharedInfrastructureWindow(&_shared_infrastructure_desc, parent); 
+}
+
 /* Names of the widgets. Keep them in the same order as in the widget array */
 enum PlayerCompanyWindowWidgets {
 	PCW_WIDGET_CLOSEBOX = 0,
@@ -1051,6 +1481,7 @@
 	PCW_WIDGET_BUY_SHARE,
 	PCW_WIDGET_SELL_SHARE,
 	PCW_WIDGET_COMPANY_PASSWORD,
+	PCW_WIDGET_COMPANY_SHARING,
 };
 
 static const Widget _player_company_widgets[] = {
@@ -1066,6 +1497,7 @@
 { WWT_PUSHTXTBTN,   RESIZE_NONE,    14,     0,   179,   158,   169, STR_7077_BUY_25_SHARE_IN_COMPANY,  STR_7079_BUY_25_SHARE_IN_THIS_COMPANY},
 { WWT_PUSHTXTBTN,   RESIZE_NONE,    14,   180,   359,   158,   169, STR_7078_SELL_25_SHARE_IN_COMPANY, STR_707A_SELL_25_SHARE_IN_THIS_COMPANY},
 { WWT_PUSHTXTBTN,   RESIZE_NONE,    14,   266,   355,   138,   149, STR_COMPANY_PASSWORD,              STR_COMPANY_PASSWORD_TOOLTIP},
+{    WWT_TEXTBTN,   RESIZE_NONE,    14,   266,   355,    46,    57, STR_COMPANY_SHARING,               STR_SET_COMPANY_SHARING},
 {   WIDGETS_END},
 };
 
@@ -1187,6 +1619,7 @@
 		this->SetWidgetHiddenState(PCW_WIDGET_BUY_SHARE,        local);
 		this->SetWidgetHiddenState(PCW_WIDGET_SELL_SHARE,       local);
 		this->SetWidgetHiddenState(PCW_WIDGET_COMPANY_PASSWORD, !local || !_networking);
+		this->SetWidgetHiddenState(PCW_WIDGET_COMPANY_SHARING, !_settings_game.sharing.shared_player_level);
 
 		if (!local) {
 			if (_settings_game.economy.allow_shares) { // Shares are allowed
@@ -1293,6 +1726,10 @@
 			case PCW_WIDGET_SELL_SHARE:
 				DoCommandP(0, this->window_number, 0, NULL, CMD_SELL_SHARE_IN_COMPANY | CMD_MSG(STR_707C_CAN_T_SELL_25_SHARE_IN));
 				break;
+					
+			case PCW_WIDGET_COMPANY_SHARING:
+				ShowPlayerSharedInfrastructure(this);
+				break;
 
 #ifdef ENABLE_NETWORK
 			case PCW_WIDGET_COMPANY_PASSWORD:
Index: src/aircraft_cmd.cpp
===================================================================
--- src/aircraft_cmd.cpp	(revision 13552)
+++ src/aircraft_cmd.cpp	(working copy)
@@ -37,6 +37,7 @@
 #include "settings_type.h"
 #include "order_func.h"
 #include "effectvehicle_func.h"
+#include "sharedinfrastructure.h"
 
 #include "table/strings.h"
 #include "table/sprites.h"
@@ -117,7 +118,7 @@
 	TileIndex vtile = TileVirtXY(v->x_pos, v->y_pos);
 
 	FOR_ALL_STATIONS(st) {
-		if (st->owner != v->owner || !(st->facilities & FACIL_AIRPORT)) continue;
+		if (((st->owner != v->owner)&&(!SharedAirports(st->xy,v->owner))) || !(st->facilities & FACIL_AIRPORT)) continue;
 
 		const AirportFTAClass *afc = st->Airport();
 		if (afc->nof_depots == 0 || (
@@ -149,7 +150,7 @@
 
 	FOR_VEHICLE_ORDERS(v, order) {
 		const Station *st = GetStation(order->station);
-		if (st->owner == v->owner && st->facilities & FACIL_AIRPORT) {
+		if (((st->owner == v->owner)&&(!SharedAirports(st->xy,v->owner))) && st->facilities & FACIL_AIRPORT) {
 			/* If an airport doesn't have a hangar, skip it */
 			if (st->Airport()->nof_depots != 0)
 				return true;
@@ -274,7 +275,7 @@
 	/* to just query the cost, it is not neccessary to have a valid tile (automation/AI) */
 	if (flags & DC_QUERY_COST) return value;
 
-	if (!IsHangarTile(tile) || !IsTileOwner(tile, _current_player)) return CMD_ERROR;
+	if (!IsHangarTile(tile) || (!IsTileOwner(tile, _current_player) && !SharedAirports(tile, _current_player))) return CMD_ERROR;
 
 	/* Prevent building aircraft types at places which can't handle them */
 	if (!CanAircraftUseStation(p1, tile)) return CMD_ERROR;
@@ -454,6 +455,8 @@
 		GetPlayer(_current_player)->num_engines[p1]++;
 	}
 
+	SharedDepotProvision(value, GetTileOwner(tile), flags);
+
 	return value;
 }
 
@@ -1685,7 +1688,7 @@
 	/* runway busy or not allowed to use this airstation, circle */
 	if (apc->flags & (v->subtype == AIR_HELICOPTER ? AirportFTAClass::HELICOPTERS : AirportFTAClass::AIRPLANES) &&
 			st->airport_tile != 0 &&
-			(st->owner == OWNER_NONE || st->owner == v->owner)) {
+			(st->owner == OWNER_NONE || st->owner == v->owner || SharedAirports(st->xy, v->owner))) {
 		// {32,FLYING,NOTHING_block,37}, {32,LANDING,N,33}, {32,HELILANDING,N,41},
 		// if it is an airplane, look for LANDING, for helicopter HELILANDING
 		// it is possible to choose from multiple landing runways, so loop until a free one is found
@@ -1700,6 +1703,10 @@
 				uint16 tsubspeed = v->subspeed;
 				if (!AirportHasBlock(v, current, apc)) {
 					v->u.air.state = landingtype; // LANDING / HELILANDING
+
+					/* check landing fee for shared airports */
+					if (st->owner != v->owner) SharedStationFee(st->owner, v->index);
+
 					/* it's a bit dirty, but I need to set position to next position, otherwise
 					 * if there are multiple runways, plane won't know which one it took (because
 					 * they all have heading LANDING). And also occupy that block! */
Index: src/rail_map.h
===================================================================
--- src/rail_map.h	(revision 13552)
+++ src/rail_map.h	(working copy)
@@ -31,6 +31,8 @@
  */
 static inline RailTileType GetRailTileType(TileIndex t)
 {
+  	if(!IsTileType(t, MP_RAILWAY))
+		printf("tiletype: %i\n",GetTileType(t));
 	assert(IsTileType(t, MP_RAILWAY));
 	return (RailTileType)GB(_m[t].m5, 6, 2);
 }
Index: projects/openttd_vs80.vcproj
===================================================================
--- projects/openttd_vs80.vcproj	(revision 13552)
+++ projects/openttd_vs80.vcproj	(working copy)
@@ -712,6 +712,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\sharedinfrastructure.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\signal.cpp"
 				>
 			</File>
@@ -1424,6 +1428,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\sharedinfrastructure.h"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\signal_func.h"
 				>
 			</File>
Index: projects/openttd_vs90.vcproj
===================================================================
--- projects/openttd_vs90.vcproj	(revision 13552)
+++ projects/openttd_vs90.vcproj	(working copy)
@@ -709,6 +709,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\sharedinfrastructure.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\signal.cpp"
 				>
 			</File>
@@ -1421,6 +1425,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\..\src\sharedinfrastructure.h"
+				>
+			</File>
+			<File
 				RelativePath=".\..\src\signal_func.h"
 				>
 			</File>
Index: source.list
===================================================================
--- source.list	(revision 13552)
+++ source.list	(working copy)
@@ -71,6 +71,7 @@
 	sdl.cpp
 #end
 settings.cpp
+sharedinfrastructure.cpp
 signal.cpp
 signs.cpp
 sound.cpp
@@ -281,6 +282,7 @@
 settings_internal.h
 settings_type.h
 ship.h
+sharedinfrastructure.h
 signal_func.h
 signal_type.h
 signs_base.h
