public override Element Apply(Difference difference) { if (difference == null) { throw new ArgumentNullException("difference"); } if (!difference.Identifier.Equals(this.Identifier)) { throw new MergeException("Cannot apply a difference that does not share the same identifier with the element."); } if (difference is NodeDifference) { var mergedChilds = new ElementHashList(r_childs); foreach (var subdifference in ((NodeDifference)difference).Subdifferences) { switch (subdifference.OperationOnParent) { case OperationOnParent.Added: mergedChilds.Add(subdifference.Identifier.CreateEmptyElement().Apply(subdifference)); break; case OperationOnParent.Modified: mergedChilds.AddOrUpdate(mergedChilds[subdifference.Identifier].Apply(subdifference)); break; case OperationOnParent.Removed: mergedChilds.Remove(subdifference.Identifier); break; default: throw new ArgumentOutOfRangeException("subdifference.OperationOnParent", subdifference.OperationOnParent, "Invalid value"); } } return(new NodeElement(this.Identifier, mergedChilds)); } else { throw new MergeException(string.Format("Cannot apply a {0} on a {1}.", difference.GetType().Name, this.GetType().Name)); } }