Reducing CPU to save polar bears - Fix for #2446

The amount of work done in order to build models has been reduced by:
  - Temporarily caching (in the stack) data structures that were not changing. See SyncNullabilityCSSpace().
  - Using direct iterators instead of enumerators in the hot path when the structures permit it.
  - Reducing the use of Linq and lambdas in the hot path in order to avoid unnecessary allocations and closures.
  - Calling ToList() instead of ToArray() when possible in order to avoid unnecessary allocations.
  - Eliminating the use of foreach enumerators with calls to .Reverse(). Instead using a direct decrement iterator.
  - Caching of property values that used to be computed when the getter was called. The cache also has an expiration policy related to the mutability of the data and the lifespan of the instance that references it.

The test that exposed this regression showed an 18% setback after changeset 604533a309d7 was committed. This fix not only puts model building back on baseline, but it made it 15% faster than it was before this regression.

All tests passing.
Schrödinger's Granny (2435: Stop IsPropertyChanged from throwing for change tracking entities)

The IsPropertyChanged API was added in .NET 4.5. The intention of this API is to check whether a property's current value is different from its original value. This may be different from the actual modified state of the property for properties that have been explicitly set as modified or where the property was changed but then changed back.

The problem is that for change tracking proxies and entities that derive from EntityObject there is no way of knowing this information because original values are not tracked for this type of entity. Therefore the best we can do is return whether or not the property is marked as modified, which is what we now do. We could throw instead, but for most usages the modified state is sufficient and hence seems like the more useful behavior.