Moved EventSniffer to ToadicusTools.
Moved EventSniffer to ToadicusTools.

--- a/AntennaRelay.cs
+++ b/AntennaRelay.cs
@@ -27,6 +27,7 @@
 		protected CelestialBody Kerbin;
 
 		protected IAntennaRelay _nearestRelayCache;
+		protected IAntennaRelay moduleRef;
 
 		protected System.Diagnostics.Stopwatch searchTimer;
 		protected long millisecondsBetweenSearches;
@@ -35,81 +36,83 @@
 		/// Gets the parent Vessel.
 		/// </summary>
 		/// <value>The parent Vessel.</value>
-		public Vessel vessel
+		public virtual Vessel vessel
+		{
+			get
+			{
+				return this.moduleRef.vessel;
+			}
+		}
+
+		/// <summary>
+		/// Gets or sets the nearest relay.
+		/// </summary>
+		/// <value>The nearest relay</value>
+		public IAntennaRelay nearestRelay
+		{
+			get
+			{
+				if (this.searchTimer.IsRunning &&
+					this.searchTimer.ElapsedMilliseconds > this.millisecondsBetweenSearches)
+				{
+					this._nearestRelayCache = this.FindNearestRelay();
+					this.searchTimer.Restart();
+				}
+
+				return this._nearestRelayCache;
+			}
+			protected set
+			{
+				this._nearestRelayCache = value;
+			}
+		}
+
+		/// <summary>
+		/// Gets the transmit distance.
+		/// </summary>
+		/// <value>The transmit distance.</value>
+		public double transmitDistance
+		{
+			get
+			{
+				this.nearestRelay = this.FindNearestRelay();
+
+				// If there is no available relay nearby...
+				if (this.nearestRelay == null)
+				{
+					// .. return the distance to Kerbin
+					return this.DistanceTo(this.Kerbin);
+				}
+				else
+				{
+					/// ...otherwise, return the distance to the nearest available relay.
+					return this.DistanceTo(nearestRelay);
+				}
+			}
+		}
+
+		/// <summary>
+		/// The maximum distance at which this relay can operate.
+		/// </summary>
+		/// <value>The max transmit distance.</value>
+		public virtual float maxTransmitDistance
+		{
+			get;
+			set;
+		}
+
+		/// <summary>
+		/// Gets a value indicating whether this <see cref="AntennaRange.ProtoDataTransmitter"/> has been checked during
+		/// the current relay attempt.
+		/// </summary>
+		/// <value><c>true</c> if relay checked; otherwise, <c>false</c>.</value>
+		public virtual bool relayChecked
 		{
 			get;
 			protected set;
 		}
 
 		/// <summary>
-		/// Gets or sets the nearest relay.
-		/// </summary>
-		/// <value>The nearest relay</value>
-		public IAntennaRelay nearestRelay
-		{
-			get
-			{
-				if (this.searchTimer.IsRunning &&
-					this.searchTimer.ElapsedMilliseconds > this.millisecondsBetweenSearches)
-				{
-					this._nearestRelayCache = this.FindNearestRelay();
-					this.searchTimer.Restart();
-				}
-
-				return this._nearestRelayCache;
-			}
-			protected set
-			{
-				this._nearestRelayCache = value;
-			}
-		}
-
-		/// <summary>
-		/// Gets the transmit distance.
-		/// </summary>
-		/// <value>The transmit distance.</value>
-		public double transmitDistance
-		{
-			get
-			{
-				this.nearestRelay = this.FindNearestRelay();
-
-				// If there is no available relay nearby...
-				if (this.nearestRelay == null)
-				{
-					// .. return the distance to Kerbin
-					return this.DistanceTo(this.Kerbin);
-				}
-				else
-				{
-					/// ...otherwise, return the distance to the nearest available relay.
-					return this.DistanceTo(nearestRelay);
-				}
-			}
-		}
-
-		/// <summary>
-		/// The maximum distance at which this relay can operate.
-		/// </summary>
-		/// <value>The max transmit distance.</value>
-		public virtual float maxTransmitDistance
-		{
-			get;
-			set;
-		}
-
-		/// <summary>
-		/// Gets a value indicating whether this <see cref="AntennaRange.ProtoDataTransmitter"/> has been checked during
-		/// the current relay attempt.
-		/// </summary>
-		/// <value><c>true</c> if relay checked; otherwise, <c>false</c>.</value>
-		public virtual bool relayChecked
-		{
-			get;
-			protected set;
-		}
-
-		/// <summary>
 		/// Determines whether this instance can transmit.
 		/// </summary>
 		/// <returns><c>true</c> if this instance can transmit; otherwise, <c>false</c>.</returns>
