public static CodeTypeMember ConvertToSourceMethod(
            TranslateAttribute attr,
            CodeMemberMethod method, CodeParameterDeclarationExpression from,
            Func <Type, Type, TranslateAttribute> getTypesTranslateAttributeFn)
        {
            method.Statements.Add(from.ReturnNullIfNull());

            // targetType to = new T();
            var to = attr.SourceType.DeclareVar("to");

            method.Statements.Add(to);

            var fromTargetTypePropertyNames = attr.TargetType.GetProperties().ToList().Select(x => x.Name);

            foreach (var toSourceTypeProperty in attr.SourceType.GetProperties())
            {
                if (!fromTargetTypePropertyNames.Contains(toSourceTypeProperty.Name))
                {
                    continue;
                }
                method.Statements.Add(CreateToSourceAssignmentMethod(attr, to, toSourceTypeProperty, from, getTypesTranslateAttributeFn));
            }

            method.Statements.Add(to.Return());
            return(method);
        }
        public static CodeMemberMethod ConvertToTargetsMethod(TranslateAttribute attr, CodeParameterDeclarationExpression from)
        {
            var method = DeclareToTargetsMethod(attr, from);

            method.Statements.Add(from.ReturnNullIfNull());

            var to = "to".DeclareGenericVar(attr.TargetType, typeof(List <>));

            method.Statements.Add(to);

            CodeVariableDeclarationStatement item;
            var iter = from.ForEach(attr.SourceType, out item);

            method.Statements.Add(iter);
            var toTargetMethodName = attr.GetConvertToTargetMethodName();

            iter.Statements.Add(item.IfIsNotNull(to.Call(LIST_ADD_METHOD, item.Call(toTargetMethodName))));

            method.Statements.Add(to.Return());

            return(method);
        }
        public static CodeTypeMember ConvertToSourcesMethod(TranslateAttribute attr, CodeMemberMethod method, CodeParameterDeclarationExpression from)
        {
            method.Statements.Add(from.ReturnNullIfNull());

            var to = "to".DeclareGenericVar(attr.SourceType, typeof(List <>));

            method.Statements.Add(to);

            CodeVariableDeclarationStatement item;
            var iter = from.ForEach(attr.TargetType, out item);

            method.Statements.Add(iter);
            var useExtensionMethod = attr is TranslateExtensionAttribute;

            var itemMethod = useExtensionMethod
                                                        ? item.Call(attr.GetConvertToSourceMethodName())
                                                                        : attr.SourceType.Call(attr.GetConvertToSourceMethodName(), item);

            iter.Statements.Add(to.Call(LIST_ADD_METHOD, itemMethod));

            method.Statements.Add(to.Return());

            return(method);
        }