private Expression BuildWriterItem(IMappingAssociation association, Expression from, Expression to, ParameterExpression explicitProperties) { if ((association.Direction & MappingDirection.Write) != MappingDirection.Write) { return(null); } var converter = association as IConvertionAssociation; var component = association as IComponentAssociation; var donor = association.Target.Apply(@from); var acceptor = association.Source.Apply(to); Expression result; if (component != null) { //todo: probably should filterout expand somehow. E.g. 'foo.id' should become 'id'. Now simply not passing outer expand result = BuildWriterBody(donor, acceptor, null); if (result.NodeType == ExpressionType.Default && result.Type == typeof(void)) { return(null); } } else { PropertyInfo prop; if (!acceptor.TryGetProperty(out prop)) { throw new InvalidOperationException( string.Format("Mapping from source:{0} to target:{1} marked as writable but source is not a property access expression", association.Source.Stringify(), association.Target.Stringify()) ); } result = Expression.Assign( acceptor, converter == null ? donor : converter.TargetConverter.Expression.Apply(donor) ); } if (!(donor.Type.IsValueType || (result.NodeType == ExpressionType.Assign && ((BinaryExpression)result).Right == donor))) { result = Expression.IfThenElse( donor.CreateCheckForDefault(), Expression.Assign(acceptor, acceptor.Type.GetDefaultExpression()), result ); } if (explicitProperties != null) { result = Expression.IfThen( Expression.OrElse( explicitProperties.CreateCheckForDefault(), explicitProperties.CreateContains(Expression.Constant(association.Key, typeof(string))) ), result ); } return(result); }