'Computes the shortest distance along the transform graph from
one system to another.
Parameters
fromsys : class
The coordinate frame class to start from.
tosys : class
The coordinate frame class to transform into.
Returns
path : list of classes or `None`
The path from ``fromsys`` to ``tosys`` as an in-order sequence
of classes.  This list includes *both* ``fromsys`` and
``tosys``. Is `None` if there is no possible path.
distance : number
The total distance/priority from ``fromsys`` to ``tosys``.  If
priorities are not set this is the number of transforms
needed. Is ``inf`` if there is no possible path.'

def find_shortest_path(self, fromsys, tosys):

    inf = float(u'inf')
    if (tosys is fromsys):
        if (tosys not in self._graph[fromsys]):
            return ([tosys], 0)
    if (tosys in self._graph[fromsys]):
        t = self._graph[fromsys][tosys]
        return ([fromsys, tosys], float((t.priority if hasattr(t, u'priority') else 1)))
    if (fromsys in self._shortestpaths):
        fpaths = self._shortestpaths[fromsys]
        if (tosys in fpaths):
            return fpaths[tosys]
        else:
            return (None, inf)
    nodes = []
    for a in self._graph:
        if (a not in nodes):
            nodes.append(a)
        for b in self._graph[a]:
            if (b not in nodes):
                nodes.append(b)
    if ((fromsys not in nodes) or (tosys not in nodes)):
        return (None, inf)
    edgeweights = {}
    for a in self._graph:
        edgeweights[a] = aew = {}
        agraph = self._graph[a]
        for b in agraph:
            aew[b] = float((agraph[b].priority if hasattr(agraph[b], u'priority') else 1))
    q = [[inf, i, n, []] for (i, n) in enumerate(nodes) if (n is not fromsys)]
    q.insert(0, [0, (-1), fromsys, []])
    result = {}
    while (len(q) > 0):
        (d, orderi, n, path) = heapq.heappop(q)
        if (d == inf):
            result[n] = (None, d)
            for (d, orderi, n, path) in q:
                result[n] = (None, d)
            break
        else:
            result[n] = (path, d)
            path.append(n)
            if (n not in edgeweights):
                continue
            for n2 in edgeweights[n]:
                if (n2 not in result):
                    for i in range(len(q)):
                        if (q[i][2] == n2):
                            break
                    else:
                        raise ValueError(u'n2    not    in    heap    -    this    should    be    impossible!')
                    newd = (d + edgeweights[n][n2])
                    if (newd < q[i][0]):
                        q[i][0] = newd
                        q[i][3] = list(path)
                        heapq.heapify(q)
    self._shortestpaths[fromsys] = result
    return result[tosys]
