public List <Task> GetAvailableTasks() { List <Task> available = new List <Task>(); // First of all, get the tasks from each breakable Task coffeeTask = coffeeMachine.getSpecialTask(); Task whiteboardTask = whiteboard.getSpecialTask(); Task switchTask = networkSwitch.getSpecialTask(); Task phoneTask = phone.getSpecialTask(); Task toiletTask = toilet.getSpecialTask(); available.Add(coffeeTask); available.Add(whiteboardTask); available.Add(phoneTask); available.Add(toiletTask); if (switchTask != null) { available.Add(switchTask); } // For each Task, if it is completed, look at its children (recursively?), // If it isn't completed, then add it to the list iff all of its parents // are completed. // Either doubly link the tree // Or check all available with their children for references to task completed.ForEach((t) => { if (t.nextTasks != null) { available.AddRange(t.nextTasks.FindAll((ta) => !ta.IsComplete())); } }); var workingSet = new HashSet <Task>(); var toRemove = new List <Task>(); available.ForEach((t) => searchForShit(workingSet, toRemove, t)); available.RemoveAll((t) => toRemove.Contains(t)); return(available); }