private IDictionary <Guid, Guid?> ExerciseCredits(Guid creditId, IEnumerable <Guid> hierarchyPath, bool adjustAllocation, Guid exercisedById, IEnumerable <Guid> exercisedOnIds, Guid?referenceId) { var exercisedCredits = new Dictionary <Guid, ExercisedCredit>(); var exercisedOwnerIds = new List <Guid>(); var allocations = _repository.GetActiveAllocations(hierarchyPath, new[] { creditId }); var originalRemainingQuantities = allocations.SelectMany(a => a.Value).ToDictionary(a => a.Id, a => a.RemainingQuantity); foreach (var exercisedOnId in exercisedOnIds) { // Iterate through the owners looking for someone who can exercise the credit. ExercisedCredit exercisedCredit = null; foreach (var ownerId in hierarchyPath) { exercisedCredit = ExerciseCredit(allocations[ownerId], adjustAllocation, exercisedById, exercisedOnId, referenceId); if (exercisedCredit != null) { if (!exercisedOwnerIds.Contains(ownerId)) { exercisedOwnerIds.Add(ownerId); } break; } } exercisedCredits[exercisedOnId] = exercisedCredit; } // Create all exercised credits. _repository.CreateExercisedCredits(from c in exercisedCredits where c.Value != null select c.Value); // Now update all allocations where needed. var changedAllocations = from a in allocations.SelectMany(a => a.Value) where a.RemainingQuantity != originalRemainingQuantities[a.Id] select a; if (changedAllocations.Any()) { _repository.UpdateAllocations(changedAllocations); } // Fire events. if (exercisedOwnerIds.Count > 0) { var handlers = CreditExercised; if (handlers != null) { foreach (var exercisedOwnerId in exercisedOwnerIds) { handlers(this, new CreditExercisedEventArgs(creditId, exercisedOwnerId, (from a in changedAllocations where a.OwnerId == exercisedOwnerId select a).Any())); } } } return(exercisedCredits.ToDictionary(c => c.Key, c => c.Value == null ? (Guid?)null : c.Value.Id)); }