public List <uint> FindBestPath(JVector origin, JVector destination)
        {
            if (_tradelanes.Count == 0)
            {
                return(null);
            }

            var tldist = new Dictionary <uint, double>();
            var tlprev = new Dictionary <uint, uint>();

            foreach (var tl in _tradelanes)
            {
                if (tldist.ContainsKey(tl.Key))
                {
                    continue;
                }

                JVector x1 = Solars[tl.Key].Position, x2 = Solars[tl.Value].Position;

                double t = -(x1 - origin).Dot(x2 - x1) / (x2 - x1).LengthSq();

                double cruiseTravel = 0, tlTravel = (x2 - x1).Length() / UniverseDB.TradelaneSpeed;
                if (t >= 0 && t <= 1)
                {
                    JVector newintersect = x1 + (x2 - x1) * t;
                    cruiseTravel = (newintersect - origin).Length();
                }
                else if (t < 0)
                {
                    t            = 0;
                    cruiseTravel = x1.DistanceTo(origin);
                }
                else if (t > 1)
                {
                    t            = 1;
                    cruiseTravel = x2.DistanceTo(origin);
                }

                tlprev.Add(tl.Key, 0);
                tlprev.Add(tl.Value, 0);
                tldist.Add(tl.Key, cruiseTravel / UniverseDB.CruiseSpeed + tlTravel * t);
                tldist.Add(tl.Value, cruiseTravel / UniverseDB.CruiseSpeed + tlTravel * (1 - t));
            }

            /*double dist = origin.DistanceTo(destination);
             * Solar closest = null;
             * foreach (KeyValuePair<uint, uint> tl in tradelanes)
             * {
             *  Solar s = solars[tl.Key];
             *  double newdist = s.position.DistanceTo(destination);
             *  if (newdist < dist)
             *  {
             *      dist = newdist;
             *      closest = s;
             *  }
             * }
             * if (closest == null)
             *  return null; // Cruise directly to destination*/

            var nodes = new HashSet <PathfindingNode>();

            foreach (var ns in _pathfinding)
            {
                nodes.Add(ns.Value);
            }

            while (nodes.Count > 0)
            {
                KeyValuePair <uint, double> u =
                    tldist.Where(x => nodes.Contains(_pathfinding[x.Key]))
                    .Aggregate((p1, p2) => (p1.Value < p2.Value) ? p1 : p2);

                nodes.Remove(_pathfinding[u.Key]);

                if (u.Value == Double.MaxValue)
                {
                    return(null); // derp?
                }
                foreach (PathfindingConnection c in _pathfinding[u.Key].Connections)
                {
                    if (nodes.Contains(c.To))
                    {
                        double alt = tldist[c.From.SolarID] + c.Cost;
                        if (alt < tldist[c.To.SolarID])
                        {
                            tldist[c.To.SolarID] = alt;
                            tlprev[c.To.SolarID] = c.From.SolarID;
                        }
                    }
                }
            }

            var objects = new List <uint>();

            {
                uint   u       = 0;
                double mindist = Double.MaxValue;

                foreach (var tl in tldist)
                {
                    var    s    = Solars[tl.Key];
                    double dist = s.Position.DistanceTo(destination) / UniverseDB.CruiseSpeed + tl.Value;
                    if (dist < mindist)
                    {
                        u       = tl.Key;
                        mindist = dist;
                    }
                }

                while (tlprev[u] != 0)
                {
                    objects.Add(u);
                    u = tlprev[u];
                }

                objects.Add(u);

                uint lastadded = u;

                uint minu = u;
                mindist = Solars[u].Position.DistanceTo(origin);
                if (Solars[u].PrevRing != 0)
                {
                    while (Solars[u].PrevRing != 0)
                    {
                        u = Solars[u].PrevRing;

                        double d = Solars[u].Position.DistanceTo(origin);
                        if (d < mindist)
                        {
                            minu    = u;
                            mindist = d;
                        }
                    }
                }
                else
                {
                    while (Solars[u].NextRing != 0)
                    {
                        u = Solars[u].NextRing;

                        double d = Solars[u].Position.DistanceTo(origin);
                        if (d < mindist)
                        {
                            minu    = u;
                            mindist = d;
                        }
                    }
                }

                if (minu == lastadded)
                {
                    objects.Remove(lastadded);
                }
                else
                {
                    objects.Add(minu);
                }
            }

            objects.Reverse();

            return(objects);
        }