@@ -143,6 +146,13 @@
 			}
 
 			this.searchTimer.Start();
+
+			Tools.PostDebugMessage(string.Format(
+				"{0}: finding nearest relay for {1} ({2})",
+				this.GetType().Name,
+				this,
+				this.vessel.id
+			));
 
 			// Set this vessel as checked, so that we don't check it again.
 			RelayDatabase.Instance.CheckedVesselsTable[vessel.id] = true;
@@ -166,7 +176,7 @@
 						continue;
 					}
 				}
-				catch (KeyNotFoundException) { /* If the key doesn't exist, do nothing. */}
+				catch (KeyNotFoundException) { /* If the key doesn't exist, don't skip it. */}
 
 				// Skip vessels of the wrong type.
 				switch (potentialVessel.vesselType)
@@ -206,6 +216,11 @@
 					if (potentialRelay.CanTransmit())
 					{
 						_nearestRelay = potentialRelay;
+						Tools.PostDebugMessage(string.Format("{0}: found new best relay {1} ({2})",
+							this.GetType().Name,
+							_nearestRelay.ToString(),
+							_nearestRelay.vessel.id
+						));
 						break;
 					}
 				}
@@ -223,9 +238,9 @@
 		/// Initializes a new instance of the <see cref="AntennaRange.ProtoDataTransmitter"/> class.
 		/// </summary>
 		/// <param name="ms"><see cref="ProtoPartModuleSnapshot"/></param>
-		public AntennaRelay(Vessel v)
-		{
-			this.vessel = v;
+		public AntennaRelay(IAntennaRelay module)
+		{
+			this.moduleRef = module;
 
 			this.searchTimer = new System.Diagnostics.Stopwatch();
 			this.millisecondsBetweenSearches = 5000;
@@ -234,46 +249,6 @@
 			// we hope it is safe enough.
 			this.Kerbin = FlightGlobals.Bodies.FirstOrDefault(b => b.name == "Kerbin");
 		}
-
-		/*
-		 * Class implementing IComparer<IAntennaRelay> for use in sorting relays by distance.
-		 * */
-		internal class RelayComparer : IComparer<IAntennaRelay>
-		{
-			/// <summary>
-			/// The reference Vessel (usually the active vessel).
-			/// </summary>
-			protected Vessel referenceVessel;
-
-			// We don't want no stinking public parameterless constructors.
-			private RelayComparer() {}
-
-			/// <summary>
-			/// Initializes a new instance of the <see cref="AntennaRange.AntennaRelay+RelayComparer"/> class for use
-			/// in sorting relays by distance.
-			/// </summary>
-			/// <param name="reference">The reference Vessel</param>
-			public RelayComparer(Vessel reference)
-			{
-				this.referenceVessel = reference;
-			}
-
-			/// <summary>
-			/// Compare the <see cref="IAntennaRelay"/>s "one" and "two".
-			/// </summary>
-			/// <param name="one">The first IAntennaRelay in the comparison</param>
-			/// <param name="two">The second IAntennaRelay in the comparison</param>
-			public int Compare(IAntennaRelay one, IAntennaRelay two)
-			{
-				double distanceOne;
-				double distanceTwo;
-
-				distanceOne = one.vessel.DistanceTo(referenceVessel);
-				distanceTwo = two.vessel.DistanceTo(referenceVessel);
-
-				return distanceOne.CompareTo(distanceTwo);
-			}
-		}
 	}
 }
 

