Add debug logging for the new If Nest sections.
Add debug logging for the new If Nest sections.

--- a/ARMapRenderer.cs
+++ b/ARMapRenderer.cs
@@ -39,6 +39,7 @@
 		#region Fields
 		private Dictionary<Guid, LineRenderer> vesselLineRenderers;
 		private Dictionary<Guid, bool> vesselFrameCache;
+		private bool dumpBool;
 		#endregion
 
 		#region Properties
@@ -51,21 +52,27 @@
 					this.vesselLineRenderers = new Dictionary<Guid, LineRenderer>();
 				}
 
-				if (!this.vesselLineRenderers.ContainsKey(idx))
+				LineRenderer lr;
+
+				if (this.vesselLineRenderers.TryGetValue(idx, out lr))
+				{
+					return lr;
+				}
+				else
 				{
 					GameObject obj = new GameObject();
 					obj.layer = 31;
 
-					LineRenderer lr = obj.AddComponent<LineRenderer>();
-
-					lr.SetColors(Color.green, Color.green);
+					lr = obj.AddComponent<LineRenderer>();
+
+					// lr.SetColors(Color.green, Color.green);
 					lr.material = MapView.OrbitLinesMaterial;
-					lr.SetVertexCount(2);
+					// lr.SetVertexCount(2);
 
 					this.vesselLineRenderers[idx] = lr;
-				}
-
-				return this.vesselLineRenderers[idx];
+
+					return lr;
+				}
 			}
 		}
 		#endregion
@@ -119,6 +126,12 @@
 							continue;
 						}
 
+						if (this.vesselFrameCache.TryGetValue(vessel.id, out dumpBool))
+						{
+							log.AppendFormat("Skipping vessel {0} because it's already been processed this frame.");
+							continue;
+						}
+
 						log.AppendFormat("Checking vessel {0}.\n", vessel.vesselName);
 
 						switch (vessel.vesselType)
