public void Inherit_Run_Call_Derived_Custom_Method_On_Abstract_Base_()
        {
            // Inheritance is City <-- CityWithEditHistory <-- CityWithInfo
            // This test invokes a custom method declared on CityWithEditHistory via a CityWithInfo instance
            EntityChangeSet changeset;
            List<string> propChanged = new List<string>();
            CityDomainContext citiesProvider = new CityDomainContext(TestURIs.Cities);
            CityWithInfo cityWithInfo = null;
            DateTime priorLastUpdated = DateTime.Now;

            LoadOperation lo = citiesProvider.Load(citiesProvider.GetCitiesWithInfoQuery());
            SubmitOperation so = null;

            // wait for Load to complete, then invoke some domain methods
            EnqueueConditional(() => lo.IsComplete);
            EnqueueCallback(delegate
            {
                cityWithInfo = citiesProvider.Cities.FirstOrDefault() as CityWithInfo;
                Assert.IsNotNull(cityWithInfo, "Cities[0] should have been CityWithInfo but was " + citiesProvider.Cities.First().GetType().Name);
                changeset = citiesProvider.EntityContainer.GetChanges();
                Assert.IsTrue(changeset.IsEmpty);
                cityWithInfo.PropertyChanged += delegate(object sender, System.ComponentModel.PropertyChangedEventArgs e)
                {
                    // We filter to only those properties we see in the City hierarchy
                    BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;
                    bool isCityProperty = (typeof(CityWithInfo).GetProperty(e.PropertyName, flags) != null ||
                                           typeof(CityWithEditHistory).GetProperty(e.PropertyName, flags) != null ||
                                           typeof(City).GetProperty(e.PropertyName, flags) != null);
                    if (isCityProperty)
                    {
                        propChanged.Add(e.PropertyName);
                    }
                };

                priorLastUpdated = cityWithInfo.LastUpdated;
                Assert.IsTrue(cityWithInfo.CanTouchHistory);
                cityWithInfo.TouchHistory("xxx");
            });

            // wait for prop changed for domain method guards
            EnqueueConditional(() => propChanged.Count > 0);

            // Inject small delay so DateTime.Now executed on server is later than value in cithWithInfo
            EnqueueDelay(50);

            // Test validation that we will, in fact, get a different time stamp
            EnqueueCallback(delegate
            {
                Assert.AreNotEqual(priorLastUpdated, DateTime.Now, "Expected difference in times after small delay");
            });

            EnqueueCallback(delegate
            {
                Assert.IsTrue(propChanged.Contains("CanTouchHistory"));
                propChanged.Clear();

                changeset = citiesProvider.EntityContainer.GetChanges();
                Assert.AreEqual(1, changeset.ModifiedEntities.Count);

                so = citiesProvider.SubmitChanges();

                Assert.AreEqual(1, so.ChangeSet.ModifiedEntities.Count);
                Assert.AreEqual(0, so.ChangeSet.AddedEntities.Count);
                Assert.AreEqual(0, so.ChangeSet.RemovedEntities.Count);
            });
            // wait for submit to complete, then verify invokedEntities in changeset
            EnqueueConditional(() => so.IsComplete);
            EnqueueCallback(delegate
            {
                Assert.IsNull(so.Error);
                Assert.AreEqual(1, so.ChangeSet.ModifiedEntities.Count);

                // verify we got the property change notification for the city entity as a result of autosync
                Assert.AreEqual(12, propChanged.Count, "Received different property notifications than expected:\r\n" + string.Join(",", propChanged.ToArray()));
                Assert.AreEqual(1, propChanged.Count(prop => prop =="EditHistory"));
                Assert.AreEqual(1, propChanged.Count(prop => prop =="LastUpdated"));
                Assert.AreEqual(2, propChanged.Count(prop => prop =="CanAssignCityZone"));
                Assert.AreEqual(2, propChanged.Count(prop => prop =="CanAssignCityZoneIfAuthorized"));
                Assert.AreEqual(2, propChanged.Count(prop => prop =="CanAutoAssignCityZone"));
                Assert.AreEqual(1, propChanged.Count(prop => prop =="CanTouchHistory"));
                Assert.AreEqual(1, propChanged.Count(prop => prop =="IsTouchHistoryInvoked"));
                Assert.AreEqual(2, propChanged.Count(prop => prop =="CanSetCityInfo"));

                // verify entities are auto-synced back to the client as a result of the domain method execution on server
                CityWithInfo newCityWithInfo = citiesProvider.Cities.OfType<CityWithInfo>().SingleOrDefault<CityWithInfo>(c => (c.EditHistory.Contains("touch")));
                Assert.IsNotNull(newCityWithInfo, "Did not find modified CityWithInfo after the submit");
                Assert.AreNotEqual(newCityWithInfo.LastUpdated, priorLastUpdated, "Expected lastUpdated to be modified by submit");
                Assert.IsTrue(newCityWithInfo.EditHistory.Contains("touch=xxx"), "EditHistory was" + newCityWithInfo.EditHistory);
            });

            EnqueueTestComplete();
        }