file:a/EventSniffer.cs (deleted)
--- a/EventSniffer.cs
+++ /dev/null
@@ -1,207 +1,1 @@
-// AntennaRange © 2014 toadicus
-//
-// This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. To view a
-// copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/
 
-#if DEBUG
-using KSP;
-using System;
-using System.Text;
-using UnityEngine;
-
-namespace AntennaRange
-{
-	[KSPAddon(KSPAddon.Startup.Flight, false)]
-	public class EventSniffer : MonoBehaviour
-	{
-		public void Awake()
-		{
-			GameEvents.onSameVesselDock.Add(this.onSameVesselDockUndock);
-			GameEvents.onSameVesselUndock.Add(this.onSameVesselDockUndock);
-			GameEvents.onPartUndock.Add(this.onPartUndock);
-			GameEvents.onUndock.Add(this.onReportEvent);
-			GameEvents.onPartCouple.Add(this.onPartCouple);
-			GameEvents.onPartJointBreak.Add(this.onPartJointBreak);
-		}
-
-		public void Destroy()
-		{
-			GameEvents.onSameVesselDock.Remove(this.onSameVesselDockUndock);
-			GameEvents.onSameVesselUndock.Remove(this.onSameVesselDockUndock);
-			GameEvents.onPartUndock.Remove(this.onPartUndock);
-			GameEvents.onUndock.Remove(this.onReportEvent);
-			GameEvents.onPartCouple.Remove(this.onPartCouple);
-			GameEvents.onPartJointBreak.Remove(this.onPartJointBreak);
-		}
-
-		public void onSameVesselDockUndock(GameEvents.FromToAction<ModuleDockingNode, ModuleDockingNode> data)
-		{
-			this.FromModuleToModuleHelper(
-				this.getStringBuilder(),
-				new GameEvents.FromToAction<PartModule, PartModule>(data.from, data.to)
-			);
-		}
-
-		public void onPartJointBreak(PartJoint joint)
-		{
-			this.PartJointHelper(this.getStringBuilder(), joint);
-		}
-
-		public void onPartUndock(Part part)
-		{
-			this.PartEventHelper(this.getStringBuilder(), part);
-		}
-
-		public void onReportEvent(EventReport data)
-		{
-			this.EventReportHelper(this.getStringBuilder(), data);
-		}
-
-		public void onPartCouple(GameEvents.FromToAction<Part, Part> data)
-		{
-			this.FromPartToPartHelper(this.getStringBuilder(), data);
-		}
-
-		internal void EventReportHelper(StringBuilder sb, EventReport data)
-		{
-			sb.Append("\n\tOrigin Part:");
-			this.appendPartAncestry(sb, data.origin);
-
-			sb.AppendFormat(
-				"\n\tother: '{0}'" +
-				"\n\tmsg: '{1}'" +
-				"\n\tsender: '{2}'",
-				data.other,
-				data.msg,
-				data.sender
-			);
-
-			Debug.Log(sb.ToString());
-		}
-
-		internal void PartEventHelper(StringBuilder sb, Part part)
-		{
-			this.appendPartAncestry(sb, part);
-
-			Debug.Log(sb.ToString());
-		}
-
-		internal void FromPartToPartHelper(StringBuilder sb, GameEvents.FromToAction<Part, Part> data)
-		{
-			sb.Append("\n\tFrom:");
-
-			this.appendPartAncestry(sb, data.from);
-
-			sb.Append("\n\tTo:");
-
-			this.appendPartAncestry(sb, data.to);
-
-			Debug.Log(sb.ToString());
-		}
-
-		internal void FromModuleToModuleHelper(StringBuilder sb, GameEvents.FromToAction<PartModule, PartModule> data)
-		{
-			sb.Append("\n\tFrom:");
-
-			this.appendModuleAncestry(sb, data.from);
-
-			sb.Append("\n\tTo:");
-
-			this.appendModuleAncestry(sb, data.to);
-
-			Debug.Log(sb.ToString());
-		}
-
-		internal void PartJointHelper(StringBuilder sb, PartJoint joint)
-		{
-			sb.Append("PartJoint: ");
-			if (joint != null)
-			{
-				sb.Append(joint);
-				this.appendPartAncestry(sb, joint.Host);
-			}
-			else
-			{
-				sb.Append("null");
-			}
-
-			Debug.Log(sb.ToString());
-		}
-
-		internal StringBuilder appendModuleAncestry(StringBuilder sb, PartModule module, uint tabs = 1)
-		{
-			sb.Append('\n');
-			for (ushort i=0; i < tabs; i++)
-			{
-				sb.Append('\t');
-			}
-			sb.Append("Module: ");
-
-			if (module != null)
-			{
-				sb.Append(module.moduleName);
-				this.appendPartAncestry(sb, module.part, tabs + 1u);
-			}
-			else
-			{
-				sb.Append("null");
-			}
-
-			return sb;
-		}
-
-		internal StringBuilder appendPartAncestry(StringBuilder sb, Part part, uint tabs = 1)
-		{
-			sb.Append('\n');
-			for (ushort i=0; i < tabs; i++)
-			{
-				sb.Append('\t');
-			}
-			sb.Append("Part: ");
-
-			if (part != null)
-			{
-				sb.AppendFormat("'{0}' ({1})", part.partInfo.title, part.partName);
-				this.appendVessel(sb, part.vessel, tabs + 1u);
-			}
-			else
-			{
-				sb.Append("null");
-			}
-
-			return sb;
-		}
-
-		internal StringBuilder appendVessel(StringBuilder sb, Vessel vessel, uint tabs = 1)
-		{
-			sb.Append('\n');
-			for (ushort i=0; i < tabs; i++)
-			{
-				sb.Append('\t');
-			}
-			sb.Append("Vessel: ");
-
-			if (vessel != null)
-			{
-				sb.AppendFormat("'{0}' ({1})", vessel.vesselName, vessel.id);
-			}
-			else
-			{
-				sb.Append("null");
-			}
-
-			return sb;
-		}
-
-		internal StringBuilder getStringBuilder()
-		{
-			StringBuilder sb = new StringBuilder();
-			sb.AppendFormat("{0}: called {1} ",
-				this.GetType().Name,
-				new System.Diagnostics.StackTrace().GetFrame(1).GetMethod().Name
-			);
-			return sb;
-		}
-	}
-}
-#endif

