private async Task <ImmutableList <BranchGroupCompleteData> > GetBranchesToRemove(BranchGroupCompleteData targetBranch)
            {
                if (targetBranch.DirectDownstreamBranchGroups.Contains(newBaseBranch))
                {
                    // We're deleting an old branch, and all of its stuff moves down. This is like an integration branch rolling up. Easy.
                    return(new[] { targetBranch }.ToImmutableList());
                }
                var allBranches = await repository.AllBranches().FirstOrDefaultAsync();

                var actualBranches = await repository.DetectUpstream(sourceBranch);

                var upstreamBranches = await branchSettings.GetAllUpstreamBranches(sourceBranch).FirstAsync();

                // Filter to only the actual upstream branches; don't just remove anything that is downstream and happens to match!
                actualBranches = actualBranches.Intersect(upstreamBranches.Select(b => b.GroupName)).ToImmutableList();

                // FIXME - this is the _branches_ not the _groups_ that are up-to-date. That should be okay for these purposes.
                var downstream = (await branchSettings.GetBranchDetails(newBaseBranch).FirstAsync()).DownstreamBranchGroups;

                var consolidatingBranches = (await(from branch in allBranches.ToObservable()
                                                   where actualBranches.Contains(branch.GroupName) || branch.Branches.Select(b => b.Name).Any(actualBranches.Contains)
                                                   where downstream.Contains(branch.GroupName)
                                                   from result in GetLatestBranchTuple(branch)
                                                   select result
                                                   ).ToArray()).ToImmutableHashSet();


                var branchesToRemove = await FindReadyToConsolidate(consolidatingBranches);

                branchesToRemove = branchesToRemove.Concat(allBranches.Where(g => g.Branches.Select(b => b.Name).Contains(sourceBranch))).ToImmutableList();
                return(branchesToRemove);
            }
 public IObservable <BranchGroupCompleteData> GetBranchDetails(string branchName)
 {
     return(this.repositoryState.RemoteBranches()
            .Select(remoteBranches =>
     {
         return branchSettings.GetConfiguredBranches()
         .Select(branches => branches.FirstOrDefault(branch => branch.GroupName == branchName)
                 ?? branches.FirstOrDefault(branch => branchIteration.IsBranchIteration(branch.GroupName, branchName)))
         .Select(branchBasicDetails => branchSettings.GetBranchDetails(branchBasicDetails?.GroupName ?? branchName))
         .Switch()
         .Select(branchDetails => AddRemoteBranchNames(branchDetails, remoteBranches));
     }).Switch());
 }