@@ -163,71 +176,90 @@
 
 		private void SetRelayVertices(IAntennaRelay relay)
 		{
-			if (relay == null)
-			{
-				return;
-			}
+			Color lastColor = default(Color);
+			Color thisColor;
 
 			LineRenderer renderer = this[relay.vessel.id];
-
-			Vector3d start;
-			Vector3d end;
-
-			renderer.enabled = true;
-
-			if (!relay.CanTransmit())
-			{
-				renderer.SetColors(Color.red, Color.red);
+			Vector3d start = ScaledSpace.LocalToScaledSpace(relay.vessel.GetWorldPos3D());
+
+			float lineWidth;
+			float d = Screen.height / 2f + 0.01f;
+
+			if (MapView.Draw3DLines)
+			{
+				lineWidth = 0.005859375f * MapView.MapCamera.Distance;
 			}
 			else
 			{
-				if (relay.transmitDistance < relay.nominalTransmitDistance)
-				{
-					renderer.SetColors(Color.green, Color.green);
+				lineWidth = 2f;
+
+				start = MapView.MapCamera.camera.WorldToScreenPoint(start);
+
+				start.z = start.z >= 0f ? d : -d;
+			}
+
+			renderer.SetWidth(lineWidth, lineWidth);
+
+			renderer.SetPosition(0, start);
+
+			int idx = 0;
+
+			while (relay != null)
+			{
+				Vector3d nextPoint;
+
+				renderer.enabled = true;
+
+				if (!relay.CanTransmit())
+				{
+					thisColor = Color.red;
 				}
 				else
 				{
-					renderer.SetColors(Color.yellow, Color.yellow);
-				}
-			}
-
-			start = ScaledSpace.LocalToScaledSpace(relay.vessel.GetWorldPos3D());
-
-			if (relay.KerbinDirect)
-			{
-				end = ScaledSpace.LocalToScaledSpace(AntennaRelay.Kerbin.position);
-			}
-			else
-			{
-				if (relay.targetRelay == null)
-				{
-					return;
-				}
-				end = ScaledSpace.LocalToScaledSpace(relay.targetRelay.vessel.GetWorldPos3D());
-			}
-
-			float lineWidth;
-
-			if (MapView.Draw3DLines)
-			{
-				lineWidth = 0.005859375f * MapView.MapCamera.Distance;
-			}
-			else
-			{
-				lineWidth = 2f;
-
-				start = MapView.MapCamera.camera.WorldToScreenPoint(start);
-				end = MapView.MapCamera.camera.WorldToScreenPoint(end);
-
-				float d = Screen.height / 2f + 0.01f;
-				start.z = start.z >= 0f ? d : -d;
-				end.z = end.z >= 0f ? d : -d;
-			}
-
-			renderer.SetWidth(lineWidth, lineWidth);
-
-			renderer.SetPosition(0, start);
-			renderer.SetPosition(1, end);
+					if (relay.transmitDistance < relay.nominalTransmitDistance)
+					{
+						thisColor = Color.green;
+					}
+					else
+					{
+						thisColor = Color.yellow;
+					}
+				}
+
+				if (lastColor != default(Color) && thisColor != lastColor)
+				{
+					break;
+				}
+
+				lastColor = thisColor;
+				renderer.SetColors(thisColor, thisColor);
+
+				this.vesselFrameCache[relay.vessel.id] = true;
+
+				if (relay.KerbinDirect)
+				{
+					nextPoint = ScaledSpace.LocalToScaledSpace(AntennaRelay.Kerbin.position);
+					relay = null;
+				}
+				else
+				{
+					if (relay.targetRelay == null)
+					{
+						return;
+					}
+
+					nextPoint = ScaledSpace.LocalToScaledSpace(relay.targetRelay.vessel.GetWorldPos3D());
+					relay = relay.targetRelay;
+				}
+
+				if (!MapView.Draw3DLines)
+				{
+					nextPoint = MapView.MapCamera.camera.WorldToScreenPoint(nextPoint);
+					nextPoint.z = nextPoint.z >= 0f ? d : -d;
+				}
+
+				renderer.SetPosition(++idx, nextPoint);
+			}
 		}
 
 		public void Cleanup()

--- a/AntennaRelay.cs
+++ b/AntennaRelay.cs
@@ -38,6 +38,9 @@
 	/// </summary>
 	public class AntennaRelay
 	{
+		private static readonly System.Diagnostics.Stopwatch searchTimer = new System.Diagnostics.Stopwatch();
+		private const long millisecondsBetweenSearches = 125L;
+
 		// We don't have a Bard, so we'll hide Kerbin here.
 		private static CelestialBody _Kerbin;
 
@@ -57,14 +60,13 @@
 			}
 		}
 
+		private long lastSearch;
+
 		private bool canTransmit;
 
 		private IAntennaRelay nearestRelay;
 		private IAntennaRelay bestOccludedRelay;
 
-		private System.Diagnostics.Stopwatch searchTimer;
-		private long millisecondsBetweenSearches;
-
 		/// <summary>
 		/// The <see cref="AntennaRange.ModuleLimitedDataTransmitter"/> reference underlying this AntennaRelay, as an
 		/// <see cref="AntennaRange.IAntennaRelay"/>
