private void GenerateMappingForItem(Dictionary <int, TypeMapping> typeMappings, SchemaItem targetItem, GeneratedMethod parentMethod, Type rootSourceType) { if (typeMappings.ContainsKey(targetItem.key)) { var tm = typeMappings[targetItem.key]; if (IsSimpleDefault(tm)) { // item is defaulted - generate defaulting method tm.MappingMethod = new GeneratedMethod() { Name = GenerateDefaultingMethodName(tm), ReturnType = tm.TargetProperty.PropertyType }; parentMethod.AppendMethodBodyCode($"target.{tm.TargetProperty.Name} = {tm.MappingMethod.Name}();"); } else { if (CanBeDirectAssignment(tm)) { var propPath = BuildPropertyPath(tm.Mappings.First().SourcePath, parentMethod.Parameters, tm.TargetPath.IsArray); // first is valid here, because to be a valid direct assignment (like highlander) there can be only one parentMethod.AppendMethodBodyCode($"target.{tm.TargetProperty.Name} = {propPath};"); } else { if (tm.TargetPath.IsArray && tm.Mappings.Count == 1 && tm.Mappings[0].SourcePath.IsArray) { // array to array } else { tm.MappingMethod = new GeneratedMethod() { Name = GenerateMappingMethodName(tm), Parameters = GetMappingParameters(tm), ReturnType = tm.TargetProperty.PropertyType }; tm.MappingMethod.AppendMethodBodyCode($"var target = new {tm.TargetProperty.PropertyType}();"); var parameters = new List <string>(); foreach (var m in tm.Mappings) { var parameter = BuildPropertyPath(m.SourcePath, parentMethod.Parameters, m.SourcePath.IsArray); if (!parameters.Contains(parameter)) { parameters.Add(parameter); } } parentMethod.AppendMethodBodyCode($"target.{tm.TargetProperty.Name} = {tm.MappingMethod.Name}({string.Join(", ", parameters)});"); } } } IterateOverChildren(targetItem, typeMappings, rootSourceType, tm.MappingMethod); } else { IterateOverChildren(targetItem, typeMappings, rootSourceType, parentMethod); } }