--- a/ModuleLimitedDataTransmitter.cs
+++ b/ModuleLimitedDataTransmitter.cs
@@ -204,7 +204,7 @@
 
 			if (state >= StartState.PreLaunch)
 			{
-				this.relay = new AntennaRelay(vessel);
+				this.relay = new AntennaRelay(this);
 				this.relay.maxTransmitDistance = this.maxTransmitDistance;
 
 				this.UImaxTransmitDistance = Tools.MuMech_ToSI(this.maxTransmitDistance) + "m";
@@ -330,8 +330,31 @@
 		// returns false.
 		public new void TransmitData(List<ScienceData> dataQueue)
 		{
+			this.PreTransmit_SetPacketSize();
+			this.PreTransmit_SetPacketResourceCost();
+
 			if (this.CanTransmit())
 			{
+				StringBuilder message = new StringBuilder();
+
+				message.Append("[");
+				message.Append(base.part.partInfo.title);
+				message.Append("]: ");
+
+				message.Append("Beginning transmission ");
+
+				if (this.relay.nearestRelay == null)
+				{
+					message.Append("directly to Kerbin.");
+				}
+				else
+				{
+					message.Append("via ");
+					message.Append(this.relay.nearestRelay);
+				}
+
+				ScreenMessages.PostScreenMessage(message.ToString(), 4f, ScreenMessageStyle.UPPER_LEFT);
+
 				base.TransmitData(dataQueue);
 			}
 			else
@@ -451,7 +474,8 @@
 				"DataRate: {9}\n" +
 				"DataResourceCost: {10}\n" +
 				"TransmitterScore: {11}\n" +
-				"NearestRelay: {12}",
+				"NearestRelay: {12}\n" +
+				"Vessel ID: {13}",
 				this.name,
 				this._basepacketSize,
 				base.packetSize,
@@ -464,9 +488,31 @@
 				this.DataRate,
 				this.DataResourceCost,
 				ScienceUtil.GetTransmitterScore(this),
-				this.relay.FindNearestRelay()
+				this.relay.FindNearestRelay(),
+				this.vessel.id
 				);
-			ScreenMessages.PostScreenMessage (new ScreenMessage (msg, 4f, ScreenMessageStyle.UPPER_RIGHT));
+			Tools.PostDebugMessage(msg);
+		}
+
+		[KSPEvent (guiName = "Dump Vessels", active = true, guiActive = true)]
+		public void PrintAllVessels()
+		{
+			StringBuilder sb = new StringBuilder();
+
+			sb.Append("Dumping FlightGlobals.Vessels:");
+
+			foreach (Vessel vessel in FlightGlobals.Vessels)
+			{
+				sb.AppendFormat("\n'{0} ({1})'", vessel.vesselName, vessel.id);
+			}
+
+			Tools.PostDebugMessage(sb.ToString());
+		}
+
+		[KSPEvent (guiName = "Dump RelayDB", active = true, guiActive = true)]
+		public void DumpRelayDB()
+		{
+			RelayDatabase.Instance.Dump();
 		}
 		#endif
 	}