@@ -167,14 +169,23 @@
 		/// <returns>The nearest relay or null, if no relays in range.</returns>
 		private void FindNearestRelay()
 		{
-			if (!this.searchTimer.IsRunning || this.searchTimer.ElapsedMilliseconds > this.millisecondsBetweenSearches)
-			{
-				this.searchTimer.Reset();
-			}
-			else
+			if (!searchTimer.IsRunning)
+			{
+				searchTimer.Start();
+			}
+
+			long searchTime = searchTimer.ElapsedMilliseconds;
+			long timeSinceLast = searchTime - this.lastSearch;
+
+			if (timeSinceLast < Math.Max(millisecondsBetweenSearches, UnityEngine.Time.smoothDeltaTime))
 			{
 				return;
 			}
+
+			Tools.PostDebugMessage("{0}: Updating at {1}ms, {2}ms since last search.",
+				this.ToString(), searchTime, timeSinceLast);
+
+			this.lastSearch = searchTime;
 
 			// Skip vessels that have already been checked for a nearest relay this pass.
 			if (RelayDatabase.Instance.CheckedVesselsTable.ContainsKey(this.vessel.id))
@@ -377,26 +388,63 @@
 
 					this.canTransmit = false;
 
-					// If the best occluded relay is closer than Kerbin, target it.
+					// If the best occluded relay is closer than Kerbin, check it against the nearest relay.
+					// Since bestOccludedSqrDistance is infinity if there are no occluded relays, this is safe
 					if (bestOccludedSqrDistance < kerbinSqrDistance)
 					{
-						log.AppendFormat("\n\t\tPicking occluded relay {0} as target ({1} < {2}).",
-							this.bestOccludedRelay == null ? "null" : this.bestOccludedRelay.ToString(),
-							bestOccludedSqrDistance, kerbinSqrDistance);
-
+						log.AppendFormat("\n\tBest occluded relay is closer than Kerbin ({0} < {1})",
+							bestOccludedRelay, kerbinSqrDistance);
+						
 						this.KerbinDirect = false;
-						this.targetRelay = this.bestOccludedRelay;
-						this.firstOccludingBody = bodyOccludingBestOccludedRelay;
-					}
-					// Otherwise, target Kerbin and report the first body blocking it.
+
+						// If the nearest relay is closer than the best occluded relay, pick it.
+						// Since nearestRelaySqrDistane is infinity if there are no nearby relays, this is safe.
+						if (nearestRelaySqrDistance < bestOccludedSqrDistance)
+						{
+							log.AppendFormat("\n\t\t...but the nearest relay is closer ({0} < {1}), so picking it.",
+								nearestRelaySqrDistance, bestOccludedSqrDistance);
+							
+							this.targetRelay = nearestRelay;
+							this.firstOccludingBody = null;
+						}
+						// Otherwise, target the best occluded relay.
+						else
+						{
+							log.AppendFormat("\n\t\t...and closer than the nearest relay ({0} >= {1}), so picking it.",
+								nearestRelaySqrDistance, bestOccludedSqrDistance);
+							
+							this.targetRelay = bestOccludedRelay;
+							this.firstOccludingBody = bodyOccludingBestOccludedRelay;
+						}
+					}
+					// Otherwise, check Kerbin against the nearest relay.
+					// Since we have LOS, blank the first occluding body.
 					else
 					{
-						log.AppendFormat("\n\t\tPicking Kerbin as target ({0} >= {1}).",
-							bestOccludedSqrDistance, kerbinSqrDistance);
-
-						this.KerbinDirect = true;
-						this.targetRelay = null;
-						this.firstOccludingBody = bodyOccludingKerbin;
+						log.AppendFormat("\n\tKerbin is closer than the best occluded relay ({0} >= {1})",
+							bestOccludedRelay, kerbinSqrDistance);
+						
+						this.firstOccludingBody = null;
+
+						// If the nearest relay is closer than Kerbin, pick it.
+						// Since nearestRelaySqrDistane is infinity if there are no nearby relays, this is safe.
+						if (nearestRelaySqrDistance < kerbinSqrDistance)
+						{
+							log.AppendFormat("\n\t\t...but the nearest relay is closer ({0} < {1}), so picking it.",
+								nearestRelaySqrDistance, kerbinSqrDistance);
+							
+							this.KerbinDirect = false;
+							this.targetRelay = nearestRelay;
+						}
+						// Otherwise, pick Kerbin.
+						else
+						{
+							log.AppendFormat("\n\t\t...and closer than the nearest relay ({0} >= {1}), so picking it.",
+								nearestRelaySqrDistance, kerbinSqrDistance);
+							
+							this.KerbinDirect = true;
+							this.targetRelay = null;
+						}
 					}
 				}
 			}
