public static async T.Task <IEnumerable <Node> > GetNodesAsync(this CloudUtilities u, string lowerNodeName, string higherNodeName, int?count, CancellationToken token)
        {
            var nodesTable     = u.GetNodesTable();
            var partitionQuery = u.GetPartitionQueryString(u.NodesPartitionKey);

            var lastRegistrationKey    = u.GetRegistrationKey(lowerNodeName);
            var registrationEnd        = u.GetRegistrationKey(higherNodeName);
            var registrationRangeQuery = u.GetRowKeyRangeString(lastRegistrationKey, registrationEnd);

            var q = TableQuery.CombineFilters(
                partitionQuery,
                TableOperators.And,
                registrationRangeQuery);

            var registrations = (await nodesTable.QueryAsync <ComputeClusterRegistrationInformation>(q, count, token)).Select(r => r.Item3).ToList();

            if (!registrations.Any())
            {
                return(new Node[0]);
            }

            var firstHeartbeat      = u.GetHeartbeatKey(registrations[0].NodeName.ToLowerInvariant());
            var lastHeartbeat       = u.GetHeartbeatKey(registrations[registrations.Count - 1].NodeName.ToLowerInvariant());
            var heartbeatRangeQuery = u.GetRowKeyRangeString(firstHeartbeat, lastHeartbeat, true);

            q = TableQuery.CombineFilters(
                partitionQuery,
                TableOperators.And,
                heartbeatRangeQuery);

            var heartbeats = (await nodesTable.QueryAsync <ComputeClusterNodeInformation>(q, null, token)).ToDictionary(h => h.Item3.Name.ToLowerInvariant(), h => (h.Item3, h.Item4));

            return(registrations.Select(r =>
            {
                var nodeName = r.NodeName.ToLowerInvariant();
                var node = new Node()
                {
                    NodeRegistrationInfo = r, Name = nodeName,
                };

                if (heartbeats.TryGetValue(nodeName, out (ComputeClusterNodeInformation, DateTimeOffset)n))
                {
                    node.LastHeartbeatTime = n.Item2;
                    node.RunningJobCount = n.Item1.Jobs.Count;

                    if (n.Item2.AddSeconds(u.Option.MaxMissedHeartbeats * u.Option.HeartbeatIntervalSeconds) > DateTimeOffset.UtcNow)
                    {
                        node.Health = NodeHealth.OK;
                        node.State = NodeState.Online;
                        // TODO: adding events
                    }
                    else
                    {
                        node.Health = NodeHealth.Error;
                    }
                }

                return node;
            }));
        }