MemberInfo GetSetter()
        {
            Debug.Assert(Context.CurrentProperty != null, "Context.CurrentProperty != null");

            const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance;

            var propertyType = Context.CurrentProperty.PropertyType;
            var fields       = InstanceType.GetFields(bindingFlags);

            foreach (var field in fields)
            {
                var attrs = field.GetCustomAttributes(typeof(SetValueAttribute), true);

                if (attrs.Length > 0 && field.FieldType.IsSameOrParentOf(propertyType))
                {
                    return(field);
                }
            }

            var props = InstanceType.GetProperties(bindingFlags);

            foreach (var prop in props)
            {
                var attrs = prop.GetCustomAttributes(typeof(SetValueAttribute), true);

                if (attrs.Length > 0 && prop.PropertyType.IsSameOrParentOf(propertyType))
                {
                    return(prop);
                }
            }

            foreach (var field in fields)
            {
                if (field.Name == "Value" && field.FieldType.IsSameOrParentOf(propertyType))
                {
                    return(field);
                }
            }

            foreach (var prop in props)
            {
                if (prop.Name == "Value" && prop.PropertyType.IsSameOrParentOf(propertyType))
                {
                    return(prop);
                }
            }

            var method = InstanceType.GetMethod(false, "SetValue", bindingFlags);

            if (method != null && method.ReturnType == typeof(void))
            {
                return(method);
            }

            throw new TypeBuilderException(string.Format(
                                               "The '{0}' type does not have appropriate setter. See '{1}' member '{2}' of '{3}' type.",
                                               InstanceType.FullName, propertyType.FullName, Context.CurrentProperty.Name, Context.Type.FullName));
        }
        private MemberInfo GetSetter()
        {
            const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance;

            Type propertyType = Context.CurrentProperty.PropertyType;

            FieldInfo[] fields = InstanceType.GetFields(bindingFlags);

            foreach (FieldInfo field in fields)
            {
                object[] attrs = field.GetCustomAttributes(typeof(SetValueAttribute), true);

                if (attrs.Length > 0 && TypeHelper.IsSameOrParent(field.FieldType, propertyType))
                {
                    return(field);
                }
            }

            PropertyInfo[] props = InstanceType.GetProperties(bindingFlags);

            foreach (PropertyInfo prop in props)
            {
                object[] attrs = prop.GetCustomAttributes(typeof(SetValueAttribute), true);

                if (attrs.Length > 0 && TypeHelper.IsSameOrParent(prop.PropertyType, propertyType))
                {
                    return(prop);
                }
            }

            foreach (FieldInfo field in fields)
            {
                if (field.Name == "Value" && TypeHelper.IsSameOrParent(field.FieldType, propertyType))
                {
                    return(field);
                }
            }

            foreach (PropertyInfo prop in props)
            {
                if (prop.Name == "Value" && TypeHelper.IsSameOrParent(prop.PropertyType, propertyType))
                {
                    return(prop);
                }
            }

            MethodInfo method = TypeHelper.GetMethod(InstanceType, false, "SetValue", bindingFlags);

            if (method != null && method.ReturnType == typeof(void))
            {
                return(method);
            }

            throw new TypeBuilderException(string.Format(
                                               Resources.TypeBuilder_CannotGetSetter, InstanceType.FullName,
                                               propertyType.FullName, Context.CurrentProperty.Name, Context.Type.FullName));
        }