@@ -461,28 +509,45 @@
 
 						this.canTransmit = false;
 
-						// If the best occluded relay is closer than Kerbin, use it.
-						// Since bestOccludedSqrDistance is infinity if there are no occluded relays,
-						// this is safe
+						// If the best occluded relay is closer than Kerbin, check it against the nearest relay.
+						// Since bestOccludedSqrDistance is infinity if there are no occluded relays, this is safe
 						if (bestOccludedSqrDistance < kerbinSqrDistance)
 						{
-							log.AppendFormat("\n\t\tPicking occluded relay {0} as target ({1} < {2}).",
-								this.bestOccludedRelay == null ? "null" : this.bestOccludedRelay.ToString(),
-									bestOccludedSqrDistance, kerbinSqrDistance);
-
 							this.KerbinDirect = false;
-							this.targetRelay = bestOccludedRelay;
-							this.firstOccludingBody = bodyOccludingBestOccludedRelay;
-						}
-						// Otherwise, target Kerbin.  Since we have LOS, blank the first occluding body.
+
+							// If the nearest relay is closer than the best occluded relay, pick it.
+							// Since nearestRelaySqrDistane is infinity if there are no nearby relays, this is safe.
+							if (nearestRelaySqrDistance < bestOccludedSqrDistance)
+							{
+								this.targetRelay = nearestRelay;
+								this.firstOccludingBody = null;
+							}
+							// Otherwise, target the best occluded relay.
+							else
+							{
+								this.targetRelay = bestOccludedRelay;
+								this.firstOccludingBody = bodyOccludingBestOccludedRelay;
+							}
+						}
+						// Otherwise, check Kerbin against the nearest relay.
+						// Since we have LOS, blank the first occluding body.
 						else
 						{
-							log.AppendFormat("\n\t\tPicking Kerbin as target ({0} >= {1}).",
-								bestOccludedSqrDistance, kerbinSqrDistance);
-
-							this.KerbinDirect = true;
-							this.targetRelay = null;
 							this.firstOccludingBody = null;
+
+							// If the nearest relay is closer than Kerbin, pick it.
+							// Since nearestRelaySqrDistane is infinity if there are no nearby relays, this is safe.
+							if (nearestRelaySqrDistance < kerbinSqrDistance)
+							{
+								this.KerbinDirect = false;
+								this.targetRelay = nearestRelay;
+							}
+							// Otherwise, pick Kerbin.
+							else
+							{
+								this.KerbinDirect = true;
+								this.targetRelay = null;
+							}
 						}
 					}
 				}
@@ -518,9 +583,6 @@
 		public AntennaRelay(IAntennaRelay module)
 		{
 			this.moduleRef = module;
-
-			this.searchTimer = new System.Diagnostics.Stopwatch();
-			this.millisecondsBetweenSearches = 125L;
 		}
 	}
 }

--- a/ProtoAntennaRelay.cs
+++ b/ProtoAntennaRelay.cs
@@ -126,11 +126,16 @@
 		/// <returns>A <see cref="System.String"/> that represents the current <see cref="AntennaRange.ProtoAntennaRelay"/>.</returns>
 		public override string ToString()
 		{
-			return string.Format(
-				"{0} on {1}",
-				this.Title,
-				this.protoPart.pVesselRef.vesselName
-			);
+			System.Text.StringBuilder sb = new System.Text.StringBuilder();
+
+			sb.Append(this.Title);
+
+			if (this.protoPart != null && this.protoPart.pVesselRef != null)
+			{
+				sb.AppendFormat(" on {0}", this.protoPart.pVesselRef.vesselName);
+			}
+
+			return sb.ToString();
 		}
 
 		/// <summary>