Index: binaries/data/mods/public/simulation/components/BuildingAI.js
===================================================================
--- binaries/data/mods/public/simulation/components/BuildingAI.js	(revision 18140)
+++ binaries/data/mods/public/simulation/components/BuildingAI.js	(working copy)
@@ -32,6 +32,8 @@
 
 BuildingAI.prototype.OnGarrisonedUnitsChanged = function(msg)
 {
+	if(msg.visible)
+		return;
 	let classes = this.template.GarrisonArrowClasses;
 
 	for (let ent of msg.added)
Index: binaries/data/mods/public/simulation/components/GarrisonHolder.js
===================================================================
--- binaries/data/mods/public/simulation/components/GarrisonHolder.js	(revision 18140)
+++ binaries/data/mods/public/simulation/components/GarrisonHolder.js	(working copy)
@@ -1,3 +1,6 @@
+/**
+ * @class Defines an entity's ability to garrison units.
+ */
 function GarrisonHolder() {}
 
 GarrisonHolder.prototype.Schema =
@@ -45,6 +48,14 @@
 						"<element name='Z'>" +
 							"<data type='decimal'/>" +
 						"</element>" +
+						"<optional>" +
+							"<element name='VisibleGarrisonAllowedClasses'>" +
+								"<attribute name='datatype'>" +
+									"<value>tokens</value>" +
+								"</attribute>" +
+								"<text/>" +
+							"</element>" +
+						"</optional>" +
 					"</interleave>" +
 				"</element>" +
 			"</zeroOrMore>" +
@@ -72,7 +83,7 @@
 			o.x = +offset.X;
 			o.y = +offset.Y;
 			o.z = +offset.Z;
-			this.visibleGarrisonPoints.push({"offset":o, "entity": null});
+			this.visibleGarrisonPoints.push({ "offset":o, "entity": null, "allowedClass": offset.VisibleGarrisonAllowedClasses });
 		}
 	}
 };
@@ -100,7 +111,6 @@
 	return IsOwnedByPlayer(player, ent);
 };
 
-
 /**
  * Return the list of entities garrisoned inside
  */
@@ -204,6 +214,19 @@
 };
 
 /**
+ * Returns true if the unit is allowed be visible on that garrison point, false otherwise.
+ */
+GarrisonHolder.prototype.AllowedToVisibleGarrisoning = function(visibleGarrisonPoint, entity)
+{
+	let allowedClassesList = visibleGarrisonPoint.allowedClass._string; 
+	//If classlist is empty, everybody can garrison.
+	if (!allowedClassesList) 
+		return true; 
+	
+	return MatchesClassList(Engine.QueryInterface(entity, IID_Identity).GetClassesList(), allowedClassesList);
+};
+
+/**
  * Garrison a unit inside.
  * Returns true if successful, false if not
  * The timer for AutoHeal is started here
@@ -229,21 +252,30 @@
 			break;
 		}
 	}
-
 	if (visibleGarrisonPoint)
-	{
-		visibleGarrisonPoint.entity = entity;
-		cmpPosition.SetTurretParent(this.entity, visibleGarrisonPoint.offset);
-		let cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI);
-		if (cmpUnitAI)
-			cmpUnitAI.SetTurretStance();
+	{    
+		if (this.AllowedToVisibleGarrisoning(visibleGarrisonPoint, entity))
+		{
+			visibleGarrisonPoint.entity = entity;
+			cmpPosition.SetTurretParent(this.entity, visibleGarrisonPoint.offset);
+			let cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI);
+			if (cmpUnitAI)
+				cmpUnitAI.SetTurretStance();
+		}
+		else
+			cmpPosition.MoveOutOfWorld();
 	}
 	else
 		cmpPosition.MoveOutOfWorld();
-
+	// Should only be called after the garrison has been performed else the visible Garrison Points are not updated yet.
+	Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added": [entity], "visible": this.IsVisiblyGarrisonned(entity), "removed": [] });
 	return true;
 };
 
+/**
+ * Garrison units inside the entity
+ * @return true if successful, false if not
+ */
 GarrisonHolder.prototype.PerformGarrison = function(entity)
 {
 	if (!this.HasEnoughHealth())
@@ -278,8 +310,6 @@
 	if (cmpAura && cmpAura.HasGarrisonAura())
 		cmpAura.ApplyGarrisonBonus(this.entity);
 
-	Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [entity], "removed": [] });
-
 	var cmpUnitAI = Engine.QueryInterface(entity, IID_UnitAI);
 	if (cmpUnitAI && cmpUnitAI.IsUnderAlert())
 		Engine.PostMessage(cmpUnitAI.GetAlertRaiser(), MT_UnitGarrisonedAfterAlert, {"holder": this.entity, "unit": entity});
@@ -326,7 +356,8 @@
 
 	var cmpNewPosition = Engine.QueryInterface(entity, IID_Position);
 	this.entities.splice(entityIndex, 1);
-
+	// Should only be called before the ejection has been performed else the visible Garrison Points will be empty.
+	Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added": [], "visible": this.IsVisiblyGarrisonned(entity), "removed": [entity] });
 	for (var vgp of this.visibleGarrisonPoints)
 	{
 		if (vgp.entity != entity)
@@ -356,7 +387,6 @@
 	cmpNewPosition.SetHeightOffset(0);
 	// TODO: what direction should they face in?
 
-	Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed": [entity] });
 
 	return true;
 };
@@ -620,7 +650,7 @@
 		if (cmpHealth && cmpHealth.GetHitpoints() == 0)
 		{
 			this.entities.splice(entityIndex, 1);
-			Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed": [msg.entity] });
+			Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added": [], "visible": this.IsVisiblyGarrisonned(entity), "removed": [msg.entity] });
 			this.UpdateGarrisonFlag();
 
 			for (var pt of this.visibleGarrisonPoints)
@@ -634,6 +664,8 @@
 
 /**
  * Update list of garrisoned entities if one gets renamed (e.g. by promotion)
+ * vgpEntity is only defined in some peculiar case where we want to reuse the same visibleGarrisonPoint,
+ * in case of promotion for example, and thus should always be allowed. 
  */
 GarrisonHolder.prototype.OnGlobalEntityRenamed = function(msg)
 {
@@ -670,7 +702,6 @@
 	}
 };
 
-
 /**
  * Eject all foreign garrisoned entities which are no more allied
  */
@@ -712,11 +743,24 @@
 	}
 
 	if (killedEntities.length > 0)
-		Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added" : [], "removed" : killedEntities });
+		Engine.PostMessage(this.entity, MT_GarrisonedUnitsChanged, { "added": [], "visible": this.IsVisiblyGarrisonned(entity), "removed" : killedEntities });
 	this.UpdateGarrisonFlag();
 };
 
 /**
+ * Gives insight about the unit type of garrisoning.
+ * @return{bool} returns true if the unit is visible on the structure
+ * @param {int} the entity's id
+ */
+GarrisonHolder.prototype.IsVisiblyGarrisonned = function(entity)
+{
+	for(let point of this.visibleGarrisonPoints)
+		if (point.entity === entity)
+			return true
+	return false;
+};
+
+/**
  * Checks if an entity is ejectable on destroy if possible
  */
 GarrisonHolder.prototype.IsEjectable = function(entity)
