public void SetValue(object targetResource, string propertyName, object propertyValue)
        {
            CustomUtils.CheckArgumentNotNull(targetResource, "targetResource");
            CustomUtils.CheckArgumentNotNull(propertyName, "propertyName");

            var property = GetProperty(targetResource.GetType(), propertyName);

            if (IsComplexType(property.PropertyType))
            {
                // we treat complex types as value types, an inherit part of an entity type,
                // they cannot be null, have no separate metadata, always exist and
                // by design complex type properties have no setters
                //
                // we can relax these constraints later, but now change detection
                // logic in custom object context depends on it

                if (null == propertyValue)
                {
                    throw new ArgumentNullException(String.Format(
                                                        "Value for complex type property '{0}' cannot be null.",
                                                        propertyName
                                                        ));
                }

                object currentComplexValue = property.GetValue(targetResource, null);
                CopyComplexTypeObject(currentComplexValue, propertyValue);
                return;
            }

            CustomMemberType entityMember;

            if (TryGetEntityMember(targetResource, propertyName, out entityMember))
            {
                if (entityMember is CustomNavigationPropertyType)
                {
                    throw new InvalidOperationException(String.Format(
                                                            "Given property '{0}' of entity object '{1}' is a navigation " +
                                                            "property of type '{2}'. SetValue() is not supposed for " +
                                                            "changing navigation properties. Use SetReference() or " +
                                                            "AddReferenceToCollection() methods.",
                                                            propertyName, targetResource, entityMember.ClrType
                                                            ));
                }

                Debug.Assert(entityMember is CustomPropertyType);

                CustomPropertyType entityProperty = (CustomPropertyType)entityMember;

                if (null != entityProperty.ForeignKeyConstraint)
                {
                    // attempt to set a foreign key property is incorrect in the world of our custom
                    // data model because there is no setter for such properties at all and the getter
                    // simply returns value of a primary key property from the primary end entity using
                    // corresponding navigation property
                    // get
                    // {
                    //    if(null == _primaryEnd)
                    //    {
                    //       return default(int);
                    //    }
                    //    return _primaryEnd.Id;
                    // }
                    //
                    // silently return from SetValue without error reporting for compatibility
                    // with existing tests
                    return;
                }

                if (entityProperty.IsPrimaryKey)
                {
                    // all our primary keys are store generated and have internal setter, but
                    // test framework for Astoria suppose to be able to set primary keys and
                    // then use same values to query the object; we allow it here to be
                    // compatible with the existing tests; for objects with initialized primary keys
                    // the custom object context will actually queue an update operation, but not insert
                    entityProperty.SetValue(targetResource, propertyValue);
                    return;
                }
            }
            else
            {
                Debug.Assert(IsComplexType(targetResource.GetType()));
            }

            if (null == property.GetSetMethod() || !property.CanWrite)
            {
                throw new InvalidOperationException(String.Format(
                                                        "Property '{0}' of resource type '{1}' is not writable.",
                                                        propertyName,
                                                        targetResource.GetType().Name
                                                        ));
            }
            property.SetValue(targetResource, propertyValue, null);
        }