diff --git a/dist/game/data/scripts/handlers/targethandlers/AreaFriendly.java b/dist/game/data/scripts/handlers/targethandlers/AreaFriendly.java
index bf0005dfb61a306b02773d0a1ef71562d3371ed2..9303e20f2e58826436a08e92acecc3099e294724 100644
--- a/dist/game/data/scripts/handlers/targethandlers/AreaFriendly.java
+++ b/dist/game/data/scripts/handlers/targethandlers/AreaFriendly.java
@@ -18,10 +18,9 @@
  */
 package handlers.targethandlers;
 
-import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.LinkedList;
 import java.util.List;
 
 import com.l2jserver.gameserver.GeoData;
@@ -37,14 +36,15 @@ import com.l2jserver.gameserver.network.SystemMessageId;
 
 /**
  * Area Friendly target handler implementation.
- * @author Adry_85
+ * @author Adry_85, Zoey76
  */
 public class AreaFriendly implements ITargetTypeHandler
 {
+	private static final CharComparator CHAR_COMPARATOR = new CharComparator();
+	
 	@Override
 	public L2Object[] getTargetList(Skill skill, L2Character activeChar, boolean onlyFirst, L2Character target)
 	{
-		List<L2Character> targetList = new ArrayList<>();
 		L2PcInstance player = activeChar.getActingPlayer();
 		
 		if (!checkTarget(player, target) && (skill.getCastRange() >= 0))
@@ -68,30 +68,31 @@ public class AreaFriendly implements ITargetTypeHandler
 				player
 			};
 		}
-		targetList.add(target); // Add target to target list
 		
+		final List<L2Character> targetList = new LinkedList<>();
 		if (target != null)
 		{
-			int maxTargets = skill.getAffectLimit();
-			final Collection<L2Character> objs = target.getKnownList().getKnownCharactersInRadius(skill.getAffectRange());
-			
-			// TODO: Chain Heal - The recovery amount decreases starting from the most injured person.
-			Collections.sort(targetList, new CharComparator());
+			// Add target to target list.
+			targetList.add(target);
 			
-			for (L2Character obj : objs)
+			final int maxTargets = skill.getAffectLimit();
+			for (L2Character obj : target.getKnownList().getKnownCharactersInRadius(skill.getAffectRange()))
 			{
-				if (!checkTarget(player, obj) || (obj == activeChar))
+				if ((maxTargets > 0) && (targetList.size() >= maxTargets))
 				{
-					continue;
+					break;
 				}
 				
-				if ((maxTargets > 0) && (targetList.size() >= maxTargets))
+				if (!checkTarget(player, obj) || (obj == activeChar))
 				{
-					break;
+					continue;
 				}
 				
 				targetList.add(obj);
 			}
+			
+			// Sort creatures, the most injured first.
+			Collections.sort(targetList, CHAR_COMPARATOR);
 		}
 		
 		if (targetList.isEmpty())
@@ -108,7 +109,13 @@ public class AreaFriendly implements ITargetTypeHandler
 			return false;
 		}
 		
-		if ((target == null) || target.isAlikeDead() || target.isDoor() || !activeChar.isOnSameSiegeSideWith(target) || (target instanceof L2SiegeFlagInstance) || target.isMonster())
+		if ((target == null) || target.isAlikeDead() || target.isDoor() || (target instanceof L2SiegeFlagInstance) || target.isMonster())
+		{
+			return false;
+		}
+		
+		// GMs and hidden creatures.
+		if (target.isInvisible())
 		{
 			return false;
 		}
@@ -137,6 +144,12 @@ public class AreaFriendly implements ITargetTypeHandler
 				return true;
 			}
 			
+			// Only siege allies.
+			if (activeChar.isInSiege() && !activeChar.isOnSameSiegeSideWith(targetPlayer))
+			{
+				return false;
+			}
+			
 			if (target.isInsideZone(ZoneId.PVP))
 			{
 				return false;
@@ -155,7 +168,7 @@ public class AreaFriendly implements ITargetTypeHandler
 		return true;
 	}
 	
-	public class CharComparator implements Comparator<L2Character>
+	public static class CharComparator implements Comparator<L2Character>
 	{
 		@Override
 		public int compare(L2Character char1, L2Character char2)