/// <summary>
        /// Called when the cache does not contain the requested route length.
        /// Attempt to get length from the database, if it's not there then calculate it and
        /// store the result in the database.
        /// </summary>
        /// <param name="myObject"></param>
        /// <param name="args"></param>
        static void _cache_DataUpdateNeeded(object myObject, DataUpdateNeededArgs<RouteKey, int> args)
        {
            int jumps = int.MaxValue;
            int startSystemID = args.Key.StartSystem;
            int endSystemID = args.Key.EndSystem;

            if (_hitLevel.ContainsKey(args.Key))
            {
                _hitLevel.Remove(args.Key);
            }

            EveDataSet.SolarSystemDistancesDataTable distances = new EveDataSet.SolarSystemDistancesDataTable();

            // try the database...
            LoadDistanceData(startSystemID, endSystemID, distances);
            EveDataSet.SolarSystemDistancesRow distanceData =
                distances.FindByFromSolarSystemIDToSolarSystemID(startSystemID, endSystemID);

            if (distanceData != null)
            {
                jumps = distanceData.Distance;
                _hitLevel.Add(args.Key, 2);
            }
            else
            {
                LoadDistanceData(endSystemID, startSystemID, distances);
                distanceData = distances.FindByFromSolarSystemIDToSolarSystemID(endSystemID, startSystemID);
                if (distanceData != null)
                {
                    jumps = distanceData.Distance;
                    SetDistance(startSystemID, endSystemID, jumps);
                    _hitLevel.Add(args.Key, 2);
                }
                else
                {
                    // If it's not in the database then we need to calculate it.
                    Map.SetCosts(1, 1, 1);
                    jumps = Map.CalcRouteLength(startSystemID, endSystemID);
                    SetDistance(startSystemID, endSystemID, jumps);
                    _hitLevel.Add(args.Key, 3);
                }
            }

            args.Data = jumps;
        }
        public static void PopulateJumpsArray(List<long> fromSystemIDs, List<long> toSystemIDs,
            ref short[,] jumps, Dictionary<long, int> idMapper, ref int nextFreeIndex)
        {
            StringBuilder fromString = new StringBuilder("");
            StringBuilder toString = new StringBuilder("");
            List<long> addedIds = new List<long>();

            foreach (int id in fromSystemIDs)
            {
                if (!addedIds.Contains(id))
                {
                    if (fromString.Length > 0) { fromString.Append(","); }
                    fromString.Append(id);
                    addedIds.Add(id);
                }
            }
            addedIds = new List<long>();
            foreach (int id in toSystemIDs)
            {
                if (!addedIds.Contains(id))
                {
                    if (toString.Length > 0) { toString.Append(","); }
                    toString.Append(id);
                    addedIds.Add(id);
                }
            }

            EveDataSet.SolarSystemDistancesDataTable table = new EveDataSet.SolarSystemDistancesDataTable();
            tableAdapter.FillByMultipleIDs(table, fromString.ToString(), toString.ToString());

            foreach (EveDataSet.SolarSystemDistancesRow route in table)
            {
                int startSystemID = route.FromSolarSystemID;
                int endSystemID = route.ToSolarSystemID;
                if (startSystemID > endSystemID)
                {
                    int tmp = startSystemID;
                    startSystemID = endSystemID;
                    endSystemID = tmp;
                }

                int startIndex = 0;
                if (idMapper.ContainsKey(startSystemID))
                {
                    startIndex = idMapper[startSystemID];
                }
                else
                {
                    idMapper.Add(startSystemID, nextFreeIndex);
                    startIndex = nextFreeIndex;
                    nextFreeIndex++;
                }

                int endIndex = 0;
                if (idMapper.ContainsKey(endSystemID))
                {
                    endIndex = idMapper[endSystemID];
                }
                else
                {
                    idMapper.Add(endSystemID, nextFreeIndex);
                    endIndex = nextFreeIndex;
                    nextFreeIndex++;
                }

                jumps[startIndex, endIndex] = (short)route.Distance;
            }
        }
        /// <summary>
        /// Set distance data for the specified route
        /// </summary>
        /// <param name="startSystemID"></param>
        /// <param name="endSystemID"></param>
        /// <returns></returns>
        public static void SetDistance(int startSystemID, int endSystemID, int numJumps)
        {
            EveDataSet.SolarSystemDistancesDataTable distances = new EveDataSet.SolarSystemDistancesDataTable();
            LoadDistanceData(startSystemID, endSystemID, distances);
            EveDataSet.SolarSystemDistancesRow newRow = distances.FindByFromSolarSystemIDToSolarSystemID(
                startSystemID, endSystemID);

            if (newRow == null)
            {
                newRow = distances.NewSolarSystemDistancesRow();
                newRow.FromSolarSystemID = startSystemID;
                newRow.ToSolarSystemID = endSystemID;
                newRow.Distance = numJumps;
                distances.AddSolarSystemDistancesRow(newRow);
                lock (tableAdapter)
                {
                    tableAdapter.Update(distances);
                }
                distances.AcceptChanges();
            }
            else
            {
                newRow.Distance = numJumps;
                lock (tableAdapter)
                {
                    tableAdapter.Update(newRow);
                }
                distances.AcceptChanges();
            }
        }
 /// <summary>
 /// Get a list of system IDs for systems that are within the specified number of jumps
 /// of the given system.
 /// </summary>
 /// <param name="systemID"></param>
 /// <param name="range"></param>
 /// <returns></returns>
 public static List<long> GetSystemsInRange(long systemID, int range)
 {
     List<long> retVal = new List<long>();
     EveDataSet.SolarSystemDistancesDataTable table = new EveDataSet.SolarSystemDistancesDataTable();
     tableAdapter.FillBySystemAndRange(table, (int)systemID, range);
     foreach (EveDataSet.SolarSystemDistancesRow distance in table)
     {
         retVal.Add(distance.ToSolarSystemID);
     }
     return retVal;
 }