--- a/Properties/AssemblyInfo.cs
+++ b/Properties/AssemblyInfo.cs
@@ -25,7 +25,7 @@
 // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
 // The form "{Major}.{Minor}.*" will automatically update the build and revision,
 // and "{Major}.{Minor}.{Build}.*" will update just the revision.
-[assembly: AssemblyVersion("0.6.3.*")]
+[assembly: AssemblyVersion("1.0.0.*")]
 // The following attributes are used to specify the signing key for the assembly,
 // if desired. See the Mono documentation for more information about signing.
 //[assembly: AssemblyDelaySign(false)]

--- a/ProtoAntennaRelay.cs
+++ b/ProtoAntennaRelay.cs
@@ -26,11 +26,16 @@
 	 * */
 	public class ProtoAntennaRelay : AntennaRelay, IAntennaRelay
 	{
-		// Stores the relay prefab
-		protected IAntennaRelay relayPrefab;
-
 		// Stores the prototype part so we can make sure we haven't exploded or so.
 		protected ProtoPartSnapshot protoPart;
+
+		public override Vessel vessel
+		{
+			get
+			{
+				return this.protoPart.pVesselRef.vesselRef;
+			}
+		}
 
 		/// <summary>
 		/// The maximum distance at which this transmitter can operate.
@@ -40,7 +45,7 @@
 		{
 			get
 			{
-				return relayPrefab.maxTransmitDistance;
+				return moduleRef.maxTransmitDistance;
 			}
 		}
 
@@ -87,7 +92,7 @@
 		public override string ToString()
 		{
 			return string.Format(
-				"{0} on {1}.",
+				"{0} on {1} (proto)",
 				this.title,
 				this.protoPart.pVesselRef.vesselName
 			);
@@ -98,11 +103,9 @@
 		/// </summary>
 		/// <param name="ms">The ProtoPartModuleSnapshot to wrap</param>
 		/// <param name="vessel">The parent Vessel</param>
-		public ProtoAntennaRelay(IAntennaRelay prefabRelay, ProtoPartSnapshot pps) : base(pps.pVesselRef.vesselRef)
+		public ProtoAntennaRelay(IAntennaRelay prefabRelay, ProtoPartSnapshot pps) : base(prefabRelay)
 		{
-			this.relayPrefab = prefabRelay;
 			this.protoPart = pps;
-			this.vessel = pps.pVesselRef.vesselRef;
 		}
 
 		~ProtoAntennaRelay()