private IEnumerable<Uri> Reserve(IEnumerable<ProxyWrapper> wrappers)
{
    var timeToComplete = DateTimeOffset.Now + TIMEOUT;
    var uris=Reserve(wrappers, 
                     MAX_RETRIES,
                     new List<Uri>(),
                     timeToComplete);
    return FinalizeReservation(uris);
}

private IEnumerable<Uri> Reserve(IEnumerable<ProxyWrapper> wrappers,
                                 int retries,
                                 ICollection<Uri> failedUris,
                                 DateTimeOffset timeToComplete)
{
   var success = true;
   var newUris = GetCandidateUris(wrappers, failedUris);
   if (null == newUris) return null;
   if (newUris.Count == 0) return newUris;
   failedUris = TryReserveNewMembers( newUris);
   if (failedUris.Count>0)
      success = false;
   if (DateTimeOffset.Now>timeToComplete)
      success = false;
   if (!success && retries==0)
      return null;
   if (!success && retries > 0)
      return Reserve(wrappers,
                   retries - 1,
                   failedUris,
                   timeToComplete);
   return newUris; 
}

private ICollection<Uri> TryReserveNewMembers( IEnumerable<Uri> newUris)
{
    var notifier = new SagaNotifier(Id,
                          Route,
                          newUris,
                          OptionalMembers,
                          LocalUri,
                          Allocator);
    var failedUris = notifier.ReserveAll();
    return failedUris;
}
