/// <summary>Chooses datanode locations for caching from a list of valid possibilities.
        ///     </summary>
        /// <remarks>
        /// Chooses datanode locations for caching from a list of valid possibilities.
        /// Non-stale nodes are chosen before stale nodes.
        /// </remarks>
        /// <param name="possibilities">List of candidate datanodes</param>
        /// <param name="neededCached">Number of replicas needed</param>
        /// <param name="staleInterval">Age of a stale datanode</param>
        /// <returns>A list of chosen datanodes</returns>
        private static IList <DatanodeDescriptor> ChooseDatanodesForCaching(IList <DatanodeDescriptor
                                                                                   > possibilities, int neededCached, long staleInterval)
        {
            // Make a copy that we can modify
            IList <DatanodeDescriptor> targets = new AList <DatanodeDescriptor>(possibilities);
            // Selected targets
            IList <DatanodeDescriptor> chosen = new List <DatanodeDescriptor>();
            // Filter out stale datanodes
            IList <DatanodeDescriptor>       stale = new List <DatanodeDescriptor>();
            IEnumerator <DatanodeDescriptor> it    = targets.GetEnumerator();

            while (it.HasNext())
            {
                DatanodeDescriptor d = it.Next();
                if (d.IsStale(staleInterval))
                {
                    it.Remove();
                    stale.AddItem(d);
                }
            }
            // Select targets
            while (chosen.Count < neededCached)
            {
                // Try to use stale nodes if we're out of non-stale nodes, else we're done
                if (targets.IsEmpty())
                {
                    if (!stale.IsEmpty())
                    {
                        targets = stale;
                    }
                    else
                    {
                        break;
                    }
                }
                // Select a random target
                DatanodeDescriptor target = ChooseRandomDatanodeByRemainingCapacity(targets);
                chosen.AddItem(target);
                targets.Remove(target);
            }
            return(chosen);
        }