internal static IGate Replace(this IGate gate, Func <IGate, IGate> replacer) { IGate result; if (gate.Type.IsLogical()) { result = gate.Clone(); if (result is IModifyGate) { var logic = (IModifyGate)result; var inputs = result.GetInputs().ToList(); for (int j = 0; j < inputs.Count; ++j) { var input = inputs[j]; var r = input.Replace(replacer); if (r != input) { logic.ReplaceInput(j, r); } } } else { throw new ArgumentException("expected logic gate."); } } else { result = gate; } result = replacer(result); return(result); }