ResourceDictionary.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / System / Windows / ResourceDictionary.cs / 1 / ResourceDictionary.cs

                            /****************************************************************************\ 
*
* File: ResourceDictionary.cs
*
*  Dictionary that holds Resources for Framework components. 
*
* Copyright (C) 2003 by Microsoft Corporation.  All rights reserved. 
* 
\***************************************************************************/
 
using System;
using System.IO;
using System.Net;
using System.Collections; 
using System.Collections.Generic;
using System.Collections.ObjectModel; 
using System.Collections.Specialized; 
using System.Diagnostics;
using System.ComponentModel; 
using System.Windows.Threading;
using System.Windows.Media;
using System.Windows.Markup;
using System.IO.Packaging; 
using MS.Internal.IO.Packaging;         // for PackageCacheEntry
using System.Globalization; 
using System.Windows.Navigation; 

using MS.Internal; 
using MS.Internal.Utility;
using MS.Internal.AppModel;
using MS.Utility;
 
namespace System.Windows
{ 
    ///  
    ///     Dictionary that holds Resources for Framework components.
    ///  
    [Localizability(LocalizationCategory.Ignore)]
    public class ResourceDictionary : IDictionary, INameScope, ISupportInitialize, IUriContext
    {
        #region Constructor 

        ///  
        ///     Constructor for ResourceDictionary 
        /// 
        public ResourceDictionary() 
        {
            _baseDictionary = new Hashtable();
            IsThemeDictionary = SystemResources.IsSystemResourcesParsing;
        } 

        #endregion Constructor 
 
        #region PublicAPIs
 
        /// 
        ///     Copies the dictionary's elements to a one-dimensional
        ///     Array instance at the specified index.
        ///  
        /// 
        ///     The one-dimensional Array that is the destination of the 
        ///     DictionaryEntry objects copied from Hashtable. The Array 
        ///     must have zero-based indexing.
        ///  
        /// 
        ///     The zero-based index in array at which copying begins.
        /// 
        public void CopyTo(DictionaryEntry[] array, int arrayIndex) 
        {
            if (CanBeAccessedAcrossThreads) 
            { 
                lock(((ICollection)this).SyncRoot)
                { 
                    CopyToWithoutLock(array, arrayIndex);
                }
            }
            else 
            {
                CopyToWithoutLock(array, arrayIndex); 
            } 
        }
 
        private void CopyToWithoutLock(DictionaryEntry[] array, int arrayIndex)
        {
            if (array == null)
            { 
                throw new ArgumentNullException("array");
            } 
 
            _baseDictionary.CopyTo(array, arrayIndex);
 
            int length = arrayIndex + Count;
            for (int i = arrayIndex; i < length; i++)
            {
                DictionaryEntry entry = array[i]; 
                object value = entry.Value;
                bool canCache; 
                if (RealizeDeferContent(entry.Key, ref value, out canCache)) 
                {
                    entry.Value = value; 
                }
            }
        }
 
        ///
        ///     List of ResourceDictionaries merged into this Resource Dictionary 
        /// 
        public Collection MergedDictionaries
        { 
            get
            {
                if (_mergedDictionaries == null)
                { 
                    _mergedDictionaries = new ResourceDictionaryCollection(this);
                    _mergedDictionaries.CollectionChanged += OnMergedDictionariesChanged; 
                } 

                return _mergedDictionaries; 
            }
        }

        /// 
        ///     Uri to load this resource from, it will clear the current state of the ResourceDictionary
        /// 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public Uri Source
        { 
            get
            {
                return _source;
            } 
            set
            { 
                if (value == null || String.IsNullOrEmpty(value.OriginalString)) 
                {
                    throw new ArgumentException(SR.Get(SRID.ResourceDictionaryLoadFromFailure, value == null ? "''" : value.ToString())); 
                }

                _source = value;
 
                Clear();
 
                Uri uri = BindUriHelper.GetResolvedUri(_baseUri, _source); 
                WebRequest request = WpfWebRequestHelper.CreateRequest(uri);
                WpfWebRequestHelper.ConfigCachePolicy(request, false); 
                ContentType contentType;
                Stream s = WpfWebRequestHelper.GetResponseStream(request, out contentType);

                // MimeObjectFactory.GetObjectAndCloseStream will try to find the object converter basing on the mime type. 
                // It can be a [....]/async converter. It's the converter's responsiblity to close the stream.
                // If it fails to find a convert, this call will return null. 
                XamlReader asyncObjectConverter; 
                ResourceDictionary loadedRD = MimeObjectFactory.GetObjectAndCloseStream(s, contentType, uri, false, false, false /*allowAsync*/, false /*isJournalNavigation*/, out asyncObjectConverter)
                                            as ResourceDictionary; 

                if (loadedRD == null)
                {
                    throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryLoadFromFailure, _source.ToString())); 
                }
 
                // ReferenceCopy all the key-value pairs in the _baseDictionary 
                _baseDictionary = loadedRD._baseDictionary;
 
                // ReferenceCopy all the entries in the MergedDictionaries collection
                _mergedDictionaries = loadedRD._mergedDictionaries;

                // ReferenceCopy all of the deferred content state 
                _buffer = loadedRD._buffer;
                _bamlStream = loadedRD._bamlStream; 
                _startPosition = loadedRD._startPosition; 
                _contentSize = loadedRD._contentSize;
                _context = loadedRD._context; 
                _rootElement = loadedRD._rootElement;
                _reader = loadedRD._reader;
                _numDefer = loadedRD._numDefer;
 
                // Copy over the HasImplicitStyles flag
                HasImplicitStyles = loadedRD.HasImplicitStyles; 
 
                if (!IsInitializePending)
                { 
                    // Fire Invalidations for the changes made by asigning a new Source
                    NotifyOwners(new ResourcesChangeInfo(null, this));
                }
            } 
        }
 
        #region INameScope 
        /// 
        /// Registers the name - element combination 
        /// 
        /// name of the element
        /// Element where name is defined
        public void RegisterName(string name, object scopedElement) 
        {
            throw new NotSupportedException(SR.Get(SRID.NamesNotSupportedInsideResourceDictionary)); 
        } 

        ///  
        /// Unregisters the name - element combination
        /// 
        /// Name of the element
        public void UnregisterName(string name) 
        {
            // Do Nothing as Names cannot be registered on ResourceDictionary 
        } 

        ///  
        /// Find the element given name
        /// 
        /// Name of the element
        /// null always 
        public object FindName(string name)
        { 
            return null; 
        }
 
        #endregion INameScope

        #region IUriContext
 
        /// 
        ///     Accessor for the base uri of the ResourceDictionary 
        ///  
        Uri IUriContext.BaseUri
        { 
            get
            {
                return  _baseUri;
            } 
            set
            { 
                _baseUri = value; 
            }
        } 

        #endregion IUriContext

        #endregion PublicAPIs 

        #region IDictionary 
 
        /// 
        ///     Gets a value indicating whether the IDictionary has a fixed size. 
        /// 
        public bool IsFixedSize
        {
            get { return _baseDictionary.IsFixedSize; } 
        }
 
        ///  
        ///     Gets a value indicating whether the ResourceDictionary is read-only.
        ///  
        public bool IsReadOnly
        {
            get { return ReadPrivateFlag(PrivateFlags.IsReadOnly); }
            internal set 
            {
                WritePrivateFlag(PrivateFlags.IsReadOnly, value); 
 
                if (value == true)
                { 
                    // Seal all the styles and templates in this dictionary
                    SealValues();
                }
 
                // Set all the merged resource dictionaries as ReadOnly
                if (_mergedDictionaries != null) 
                { 
                    for (int i = 0; i < _mergedDictionaries.Count; i++)
                    { 
                        _mergedDictionaries[i].IsReadOnly = value;
                    }
                }
            } 
        }
 
        ///  
        ///     Gets or sets the value associated with the specified key.
        ///  
        /// 
        ///     Fire Invalidations only for changes made after the Init Phase
        ///     If the key is not found on this ResourceDictionary, it will look on any MergedDictionaries for it
        ///  
        public object this[object key]
        { 
            get 
            {
                bool canCache; 
                return GetValue(key, out canCache);
            }

            set 
            {
                // Seal styles and templates within App and Theme dictionary 
                SealValue(value); 

                if (CanBeAccessedAcrossThreads) 
                {
                    lock(((ICollection)this).SyncRoot)
                    {
                        SetValueWithoutLock(key, value); 
                    }
                } 
                else 
                {
                    SetValueWithoutLock(key, value); 
                }
            }
        }
 
        private void SetValueWithoutLock(object key, object value)
        { 
            if (IsReadOnly) 
            {
                throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryIsReadOnly)); 
            }

            object oldValue = _baseDictionary[key];
 
            if (oldValue != value)
            { 
                // We need to validate all the deferred references that refer 
                // to the old resource before we overwrite it.
                ValidateDeferredResourceReferences(key); 

                if( TraceResourceDictionary.IsEnabled )
                {
                    TraceResourceDictionary.Trace( TraceEventType.Start, 
                                                   TraceResourceDictionary.AddResource,
                                                   this, 
                                                   key, 
                                                   value );
                } 


                _baseDictionary[key] = value;
 
                // Update the HasImplicitStyles flag
                UpdateHasImplicitStyles(key); 
 
                // Notify owners of the change and fire invalidate if already initialized
                NotifyOwners(new ResourcesChangeInfo(key)); 

                if( TraceResourceDictionary.IsEnabled )
                {
                    TraceResourceDictionary.Trace( 
                                                  TraceEventType.Stop,
                                                  TraceResourceDictionary.AddResource, 
                                                  this, 
                                                  key,
                                                  value ); 
                }


            } 
        }
 
        internal object GetValue(object key, out bool canCache) 
        {
            if (CanBeAccessedAcrossThreads) 
            {
                lock(((ICollection)this).SyncRoot)
                {
                    return GetValueWithoutLock(key, out canCache); 
                }
            } 
            else 
            {
                return GetValueWithoutLock(key, out canCache); 
            }
        }

        private object GetValueWithoutLock(object key, out bool canCache) 
        {
            object value = _baseDictionary[key]; 
            if (value != null) 
            {
                RealizeDeferContent(key, ref value, out canCache); 
            }
            else
            {
                canCache = true; 

                //Search for the value in the Merged Dictionaries 
                if (_mergedDictionaries != null) 
                {
                    for (int i = MergedDictionaries.Count - 1; (i > -1); i--) 
                    {
                        // Note that MergedDictionaries collection can also contain null values
                        ResourceDictionary mergedDictionary = MergedDictionaries[i];
                        if (mergedDictionary != null) 
                        {
                            value = mergedDictionary.GetValue(key, out canCache); 
                            if (value != null) 
                            {
                                break; 
                            }
                        }
                    }
                } 
            }
 
            return value; 
        }
 
        // Gets the type of the value stored at the given key
        internal Type GetValueType(object key, out bool found)
        {
            found = false; 
            Type valueType = null;
 
            object value = _baseDictionary[key]; 
            if (value != null)
            { 
                found = true;

                IBamlDictionaryKey keyRecord = value as IBamlDictionaryKey;
                if (keyRecord != null) 
                {
                    Debug.Assert(_numDefer > 0, "The stream was closed before all deferred content was loaded."); 
 
                    Int32 valuePosition = keyRecord.ValuePosition;
 
                    BamlRecordReader previousRecordReader = _context.BamlReader;
                    BamlRecordReader reader = Reader;
                    _context.BamlReader = reader;
 
                    try
                    { 
                        // Remember the starting stream position, so that it can be repositioned 
                        // after the read to handle recursive operations on the same stream.
                        Int64 startPosition = _bamlStream.Position; 

                        _bamlStream.Position = _startPosition + valuePosition;
                        BamlElementStartRecord bamlElementStartRecord = (BamlElementStartRecord)reader.GetNextRecord();
                        valueType = reader.MapTable.GetTypeFromId(bamlElementStartRecord.TypeId); 

                        _bamlStream.Position = startPosition; 
                    } 
                    finally
                    { 
                        // Restore the previousRecordReader into the context
                        _context.BamlReader = previousRecordReader;
                    }
                } 
                else
                { 
                    valueType = value.GetType(); 
                }
 
            }
            else
            {
                // Search for the value in the Merged Dictionaries 
                if (_mergedDictionaries != null)
                { 
                    for (int i = MergedDictionaries.Count - 1; (i > -1); i--) 
                    {
                        // Note that MergedDictionaries collection can also contain null values 
                        ResourceDictionary mergedDictionary = MergedDictionaries[i];
                        if (mergedDictionary != null)
                        {
                            valueType = mergedDictionary.GetValueType(key, out found); 
                            if (found)
                            { 
                                break; 
                            }
                        } 
                    }
                }
            }
 
            return valueType;
        } 
 
        /// 
        ///     Gets a copy of the ICollection containing the keys of the IDictionary. 
        /// 
        public ICollection Keys
        {
            get 
            {
                object[] keysCollection = new object[Count]; 
                _baseDictionary.Keys.CopyTo(keysCollection, 0); 
                return keysCollection;
            } 
        }

        /// 
        ///     Gets an ICollection containing the values in the Hashtable 
        /// 
        /// An ICollection containing the values in the Hashtable 
        public ICollection Values 
        {
            get 
            {
                return new ResourceValuesCollection(this);
            }
        } 

        ///  
        ///     Adds an entry 
        /// 
        ///  
        ///     Fire Invalidations only for changes made after the Init Phase
        /// 
        public void Add(object key, object value)
        { 
            // Seal styles and templates within App and Theme dictionary
            SealValue(value); 
 
            if (CanBeAccessedAcrossThreads)
            { 
                lock(((ICollection)this).SyncRoot)
                {
                    AddWithoutLock(key, value);
                } 
            }
            else 
            { 
                AddWithoutLock(key, value);
            } 

        }

        private void AddWithoutLock(object key, object value) 
        {
            if (IsReadOnly) 
            { 
                throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryIsReadOnly));
            } 

            if( TraceResourceDictionary.IsEnabled )
            {
                TraceResourceDictionary.Trace( TraceEventType.Start, 
                                               TraceResourceDictionary.AddResource,
                                               this, 
                                               key, 
                                               value );
            } 


            _baseDictionary.Add(key, value);
 
            // Update the HasImplicitKey flag
            UpdateHasImplicitStyles(key); 
 
            // Notify owners of the change and fire invalidate if already initialized
            NotifyOwners(new ResourcesChangeInfo(key)); 

            if( TraceResourceDictionary.IsEnabled )
            {
                TraceResourceDictionary.Trace( TraceEventType.Stop, 
                                               TraceResourceDictionary.AddResource,
                                               this, 
                                               key, 
                                               value );
            } 

        }

        ///  
        ///     Removes all elements from the IDictionary.
        ///  
        public void Clear() 
        {
            if (CanBeAccessedAcrossThreads) 
            {
                lock(((ICollection)this).SyncRoot)
                {
                    ClearWithoutLock(); 
                }
            } 
            else 
            {
                ClearWithoutLock(); 
            }
        }

        private void ClearWithoutLock() 
        {
            if (IsReadOnly) 
            { 
                throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryIsReadOnly));
            } 

            if (Count > 0)
            {
                // We need to validate all the deferred references that refer 
                // to the old resource before we clear it.
                ValidateDeferredResourceReferences(null); 
 
                // remove inheritance context from all values that got it from
                // this dictionary 
                RemoveInheritanceContextFromValues();

                _baseDictionary.Clear();
 
                // Notify owners of the change and fire invalidate if already initialized
                NotifyOwners(ResourcesChangeInfo.CatastrophicDictionaryChangeInfo); 
            } 
        }
 
        /// 
        ///     Determines whether the IDictionary contains an element with the specified key.
        ///     if the Key is not contained in this ResourceDictionary, it will check in the MergedDictionaries too
        ///  
        public bool Contains(object key)
        { 
            bool result = _baseDictionary.Contains(key); 

            //Search for the value in the Merged Dictionaries 
            if (_mergedDictionaries != null)
            {
                for (int i = MergedDictionaries.Count - 1; (i > -1) && !result; i--)
                { 
                    // Note that MergedDictionaries collection can also contain null values
                    ResourceDictionary mergedDictionary = MergedDictionaries[i]; 
                    if (mergedDictionary != null) 
                    {
                        result = mergedDictionary.Contains(key); 
                    }
                }
            }
            return result; 
        }
 
        ///  
        ///     Determines whether the IDictionary contains a BamlObjectFactory against the specified key.
        ///     if the Key is not contained in this ResourceDictionary, it will check in the MergedDictionaries too 
        /// 
        internal bool ContainsBamlObjectFactory(object key)
        {
            return GetBamlObjectFactory(key) != null; 
        }
 
        ///  
        ///     Retrieves an IBamlDictionaryKey from the IDictionary using the specified key.
        ///     If the Key is not contained in this ResourceDictionary, it will check in the MergedDictionaries too 
        /// 
        internal IBamlDictionaryKey GetBamlObjectFactory(object key)
        {
            if (_baseDictionary.Contains(key)) 
            {
                return _baseDictionary[key] as IBamlDictionaryKey; 
            } 

            //Search for the value in the Merged Dictionaries 
            if (_mergedDictionaries != null)
            {
                for (int i = MergedDictionaries.Count - 1; i > -1; i--)
                { 
                    // Note that MergedDictionaries collection can also contain null values
                    ResourceDictionary mergedDictionary = MergedDictionaries[i]; 
                    if (mergedDictionary != null) 
                    {
                        IBamlDictionaryKey keyRecord = mergedDictionary.GetBamlObjectFactory(key); 
                        if (keyRecord != null)
                        {
                            return keyRecord;
                        } 
                    }
                } 
            } 

            return null; 
        }

        /// 
        ///     Returns an IDictionaryEnumerator that can iterate through the Hashtable 
        /// 
        /// An IDictionaryEnumerator for the Hashtable 
        public IDictionaryEnumerator GetEnumerator() 
        {
            return new ResourceDictionaryEnumerator(this); 
        }

        /// 
        ///     Removes an entry 
        /// 
        ///  
        ///     Fire Invalidations only for changes made after the Init Phase 
        /// 
        public void Remove(object key) 
        {
            if (CanBeAccessedAcrossThreads)
            {
                lock(((ICollection)this).SyncRoot) 
                {
                    RemoveWithoutLock(key); 
                } 
            }
            else 
            {
                RemoveWithoutLock(key);
            }
        } 

        private void RemoveWithoutLock(object key) 
        { 
            if (IsReadOnly)
            { 
                throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryIsReadOnly));
            }

            // We need to validate all the deferred references that refer 
            // to the old resource before we remove it.
            ValidateDeferredResourceReferences(key); 
 
            // remove the inheritance context from the value, if it came from
            // this dictionary 
            RemoveInheritanceContext(_baseDictionary[key]);

            _baseDictionary.Remove(key);
 
            // Notify owners of the change and fire invalidate if already initialized
            NotifyOwners(new ResourcesChangeInfo(key)); 
        } 

        #endregion IDictionary 

        #region ICollection

        ///  
        ///     Gets the number of elements contained in the ICollection.
        ///  
        public int Count 
        {
            get { return _baseDictionary.Count; } 
        }

        /// 
        ///     Gets a value indicating whether access to the ICollection is synchronized (thread-safe). 
        /// 
        bool ICollection.IsSynchronized 
        { 
            get { return _baseDictionary.IsSynchronized; }
        } 

        /// 
        ///     Gets an object that can be used to synchronize access to the ICollection.
        ///  
        object ICollection.SyncRoot
        { 
            get 
            {
                if (CanBeAccessedAcrossThreads) 
                {
                    // Notice that we are acquiring the ThemeDictionaryLock. This
                    // is because the _parserContext used for template expansion
                    // shares data-structures such as the BamlMapTable and 
                    // XamlTypeMapper with the parent ParserContext that was used
                    // to build the template in the first place. So if this template 
                    // is from the App.Resources then the ParserContext that is used for 
                    // loading deferred content in the app dictionary and the
                    // _parserContext used to load template content share the same 
                    // instances of BamlMapTable and XamlTypeMapper. Hence we need to
                    // make sure that we lock on the same object inorder to serialize
                    // access to these data-structures in multi-threaded scenarios.
                    // Look at comment in Frameworktemplate.LoadContent to understand 
                    // why we use the ThemeDictionaryLock for template expansion.
 
                    return SystemResources.ThemeDictionaryLock; 
                }
                else 
                {
                    return _baseDictionary.SyncRoot;
                }
            } 
        }
 
        ///  
        ///     Copies the dictionary's elements to a one-dimensional
        ///     Array instance at the specified index. 
        /// 
        /// 
        ///     The one-dimensional Array that is the destination of the
        ///     DictionaryEntry objects copied from Hashtable. The Array 
        ///     must have zero-based indexing.
        ///  
        ///  
        ///     The zero-based index in array at which copying begins.
        ///  
        void ICollection.CopyTo(Array array, int arrayIndex)
        {
            CopyTo(array as DictionaryEntry[], arrayIndex);
        } 

        #endregion ICollection 
 
        #region IEnumerable
 
        IEnumerator IEnumerable.GetEnumerator()
        {
            return ((IDictionary)this).GetEnumerator();
        } 

        #endregion IEnumerable 
 
        #region ISupportInitialize
 
        /// 
        ///     Mark the begining of the Init phase
        /// 
        ///  
        ///     BeginInit and EndInit follow a transaction model. BeginInit marks the
        ///     dictionary uninitialized and EndInit marks it initialized. 
        ///  
        public void BeginInit()
        { 
            // Nested BeginInits on the same instance aren't permitted
            if (IsInitializePending)
            {
                throw new InvalidOperationException(SR.Get(SRID.NestedBeginInitNotSupported)); 
            }
 
            IsInitializePending = true; 
            IsInitialized = false;
        } 

        /// 
        ///     Fire Invalidation at the end of Init phase
        ///  
        /// 
        ///     BeginInit and EndInit follow a transaction model. BeginInit marks the 
        ///     dictionary uninitialized and EndInit marks it initialized. 
        /// 
        public void EndInit() 
        {
            // EndInit without a BeginInit isn't permitted
            if (!IsInitializePending)
            { 
                throw new InvalidOperationException(SR.Get(SRID.EndInitWithoutBeginInitNotSupported));
            } 
            Debug.Assert(IsInitialized == false, "Dictionary should not be initialized when EndInit is called"); 

            IsInitializePending = false; 
            IsInitialized = true;

            // Fire Invalidations collectively for all changes made during the Init Phase
            NotifyOwners(new ResourcesChangeInfo(null, this)); 
        }
 
        #endregion ISupportInitialize 

        #region DeferContent 

        private bool CanCache(IBamlDictionaryKey keyRecord, object value)
        {
            if (keyRecord.SharedSet) 
            {
                return keyRecord.Shared; 
            } 
            else
            { 
                return true;
            }
        }
 
        private bool RealizeDeferContent(ref object value)
        { 
            bool canCache; 
            return RealizeDeferContent(null, ref value, out canCache);
        } 

        private bool RealizeDeferContent(object key, ref object value, out bool canCache)
        {
            IBamlDictionaryKey keyRecord = value as IBamlDictionaryKey; 
            if (keyRecord != null)
            { 
                Debug.Assert(_numDefer > 0, "The stream was closed before all deferred content was loaded."); 

                Int32 valuePosition = keyRecord.ValuePosition; 

                // Store the StaticResources list for the current key record into the parserContext so that
                // StaticResourceId records within the current value can use it for lookup.
                _context.StaticResourcesStack.Add(keyRecord.StaticResourceValues); 
                try
                { 
                    if( TraceResourceDictionary.IsEnabled ) 
                    {
                        TraceResourceDictionary.Trace( 
                            TraceEventType.Start,
                            TraceResourceDictionary.RealizeDeferContent,
                            this,
                            key, 
                            value );
                    } 
 
                    value = CreateObject(valuePosition, key);
 
                }
                finally
                {
                    if( TraceResourceDictionary.IsEnabled ) 
                    {
                        TraceResourceDictionary.Trace( 
                            TraceEventType.Stop, 
                            TraceResourceDictionary.RealizeDeferContent,
                            this, 
                            key,
                            value );
                    }
 
                    _context.StaticResourcesStack.RemoveAt(_context.StaticResourcesStack.Count-1);
                } 
 
                if (key != null)
                { 
                    canCache = CanCache(keyRecord, value);
                    if (canCache)
                    {
                        // Seal styles and templates within App and Theme dictionary 
                        SealValue(value);
 
                        _numDefer--; 
                        _baseDictionary[key] = value;
 
                        if (_numDefer == 0)
                        {
                            _reader = null;
                            _context = null; 

                            // Only close the stream if it was a Memory Stream 
                            // built over our buffer. 
                            if(null != _buffer)
                            { 
                                _bamlStream.Close();
                                _bamlStream = null;
                                _buffer = null;
                            } 
                        }
                    } 
                } 
                else
                { 
                    canCache = true;
                }

                return true; /* Defer content */ 
            }
 
            canCache = true; 
            return false;   /* Not defer content */
        } 

        /// 
        ///  Add a byte array that contains deferable content
        ///  
        internal void SetDeferableContent(
            byte[]                          buffer, 
            ParserContext                   context, 
            object                          rootElement,
            ArrayList                       keyCollection, 
            List                  staticResourceValuesList)
        {
            if (buffer == null)
            { 
                throw new ArgumentNullException("buffer");
            } 
            if (context == null) 
            {
                throw new ArgumentNullException("context"); 
            }
            if (keyCollection == null)
            {
                throw new ArgumentNullException("keyCollection"); 
            }
 
            // If we already have the Source set then we can ignore 
            // this deferable content section
            if (_source == null) 
            {
                if (_context == null)
                {
                    _buffer = buffer; 
                    _bamlStream = new MemoryStream(buffer);
                    _startPosition = 0; 
                    _contentSize = buffer.Length; 
                    _context = context.Clone();
                    _rootElement = rootElement; 

                    SetKeys(keyCollection, staticResourceValuesList, context);
                }
                else 
                {
                    throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryDuplicateDeferredContent)); 
                } 
            }
            else if (keyCollection.Count > 0) 
            {
                throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryDeferredContentFailure));
            }
        } 

 
        ///  
        ///  Add a stream that contains deferable content
        ///  
        internal void SetDeferableContent(
            Stream                          bamlStream,
            Int64                           startPosition,
            Int32                           contentSize, 
            ParserContext                   context,
            object                          rootElement, 
            ArrayList                       keyCollection, 
            List                  staticResourceValuesList)
        { 
            if (bamlStream == null)
            {
                throw new ArgumentNullException("bamlStream");
            } 
            if (!bamlStream.CanRead)
            { 
                throw new ArgumentException(SR.Get(SRID.InputStreamMustBeReadable,"bamlStream")); 
            }
            if (context == null) 
            {
                throw new ArgumentNullException("context");
            }
            if (keyCollection == null) 
            {
                throw new ArgumentNullException("keyCollection"); 
            } 
            if (startPosition < 0)
            { 
                throw new ArgumentOutOfRangeException("startPosition");
            }
            if (contentSize < 0)
            { 
                throw new ArgumentOutOfRangeException("contentSize");
            } 
 
            // If we already have the Source set then we can ignore
            // this deferable content section 
            if (_source == null)
            {
                if (_context == null)
                { 
                    _bamlStream = bamlStream;
                    _startPosition = startPosition; 
                    _contentSize = contentSize; 
                    _context = context.Clone();
 
                    // We need to clear the Journal bit, because we know we won't be able to honor it correctly.
                    // Journaling journals the properties in the logical tree, so doesn't journal properties in the
                    // Template/Resources.  This shouldn't be hard-coded here, but is an internal solution for V1.
                    _context.SkipJournaledProperties = false; 
                    _rootElement = rootElement;
 
                    SetKeys(keyCollection, staticResourceValuesList, context); 
                }
                else 
                {
                    throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryDuplicateDeferredContent));
                }
            } 
            else if (keyCollection.Count > 0)
            { 
                throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryDeferredContentFailure)); 
            }
        } 

        private void SetKeys(
            ArrayList      keyCollection,
            List staticResourceValuesList, 
            ParserContext  context)
        { 
            _numDefer = keyCollection.Count; 

            // Use the array Count property to avoid range checking inside the loop 
            for (int i = 0; i < keyCollection.Count; i++)
            {
                IBamlDictionaryKey keyRecord = keyCollection[i] as IBamlDictionaryKey;
                if (keyRecord != null) 
                {
                    SetStaticResources(staticResourceValuesList[i], context); 
                    keyRecord.StaticResourceValues = staticResourceValuesList[i]; 

                    // Update the HasImplicitStyles flag 
                    UpdateHasImplicitStyles(keyRecord.KeyObject);

                    _baseDictionary.Add(keyRecord.KeyObject, keyRecord);
 
                    if( TraceResourceDictionary.IsEnabled )
                    { 
                        TraceResourceDictionary.TraceActivityItem( 
                            TraceResourceDictionary.SetKey,
                            this, 
                            keyRecord.KeyObject );
                    }

                } 
                else
                { 
                    throw new ArgumentException(SR.Get(SRID.KeyCollectionHasInvalidKey)); 
                }
            } 

            // Notify owners of the HasImplicitStyles flag value
            // but there is not need to fire an invalidation.
            NotifyOwners(new ResourcesChangeInfo(null, this)); 

            // Get the XamlObjectIds (Name, Uid, and Key) that are currently in our context. 
            // When we realize tese resources, we'll pass in that information, so that they 
            // can generate good exception messages.
 
            Type objectType;
            XamlParseException.GetObjectContext(context.BamlReader,
                                                null, // currentObjectIdentifiers
                                                _contextXamlObjectIds, 
                                                out objectType );
 
        } 

        private void SetStaticResources(object[] staticResourceValues, ParserContext context) 
        {
            if (staticResourceValues != null && staticResourceValues.Length > 0)
            {
                bool inDeferredSection = context.InDeferredSection; 

                for (int i=0; i(1);
                } 
                else if (_ownerFEs.Contains(fe) && ContainsCycle(this))
                { 
                    throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryInvalidMergedDictionary)); 
                }
 
                // Propagate the HasImplicitStyles flag to the new owner
                if (HasImplicitStyles)
                {
                    fe.ShouldLookupImplicitStyles = true; 
                }
 
                _ownerFEs.Add(fe); 
            }
            else 
            {
                FrameworkContentElement fce = owner as FrameworkContentElement;
                if (fce != null)
                { 
                    if (_ownerFCEs == null)
                    { 
                        _ownerFCEs = new List(1); 
                    }
                    else if (_ownerFCEs.Contains(fce) && ContainsCycle(this)) 
                    {
                        throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryInvalidMergedDictionary));
                    }
 
                    // Propagate the HasImplicitStyles flag to the new owner
                    if (HasImplicitStyles) 
                    { 
                        fce.ShouldLookupImplicitStyles = true;
                    } 

                    _ownerFCEs.Add(fce);
                }
                else 
                {
                    Application app = owner as Application; 
                    if (app != null) 
                    {
                        if (_ownerApps == null) 
                        {
                            _ownerApps = new List(1);
                        }
                        else if (_ownerApps.Contains(app) && ContainsCycle(this)) 
                        {
                            throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryInvalidMergedDictionary)); 
                        } 

                        // Propagate the HasImplicitStyles flag to the new owner 
                        if (HasImplicitStyles)
                        {
                            app.HasImplicitStylesInResources = true;
                        } 

                        _ownerApps.Add(app); 
 
                        // An Application ResourceDictionary can be accessed across threads
                        CanBeAccessedAcrossThreads = true; 

                        // Seal all the styles and templates in this app dictionary
                        SealValues();
                    } 
                }
            } 
 
            AddOwnerToAllMergedDictionaries(owner);
 
            // This dictionary will be marked initialized if no one has called BeginInit on it.
            // This is done now because having an owner is like a parenting operation for the dictionary.
            TryInitialize();
        } 

        // Remove an owner for this dictionary 
        internal void RemoveOwner(DispatcherObject owner) 
        {
            FrameworkElement fe = owner as FrameworkElement; 
            if (fe != null)
            {
                if (_ownerFEs != null)
                { 
                    _ownerFEs.Remove(fe);
 
                    if (_ownerFEs.Count == 0) 
                    {
                        _ownerFEs = null; 
                    }
                }
            }
            else 
            {
                FrameworkContentElement fce = owner as FrameworkContentElement; 
                if (fce != null) 
                {
                    if (_ownerFCEs != null) 
                    {
                        _ownerFCEs.Remove(fce);

                        if (_ownerFCEs.Count == 0) 
                        {
                            _ownerFCEs = null; 
                        } 
                    }
                } 
                else
                {
                    Application app = owner as Application;
                    if (app != null) 
                    {
                        if (_ownerApps != null) 
                        { 
                            _ownerApps.Remove(app);
 
                            if (_ownerApps.Count == 0)
                            {
                                _ownerApps = null;
                            } 
                        }
                    } 
                } 
            }
 
            RemoveOwnerFromAllMergedDictionaries(owner);
        }

        // Check if the given is an owner to this dictionary 
        internal bool ContainsOwner(DispatcherObject owner)
        { 
            FrameworkElement fe = owner as FrameworkElement; 
            if (fe != null)
            { 
                return (_ownerFEs != null && _ownerFEs.Contains(fe));
            }
            else
            { 
                FrameworkContentElement fce = owner as FrameworkContentElement;
                if (fce != null) 
                { 
                    return (_ownerFCEs != null && _ownerFCEs.Contains(fce));
                } 
                else
                {
                    Application app = owner as Application;
                    if (app != null) 
                    {
                        return (_ownerApps != null && _ownerApps.Contains(app)); 
                    } 
                }
            } 

            return false;
        }
 
        // Helper method that tries to set IsInitialized to true if BeginInit hasn't been called before this.
        // This method is called on AddOwner 
        private void TryInitialize() 
        {
            if (!IsInitializePending && 
                !IsInitialized)
            {
                IsInitialized = true;
            } 
        }
 
        // Call FrameworkElement.InvalidateTree with the right data 
        private void NotifyOwners(ResourcesChangeInfo info)
        { 
            bool shouldInvalidate   = IsInitialized;
            bool hasImplicitStyles  = info.IsResourceAddOperation && HasImplicitStyles;

            if (shouldInvalidate || hasImplicitStyles) 
            {
                // Invalidate all FE owners 
                if (_ownerFEs != null) 
                {
                    for (int i=0; i<_ownerFEs.Count; i++) 
                    {
                        // Set the HasImplicitStyles flag on the owner
                        if (hasImplicitStyles)
                            _ownerFEs[i].ShouldLookupImplicitStyles = true; 

                        // If this dictionary has been initialized fire an invalidation 
                        // to let the tree know of this change. 
                        if (shouldInvalidate)
                            TreeWalkHelper.InvalidateOnResourcesChange(_ownerFEs[i], null, info); 
                    }
                }

                // Invalidate all FCE owners 
                if (_ownerFCEs != null)
                { 
                    for (int i=0; i<_ownerFCEs.Count; i++) 
                    {
                        // Set the HasImplicitStyles flag on the owner 
                        if (hasImplicitStyles)
                            _ownerFCEs[i].ShouldLookupImplicitStyles = true;

                        // If this dictionary has been initialized fire an invalidation 
                        // to let the tree know of this change.
                        if (shouldInvalidate) 
                            TreeWalkHelper.InvalidateOnResourcesChange(null, _ownerFCEs[i], info); 
                    }
                } 

                // Invalidate all App owners
                if (_ownerApps != null)
                { 
                    for (int i=0; i<_ownerApps.Count; i++)
                    { 
                        // Set the HasImplicitStyles flag on the owner 
                        if (hasImplicitStyles)
                            _ownerApps[i].HasImplicitStylesInResources = true; 

                        // If this dictionary has been initialized fire an invalidation
                        // to let the tree know of this change.
                        if (shouldInvalidate) 
                            _ownerApps[i].InvalidateResourceReferences(info);
                    } 
                } 
            }
        } 

        /// 
        /// Fetches the resource corresponding to the given key from this dictionary.
        /// Returns a DeferredResourceReference if the object has not been inflated yet. 
        /// 
        internal object FetchResource( 
            object      resourceKey, 
            bool        allowDeferredResourceReference,
            bool        mustReturnDeferredResourceReference, 
            out bool    canCache)
        {
            Debug.Assert(resourceKey != null, "ResourceKey cannot be null");
 
            if (allowDeferredResourceReference)
            { 
                if (ContainsBamlObjectFactory(resourceKey) || 
                    (mustReturnDeferredResourceReference && Contains(resourceKey)))
                { 
                    canCache = false;

                    DeferredResourceReference deferredResourceReference;
                    if (!IsThemeDictionary) 
                    {
                        if (_ownerApps != null) 
                        { 
                            deferredResourceReference = new DeferredAppResourceReference(this, resourceKey);
                        } 
                        else
                        {
                            deferredResourceReference = new DeferredResourceReference(this, resourceKey);
                        } 

                        // Cache the deferredResourceReference so that it can be validated 
                        // in case of a dictionary change prior to its inflation 
                        if (_deferredResourceReferences == null)
                        { 
                            _deferredResourceReferences = new List();
                        }

                        _deferredResourceReferences.Add(deferredResourceReference); 
                    }
                    else 
                    { 
                        deferredResourceReference = new DeferredThemeResourceReference(this, resourceKey);
                    } 

                    return deferredResourceReference;
                }
            } 

            return GetValue(resourceKey, out canCache); 
        } 

        ///  
        /// Validate the deferredResourceReference with the given key. Key could be null meaning
        /// some catastrophic operation occurred so simply validate all DeferredResourceReferences
        /// 
        private void ValidateDeferredResourceReferences(object resourceKey) 
        {
            if (_deferredResourceReferences != null) 
            { 
                for (int i=0; i<_deferredResourceReferences.Count; i++)
                { 
                    DeferredResourceReference deferredResourceReference = _deferredResourceReferences[i];
                    if (resourceKey == null || Object.Equals(resourceKey, deferredResourceReference.Key))
                    {
#if DEBUG 
                        int oldCount = _deferredResourceReferences.Count;
#endif 
                        deferredResourceReference.GetValue(BaseValueSourceInternal.Unknown); 

#if DEBUG 
                        int newCount = _deferredResourceReferences.Count;
                        Debug.Assert(newCount == oldCount-1,
                            "The deferredResourceReference that was just validated should have also been removed from the list as part of the GetValue call.");
#endif 

                        // Adjust i to accomodate the removal of an entry 
                        i--; 
                    }
                } 
            }
        }

 
        /// 
        /// Called when the MergedDictionaries collection changes 
        ///  
        /// 
        ///  
        private void OnMergedDictionariesChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            List oldDictionaries = null;
            List newDictionaries = null; 
            ResourceDictionary mergedDictionary;
            ResourcesChangeInfo info; 
 
            if (e.Action != NotifyCollectionChangedAction.Reset)
            { 
                Invariant.Assert(
                    (e.NewItems != null && e.NewItems.Count > 0) ||
                    (e.OldItems != null && e.OldItems.Count > 0),
                    "The NotifyCollectionChanged event fired when no dictionaries were added or removed"); 

 
                // If one or more resource dictionaries were removed we 
                // need to remove the owners they were given by their
                // parent ResourceDictionary. 

                if (e.Action == NotifyCollectionChangedAction.Remove
                    || e.Action == NotifyCollectionChangedAction.Replace)
                { 
                    oldDictionaries = new List(e.OldItems.Count);
 
                    for (int i = 0; i < e.OldItems.Count; i++) 
                    {
                        mergedDictionary = (ResourceDictionary)e.OldItems[i]; 
                        oldDictionaries.Add(mergedDictionary);

                        RemoveParentOwners(mergedDictionary);
                    } 
                }
 
                // If one or more resource dictionaries were added to the merged 
                // dictionaries collection we need to send down the parent
                // ResourceDictionary's owners. 

                if (e.Action == NotifyCollectionChangedAction.Add
                    || e.Action == NotifyCollectionChangedAction.Replace)
                { 
                    newDictionaries = new List(e.NewItems.Count);
 
                    for (int i = 0; i < e.NewItems.Count; i++) 
                    {
                        mergedDictionary = (ResourceDictionary)e.NewItems[i]; 
                        newDictionaries.Add(mergedDictionary);

                        // If the merged dictionary HasImplicitStyle mark the outer dictionary the same.
                        if (!HasImplicitStyles && mergedDictionary.HasImplicitStyles) 
                        {
                            HasImplicitStyles = true; 
                        } 

                        // (03/12/08) Backing out the change for binary compat reasons. 
                        // If the parent dictionary is a theme dictionary mark the merged dictionary the same.
                        // if (IsThemeDictionary)
                        // {
                        //     mergedDictionary.IsThemeDictionary = true; 
                        // }
 
                        PropagateParentOwners(mergedDictionary); 
                    }
                } 

                info = new ResourcesChangeInfo(oldDictionaries, newDictionaries, false, false, null);
            }
            else 
            {
                // Case when MergedDictionary collection is cleared 
                info = ResourcesChangeInfo.CatastrophicDictionaryChangeInfo; 
            }
 
            // Notify the owners of the change and fire
            // invalidation if already initialized

            NotifyOwners(info); 
        }
 
        ///  
        /// Adds the given owner to all merged dictionaries of this ResourceDictionary
        ///  
        /// 
        private void AddOwnerToAllMergedDictionaries(DispatcherObject owner)
        {
            if (_mergedDictionaries != null) 
            {
                for (int i = 0; i < _mergedDictionaries.Count; i++) 
                { 
                    _mergedDictionaries[i].AddOwner(owner);
                } 
            }
        }

        ///  
        ///
        ///  
        ///  
        private void RemoveOwnerFromAllMergedDictionaries(DispatcherObject owner)
        { 
            if (_mergedDictionaries != null)
            {
                for (int i = 0; i < _mergedDictionaries.Count; i++)
                { 
                    _mergedDictionaries[i].RemoveOwner(owner);
                } 
            } 
        }
 
        /// 
        /// This sends down the owners of this ResourceDictionary into the given
        /// merged dictionary.  We do this because whenever a merged dictionary
        /// changes it should invalidate all owners of its parent ResourceDictionary. 
        ///
        /// Note that AddOwners throw if the merged dictionary already has one of the 
        /// parent's owners.  This implies that either we're putting a dictionary 
        /// into its own MergedDictionaries collection or we're putting the same
        /// dictionary into the collection twice, neither of which are legal. 
        /// 
        /// 
        private void PropagateParentOwners(ResourceDictionary mergedDictionary)
        { 
            if (_ownerFEs != null)
            { 
                Invariant.Assert(_ownerFEs.Count > 0); 

                if (mergedDictionary._ownerFEs == null) 
                {
                    mergedDictionary._ownerFEs = new List(_ownerFEs.Count);
                }
 
                for (int i = 0; i < _ownerFEs.Count; i++)
                { 
                    mergedDictionary.AddOwner(_ownerFEs[i]); 
                }
            } 

            if (_ownerFCEs != null)
            {
                Invariant.Assert(_ownerFCEs.Count > 0); 

                if (mergedDictionary._ownerFCEs == null) 
                { 
                    mergedDictionary._ownerFCEs = new List(_ownerFCEs.Count);
                } 

                for (int i = 0; i < _ownerFCEs.Count; i++)
                {
                    mergedDictionary.AddOwner(_ownerFCEs[i]); 
                }
            } 
 
            if (_ownerApps != null)
            { 
                Invariant.Assert(_ownerApps.Count > 0);

                if (mergedDictionary._ownerApps == null)
                { 
                    mergedDictionary._ownerApps = new List(_ownerApps.Count);
                } 
 
                for (int i = 0; i < _ownerApps.Count; i++)
                { 
                    mergedDictionary.AddOwner(_ownerApps[i]);
                }
            }
        } 

 
        ///  
        /// Removes the owners of this ResourceDictionary from the given
        /// merged dictionary.  The merged dictionary will be left with 
        /// whatever owners it had before being merged.
        /// 
        /// 
        internal void RemoveParentOwners(ResourceDictionary mergedDictionary) 
        {
            if (_ownerFEs != null) 
            { 
                Invariant.Assert(_ownerFEs.Count > 0);
 
                for (int i = 0; i < _ownerFEs.Count; i++)
                {
                    mergedDictionary.RemoveOwner(_ownerFEs[i]);
                } 
            }
 
            if (_ownerFCEs != null) 
            {
                Invariant.Assert(_ownerFCEs.Count > 0); 

                for (int i = 0; i < _ownerFCEs.Count; i++)
                {
                    mergedDictionary.RemoveOwner(_ownerFCEs[i]); 
                }
            } 
 
            if (_ownerApps != null)
            { 
                Invariant.Assert(_ownerApps.Count > 0);

                for (int i = 0; i < _ownerApps.Count; i++)
                { 
                    mergedDictionary.RemoveOwner(_ownerApps[i]);
                } 
            } 
        }
 
        private bool ContainsCycle(ResourceDictionary origin)
        {
            for (int i=0; i DeferredResourceReferences
        {
            get { return _deferredResourceReferences; }
        } 

        #endregion Properties 
 
        #region Enumeration
 
        /// 
        ///     Iterates the dictionary's entries, handling deferred content.
        /// 
        private class ResourceDictionaryEnumerator : IDictionaryEnumerator 
        {
            internal ResourceDictionaryEnumerator(ResourceDictionary owner) 
            { 
                _owner = owner;
                _keysEnumerator = _owner.Keys.GetEnumerator(); 
            }

            #region IEnumerator
 
            object IEnumerator.Current
            { 
                get 
                {
                    return ((IDictionaryEnumerator)this).Entry; 
                }
            }

            bool IEnumerator.MoveNext() 
            {
                return _keysEnumerator.MoveNext(); 
            } 

            void IEnumerator.Reset() 
            {
                _keysEnumerator.Reset();
            }
 
            #endregion
 
            #region IDictionaryEnumerator 

            DictionaryEntry IDictionaryEnumerator.Entry 
            {
                get
                {
                    object key = _keysEnumerator.Current; 
                    object value = _owner[key];
                    return new DictionaryEntry(key, value); 
                } 
            }
 
            object IDictionaryEnumerator.Key
            {
                get
                { 
                    return _keysEnumerator.Current;
                } 
            } 

            object IDictionaryEnumerator.Value 
            {
                get
                {
                    return _owner[_keysEnumerator.Current]; 
                }
            } 
 
            #endregion
 
            #region Data

            private ResourceDictionary _owner;
            private IEnumerator _keysEnumerator; 

            #endregion 
        } 

        ///  
        ///     Iterator for the dictionary's Values collection, handling deferred content.
        /// 
        private class ResourceValuesEnumerator : IEnumerator
        { 
            internal ResourceValuesEnumerator(ResourceDictionary owner)
            { 
                _owner = owner; 
                _keysEnumerator = _owner.Keys.GetEnumerator();
            } 

            #region IEnumerator

            object IEnumerator.Current 
            {
                get 
                { 
                    return _owner[_keysEnumerator.Current];
                } 
            }

            bool IEnumerator.MoveNext()
            { 
                return _keysEnumerator.MoveNext();
            } 
 
            void IEnumerator.Reset()
            { 
                _keysEnumerator.Reset();
            }

            #endregion 

            #region Data 
 
            private ResourceDictionary _owner;
            private IEnumerator _keysEnumerator; 

            #endregion
        }
 
        /// 
        ///     Represents the dictionary's Values collection, handling deferred content. 
        ///  
        private class ResourceValuesCollection : ICollection
        { 
            internal ResourceValuesCollection(ResourceDictionary owner)
            {
                _owner = owner;
            } 

            #region ICollection 
 
            int ICollection.Count
            { 
                get
                {
                    return _owner.Count;
                } 
            }
 
            bool ICollection.IsSynchronized 
            {
                get 
                {
                    return false;
                }
            } 

            object ICollection.SyncRoot 
            { 
                get
                { 
                    return this;
                }
            }
 
            void ICollection.CopyTo(Array array, int index)
            { 
                foreach(object key in _owner.Keys) 
                {
                    array.SetValue(_owner[key], index++); 
                }
            }

            IEnumerator IEnumerable.GetEnumerator() 
            {
                return new ResourceValuesEnumerator(_owner); 
            } 

            #endregion 

            #region Data

            private ResourceDictionary _owner; 

            #endregion 
        } 

        #endregion Enumeration 

        #region PrivateMethods

        // 
        //  This method
        //  1. Seals all the freezables/styles/templates that belong to this App/Theme/Style/Template ResourceDictionary 
        // 
        private void SealValues()
        { 
            Debug.Assert(IsThemeDictionary || _ownerApps != null || IsReadOnly, "This must be an App/Theme/Style/Template ResourceDictionary");

            foreach (object value in _baseDictionary.Values)
            { 
                SealValue(value);
            } 
        } 

        // 
        //  This method
        //  1. Sets the InheritanceContext of the value to the dictionary's principal owner
        //  2. Seals the freezable/style/template that is to be placed in an App/Theme/Style/Template ResourceDictionary
        // 
        private void SealValue(object value)
        { 
            if (_inheritanceContext != null) 
            {
                AddInheritanceContext(value); 
            }

            if (IsThemeDictionary || _ownerApps != null || IsReadOnly)
            { 
                // If the value is a ISealable then seal it
                StyleHelper.SealIfSealable(value); 
            } 
        }
 
        // add inheritance context to a value
        private void AddInheritanceContext(object value)
        {
            // The VisualBrush.Visual property is the "friendliest", i.e. the 
            // most likely to be accepted by the resource as FEs need to accept
            // being rooted by a VisualBrush. 
            // 
            // NOTE:  Freezable.Debug_VerifyContextIsValid() contains a special
            //        case to allow this with the VisualBrush.Visual property. 
            //        Changes made here will require updates in Freezable.cs
            if (_inheritanceContext.ProvideSelfAsInheritanceContext(value, VisualBrush.VisualProperty))
            {
                // if the assignment was successful, seal the value's InheritanceContext. 
                // This makes sure the resource always gets inheritance-related information
                // from its point of definition, not from its point of use. 
                DependencyObject doValue = value as DependencyObject; 
                if (doValue != null)
                { 
                    doValue.IsInheritanceContextSealed = true;
                }
            }
        } 

        // add inheritance context to all values that came from this dictionary 
        private void AddInheritanceContextToValues() 
        {
            foreach (object value in _baseDictionary.Values) 
            {
                AddInheritanceContext(value);
            }
        } 

        // remove inheritance context from a value, if it came from this dictionary 
        private void RemoveInheritanceContext(object value) 
        {
            DependencyObject doValue = value as DependencyObject; 
            if (doValue != null && _inheritanceContext != null &&
                doValue.IsInheritanceContextSealed &&
                doValue.InheritanceContext == _inheritanceContext)
            { 
                doValue.IsInheritanceContextSealed = false;
                _inheritanceContext.RemoveSelfAsInheritanceContext(doValue, VisualBrush.VisualProperty); 
            } 
        }
 
        // remove inheritance context from all values that came from this dictionary
        private void RemoveInheritanceContextFromValues()
        {
            foreach (object value in _baseDictionary.Values) 
            {
                RemoveInheritanceContext(value); 
            } 
        }
 
        private BamlRecordReader Reader
        {
            get
            { 
                if (_reader == null)
                { 
                    _reader = new BamlRecordReader(_bamlStream, _context); 
                    _reader.RootElement = _rootElement;
                    _reader.ComponentConnector = _rootElement as IComponentConnector; 
                }

                return _reader;
            } 
        }
 
        // Sets the HasImplicitStyles flag if the given key is of type Type. 
        private void UpdateHasImplicitStyles(object key)
        { 
            // Update the HasImplicitStyles flag
            if (!HasImplicitStyles && key is Type)
            {
                HasImplicitStyles = true; 
            }
        } 
 
        private bool IsInitialized
        { 
            get { return ReadPrivateFlag(PrivateFlags.IsInitialized); }
            set { WritePrivateFlag(PrivateFlags.IsInitialized, value); }
        }
 
        private bool IsInitializePending
        { 
            get { return ReadPrivateFlag(PrivateFlags.IsInitializePending); } 
            set { WritePrivateFlag(PrivateFlags.IsInitializePending, value); }
        } 

        private bool IsThemeDictionary
        {
            get { return ReadPrivateFlag(PrivateFlags.IsThemeDictionary); } 
            set { WritePrivateFlag(PrivateFlags.IsThemeDictionary, value); }
            // (03/12/08) Backing out the change for binary compat reasons. 
            // { 
            //     if (IsThemeDictionary != value)
            //     { 
            //        WritePrivateFlag(PrivateFlags.IsThemeDictionary, value);
            //
            //         if (_mergedDictionaries != null)
            //         { 
            //             for (int i=0; i<_mergedDictionaries.Count; i++)
            //             { 
            //                 _mergedDictionaries[i].IsThemeDictionary = value; 
            //             }
            //         } 
            //     }
            // }
        }
 
        internal bool HasImplicitStyles
        { 
            get { return ReadPrivateFlag(PrivateFlags.HasImplicitStyles); } 
            set { WritePrivateFlag(PrivateFlags.HasImplicitStyles, value); }
        } 

        internal bool CanBeAccessedAcrossThreads
        {
            get { return ReadPrivateFlag(PrivateFlags.CanBeAccessedAcrossThreads); } 
            set { WritePrivateFlag(PrivateFlags.CanBeAccessedAcrossThreads, value); }
        } 
 
        private void WritePrivateFlag(PrivateFlags bit, bool value)
        { 
            if (value)
            {
                _flags |= bit;
            } 
            else
            { 
                _flags &= ~bit; 
            }
        } 

        private bool ReadPrivateFlag(PrivateFlags bit)
        {
            return (_flags & bit) != 0; 
        }
 
        #endregion PrivateMethods 

        #region PrivateDataStructures 

        private enum PrivateFlags : byte
        {
            IsInitialized               = 0x01, 
            IsInitializePending         = 0x02,
            IsReadOnly                  = 0x04, 
            IsThemeDictionary           = 0x08, 
            HasImplicitStyles           = 0x10,
            CanBeAccessedAcrossThreads  = 0x20, 

            // Unused bit = 0x40,
            // Unused bit = 0x80,
        } 

        #endregion PrivateDataStructures 
 
        #region Data
 
        private Hashtable                                 _baseDictionary = null;
        private List                    _ownerFEs = null;
        private List             _ownerFCEs = null;
        private List                         _ownerApps = null; 
        private List           _deferredResourceReferences = null;
        private ObservableCollection  _mergedDictionaries = null; 
        private Uri                                       _source = null; 
        private Uri                                       _baseUri = null;
        private PrivateFlags                              _flags = 0; 

        // Buffer that contains deferable content.  This may be null if a stream was passed
        // instead of a buffer.  If a buffer was passed, then a memory stream is made on the buffer
        private byte[]          _buffer; 

        // Persistent Stream that contains values. 
        private Stream          _bamlStream; 

        // Start position in the stream where the first value record is located.  All offsets for 
        // the keys are relative to this position.
        private Int64           _startPosition;

        // Size of the delay loaded content, which only includes the value section and not the keys. 
        private Int32           _contentSize;
 
        // Parser context that is in effect when the Defer load block is encountered in the baml 
        // stream.  This should include all information, types, properties, etc that is needed to
        // parse ALL of the values in the defer load section. 
        private ParserContext   _context;

        // The root element at the time the deferred content information was given to the dictionary.
        private object          _rootElement; 

        // Baml reader associated with this chunk of defer loaded content. 
        private BamlRecordReader _reader; 

        // The number of keys that correspond to deferred content. When this reaches 0, 
        // the stream can be closed.
        private int             _numDefer;

        // The object that becomes the InheritanceContext of all eligible 
        // values in the dictionary - typically the principal owner of the dictionary.
        private DependencyObject _inheritanceContext; 
 
        XamlObjectIds _contextXamlObjectIds  = new XamlObjectIds();
 

        #endregion Data
    }
} 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
/****************************************************************************\ 
*
* File: ResourceDictionary.cs
*
*  Dictionary that holds Resources for Framework components. 
*
* Copyright (C) 2003 by Microsoft Corporation.  All rights reserved. 
* 
\***************************************************************************/
 
using System;
using System.IO;
using System.Net;
using System.Collections; 
using System.Collections.Generic;
using System.Collections.ObjectModel; 
using System.Collections.Specialized; 
using System.Diagnostics;
using System.ComponentModel; 
using System.Windows.Threading;
using System.Windows.Media;
using System.Windows.Markup;
using System.IO.Packaging; 
using MS.Internal.IO.Packaging;         // for PackageCacheEntry
using System.Globalization; 
using System.Windows.Navigation; 

using MS.Internal; 
using MS.Internal.Utility;
using MS.Internal.AppModel;
using MS.Utility;
 
namespace System.Windows
{ 
    ///  
    ///     Dictionary that holds Resources for Framework components.
    ///  
    [Localizability(LocalizationCategory.Ignore)]
    public class ResourceDictionary : IDictionary, INameScope, ISupportInitialize, IUriContext
    {
        #region Constructor 

        ///  
        ///     Constructor for ResourceDictionary 
        /// 
        public ResourceDictionary() 
        {
            _baseDictionary = new Hashtable();
            IsThemeDictionary = SystemResources.IsSystemResourcesParsing;
        } 

        #endregion Constructor 
 
        #region PublicAPIs
 
        /// 
        ///     Copies the dictionary's elements to a one-dimensional
        ///     Array instance at the specified index.
        ///  
        /// 
        ///     The one-dimensional Array that is the destination of the 
        ///     DictionaryEntry objects copied from Hashtable. The Array 
        ///     must have zero-based indexing.
        ///  
        /// 
        ///     The zero-based index in array at which copying begins.
        /// 
        public void CopyTo(DictionaryEntry[] array, int arrayIndex) 
        {
            if (CanBeAccessedAcrossThreads) 
            { 
                lock(((ICollection)this).SyncRoot)
                { 
                    CopyToWithoutLock(array, arrayIndex);
                }
            }
            else 
            {
                CopyToWithoutLock(array, arrayIndex); 
            } 
        }
 
        private void CopyToWithoutLock(DictionaryEntry[] array, int arrayIndex)
        {
            if (array == null)
            { 
                throw new ArgumentNullException("array");
            } 
 
            _baseDictionary.CopyTo(array, arrayIndex);
 
            int length = arrayIndex + Count;
            for (int i = arrayIndex; i < length; i++)
            {
                DictionaryEntry entry = array[i]; 
                object value = entry.Value;
                bool canCache; 
                if (RealizeDeferContent(entry.Key, ref value, out canCache)) 
                {
                    entry.Value = value; 
                }
            }
        }
 
        ///
        ///     List of ResourceDictionaries merged into this Resource Dictionary 
        /// 
        public Collection MergedDictionaries
        { 
            get
            {
                if (_mergedDictionaries == null)
                { 
                    _mergedDictionaries = new ResourceDictionaryCollection(this);
                    _mergedDictionaries.CollectionChanged += OnMergedDictionariesChanged; 
                } 

                return _mergedDictionaries; 
            }
        }

        /// 
        ///     Uri to load this resource from, it will clear the current state of the ResourceDictionary
        /// 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 
        public Uri Source
        { 
            get
            {
                return _source;
            } 
            set
            { 
                if (value == null || String.IsNullOrEmpty(value.OriginalString)) 
                {
                    throw new ArgumentException(SR.Get(SRID.ResourceDictionaryLoadFromFailure, value == null ? "''" : value.ToString())); 
                }

                _source = value;
 
                Clear();
 
                Uri uri = BindUriHelper.GetResolvedUri(_baseUri, _source); 
                WebRequest request = WpfWebRequestHelper.CreateRequest(uri);
                WpfWebRequestHelper.ConfigCachePolicy(request, false); 
                ContentType contentType;
                Stream s = WpfWebRequestHelper.GetResponseStream(request, out contentType);

                // MimeObjectFactory.GetObjectAndCloseStream will try to find the object converter basing on the mime type. 
                // It can be a [....]/async converter. It's the converter's responsiblity to close the stream.
                // If it fails to find a convert, this call will return null. 
                XamlReader asyncObjectConverter; 
                ResourceDictionary loadedRD = MimeObjectFactory.GetObjectAndCloseStream(s, contentType, uri, false, false, false /*allowAsync*/, false /*isJournalNavigation*/, out asyncObjectConverter)
                                            as ResourceDictionary; 

                if (loadedRD == null)
                {
                    throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryLoadFromFailure, _source.ToString())); 
                }
 
                // ReferenceCopy all the key-value pairs in the _baseDictionary 
                _baseDictionary = loadedRD._baseDictionary;
 
                // ReferenceCopy all the entries in the MergedDictionaries collection
                _mergedDictionaries = loadedRD._mergedDictionaries;

                // ReferenceCopy all of the deferred content state 
                _buffer = loadedRD._buffer;
                _bamlStream = loadedRD._bamlStream; 
                _startPosition = loadedRD._startPosition; 
                _contentSize = loadedRD._contentSize;
                _context = loadedRD._context; 
                _rootElement = loadedRD._rootElement;
                _reader = loadedRD._reader;
                _numDefer = loadedRD._numDefer;
 
                // Copy over the HasImplicitStyles flag
                HasImplicitStyles = loadedRD.HasImplicitStyles; 
 
                if (!IsInitializePending)
                { 
                    // Fire Invalidations for the changes made by asigning a new Source
                    NotifyOwners(new ResourcesChangeInfo(null, this));
                }
            } 
        }
 
        #region INameScope 
        /// 
        /// Registers the name - element combination 
        /// 
        /// name of the element
        /// Element where name is defined
        public void RegisterName(string name, object scopedElement) 
        {
            throw new NotSupportedException(SR.Get(SRID.NamesNotSupportedInsideResourceDictionary)); 
        } 

        ///  
        /// Unregisters the name - element combination
        /// 
        /// Name of the element
        public void UnregisterName(string name) 
        {
            // Do Nothing as Names cannot be registered on ResourceDictionary 
        } 

        ///  
        /// Find the element given name
        /// 
        /// Name of the element
        /// null always 
        public object FindName(string name)
        { 
            return null; 
        }
 
        #endregion INameScope

        #region IUriContext
 
        /// 
        ///     Accessor for the base uri of the ResourceDictionary 
        ///  
        Uri IUriContext.BaseUri
        { 
            get
            {
                return  _baseUri;
            } 
            set
            { 
                _baseUri = value; 
            }
        } 

        #endregion IUriContext

        #endregion PublicAPIs 

        #region IDictionary 
 
        /// 
        ///     Gets a value indicating whether the IDictionary has a fixed size. 
        /// 
        public bool IsFixedSize
        {
            get { return _baseDictionary.IsFixedSize; } 
        }
 
        ///  
        ///     Gets a value indicating whether the ResourceDictionary is read-only.
        ///  
        public bool IsReadOnly
        {
            get { return ReadPrivateFlag(PrivateFlags.IsReadOnly); }
            internal set 
            {
                WritePrivateFlag(PrivateFlags.IsReadOnly, value); 
 
                if (value == true)
                { 
                    // Seal all the styles and templates in this dictionary
                    SealValues();
                }
 
                // Set all the merged resource dictionaries as ReadOnly
                if (_mergedDictionaries != null) 
                { 
                    for (int i = 0; i < _mergedDictionaries.Count; i++)
                    { 
                        _mergedDictionaries[i].IsReadOnly = value;
                    }
                }
            } 
        }
 
        ///  
        ///     Gets or sets the value associated with the specified key.
        ///  
        /// 
        ///     Fire Invalidations only for changes made after the Init Phase
        ///     If the key is not found on this ResourceDictionary, it will look on any MergedDictionaries for it
        ///  
        public object this[object key]
        { 
            get 
            {
                bool canCache; 
                return GetValue(key, out canCache);
            }

            set 
            {
                // Seal styles and templates within App and Theme dictionary 
                SealValue(value); 

                if (CanBeAccessedAcrossThreads) 
                {
                    lock(((ICollection)this).SyncRoot)
                    {
                        SetValueWithoutLock(key, value); 
                    }
                } 
                else 
                {
                    SetValueWithoutLock(key, value); 
                }
            }
        }
 
        private void SetValueWithoutLock(object key, object value)
        { 
            if (IsReadOnly) 
            {
                throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryIsReadOnly)); 
            }

            object oldValue = _baseDictionary[key];
 
            if (oldValue != value)
            { 
                // We need to validate all the deferred references that refer 
                // to the old resource before we overwrite it.
                ValidateDeferredResourceReferences(key); 

                if( TraceResourceDictionary.IsEnabled )
                {
                    TraceResourceDictionary.Trace( TraceEventType.Start, 
                                                   TraceResourceDictionary.AddResource,
                                                   this, 
                                                   key, 
                                                   value );
                } 


                _baseDictionary[key] = value;
 
                // Update the HasImplicitStyles flag
                UpdateHasImplicitStyles(key); 
 
                // Notify owners of the change and fire invalidate if already initialized
                NotifyOwners(new ResourcesChangeInfo(key)); 

                if( TraceResourceDictionary.IsEnabled )
                {
                    TraceResourceDictionary.Trace( 
                                                  TraceEventType.Stop,
                                                  TraceResourceDictionary.AddResource, 
                                                  this, 
                                                  key,
                                                  value ); 
                }


            } 
        }
 
        internal object GetValue(object key, out bool canCache) 
        {
            if (CanBeAccessedAcrossThreads) 
            {
                lock(((ICollection)this).SyncRoot)
                {
                    return GetValueWithoutLock(key, out canCache); 
                }
            } 
            else 
            {
                return GetValueWithoutLock(key, out canCache); 
            }
        }

        private object GetValueWithoutLock(object key, out bool canCache) 
        {
            object value = _baseDictionary[key]; 
            if (value != null) 
            {
                RealizeDeferContent(key, ref value, out canCache); 
            }
            else
            {
                canCache = true; 

                //Search for the value in the Merged Dictionaries 
                if (_mergedDictionaries != null) 
                {
                    for (int i = MergedDictionaries.Count - 1; (i > -1); i--) 
                    {
                        // Note that MergedDictionaries collection can also contain null values
                        ResourceDictionary mergedDictionary = MergedDictionaries[i];
                        if (mergedDictionary != null) 
                        {
                            value = mergedDictionary.GetValue(key, out canCache); 
                            if (value != null) 
                            {
                                break; 
                            }
                        }
                    }
                } 
            }
 
            return value; 
        }
 
        // Gets the type of the value stored at the given key
        internal Type GetValueType(object key, out bool found)
        {
            found = false; 
            Type valueType = null;
 
            object value = _baseDictionary[key]; 
            if (value != null)
            { 
                found = true;

                IBamlDictionaryKey keyRecord = value as IBamlDictionaryKey;
                if (keyRecord != null) 
                {
                    Debug.Assert(_numDefer > 0, "The stream was closed before all deferred content was loaded."); 
 
                    Int32 valuePosition = keyRecord.ValuePosition;
 
                    BamlRecordReader previousRecordReader = _context.BamlReader;
                    BamlRecordReader reader = Reader;
                    _context.BamlReader = reader;
 
                    try
                    { 
                        // Remember the starting stream position, so that it can be repositioned 
                        // after the read to handle recursive operations on the same stream.
                        Int64 startPosition = _bamlStream.Position; 

                        _bamlStream.Position = _startPosition + valuePosition;
                        BamlElementStartRecord bamlElementStartRecord = (BamlElementStartRecord)reader.GetNextRecord();
                        valueType = reader.MapTable.GetTypeFromId(bamlElementStartRecord.TypeId); 

                        _bamlStream.Position = startPosition; 
                    } 
                    finally
                    { 
                        // Restore the previousRecordReader into the context
                        _context.BamlReader = previousRecordReader;
                    }
                } 
                else
                { 
                    valueType = value.GetType(); 
                }
 
            }
            else
            {
                // Search for the value in the Merged Dictionaries 
                if (_mergedDictionaries != null)
                { 
                    for (int i = MergedDictionaries.Count - 1; (i > -1); i--) 
                    {
                        // Note that MergedDictionaries collection can also contain null values 
                        ResourceDictionary mergedDictionary = MergedDictionaries[i];
                        if (mergedDictionary != null)
                        {
                            valueType = mergedDictionary.GetValueType(key, out found); 
                            if (found)
                            { 
                                break; 
                            }
                        } 
                    }
                }
            }
 
            return valueType;
        } 
 
        /// 
        ///     Gets a copy of the ICollection containing the keys of the IDictionary. 
        /// 
        public ICollection Keys
        {
            get 
            {
                object[] keysCollection = new object[Count]; 
                _baseDictionary.Keys.CopyTo(keysCollection, 0); 
                return keysCollection;
            } 
        }

        /// 
        ///     Gets an ICollection containing the values in the Hashtable 
        /// 
        /// An ICollection containing the values in the Hashtable 
        public ICollection Values 
        {
            get 
            {
                return new ResourceValuesCollection(this);
            }
        } 

        ///  
        ///     Adds an entry 
        /// 
        ///  
        ///     Fire Invalidations only for changes made after the Init Phase
        /// 
        public void Add(object key, object value)
        { 
            // Seal styles and templates within App and Theme dictionary
            SealValue(value); 
 
            if (CanBeAccessedAcrossThreads)
            { 
                lock(((ICollection)this).SyncRoot)
                {
                    AddWithoutLock(key, value);
                } 
            }
            else 
            { 
                AddWithoutLock(key, value);
            } 

        }

        private void AddWithoutLock(object key, object value) 
        {
            if (IsReadOnly) 
            { 
                throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryIsReadOnly));
            } 

            if( TraceResourceDictionary.IsEnabled )
            {
                TraceResourceDictionary.Trace( TraceEventType.Start, 
                                               TraceResourceDictionary.AddResource,
                                               this, 
                                               key, 
                                               value );
            } 


            _baseDictionary.Add(key, value);
 
            // Update the HasImplicitKey flag
            UpdateHasImplicitStyles(key); 
 
            // Notify owners of the change and fire invalidate if already initialized
            NotifyOwners(new ResourcesChangeInfo(key)); 

            if( TraceResourceDictionary.IsEnabled )
            {
                TraceResourceDictionary.Trace( TraceEventType.Stop, 
                                               TraceResourceDictionary.AddResource,
                                               this, 
                                               key, 
                                               value );
            } 

        }

        ///  
        ///     Removes all elements from the IDictionary.
        ///  
        public void Clear() 
        {
            if (CanBeAccessedAcrossThreads) 
            {
                lock(((ICollection)this).SyncRoot)
                {
                    ClearWithoutLock(); 
                }
            } 
            else 
            {
                ClearWithoutLock(); 
            }
        }

        private void ClearWithoutLock() 
        {
            if (IsReadOnly) 
            { 
                throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryIsReadOnly));
            } 

            if (Count > 0)
            {
                // We need to validate all the deferred references that refer 
                // to the old resource before we clear it.
                ValidateDeferredResourceReferences(null); 
 
                // remove inheritance context from all values that got it from
                // this dictionary 
                RemoveInheritanceContextFromValues();

                _baseDictionary.Clear();
 
                // Notify owners of the change and fire invalidate if already initialized
                NotifyOwners(ResourcesChangeInfo.CatastrophicDictionaryChangeInfo); 
            } 
        }
 
        /// 
        ///     Determines whether the IDictionary contains an element with the specified key.
        ///     if the Key is not contained in this ResourceDictionary, it will check in the MergedDictionaries too
        ///  
        public bool Contains(object key)
        { 
            bool result = _baseDictionary.Contains(key); 

            //Search for the value in the Merged Dictionaries 
            if (_mergedDictionaries != null)
            {
                for (int i = MergedDictionaries.Count - 1; (i > -1) && !result; i--)
                { 
                    // Note that MergedDictionaries collection can also contain null values
                    ResourceDictionary mergedDictionary = MergedDictionaries[i]; 
                    if (mergedDictionary != null) 
                    {
                        result = mergedDictionary.Contains(key); 
                    }
                }
            }
            return result; 
        }
 
        ///  
        ///     Determines whether the IDictionary contains a BamlObjectFactory against the specified key.
        ///     if the Key is not contained in this ResourceDictionary, it will check in the MergedDictionaries too 
        /// 
        internal bool ContainsBamlObjectFactory(object key)
        {
            return GetBamlObjectFactory(key) != null; 
        }
 
        ///  
        ///     Retrieves an IBamlDictionaryKey from the IDictionary using the specified key.
        ///     If the Key is not contained in this ResourceDictionary, it will check in the MergedDictionaries too 
        /// 
        internal IBamlDictionaryKey GetBamlObjectFactory(object key)
        {
            if (_baseDictionary.Contains(key)) 
            {
                return _baseDictionary[key] as IBamlDictionaryKey; 
            } 

            //Search for the value in the Merged Dictionaries 
            if (_mergedDictionaries != null)
            {
                for (int i = MergedDictionaries.Count - 1; i > -1; i--)
                { 
                    // Note that MergedDictionaries collection can also contain null values
                    ResourceDictionary mergedDictionary = MergedDictionaries[i]; 
                    if (mergedDictionary != null) 
                    {
                        IBamlDictionaryKey keyRecord = mergedDictionary.GetBamlObjectFactory(key); 
                        if (keyRecord != null)
                        {
                            return keyRecord;
                        } 
                    }
                } 
            } 

            return null; 
        }

        /// 
        ///     Returns an IDictionaryEnumerator that can iterate through the Hashtable 
        /// 
        /// An IDictionaryEnumerator for the Hashtable 
        public IDictionaryEnumerator GetEnumerator() 
        {
            return new ResourceDictionaryEnumerator(this); 
        }

        /// 
        ///     Removes an entry 
        /// 
        ///  
        ///     Fire Invalidations only for changes made after the Init Phase 
        /// 
        public void Remove(object key) 
        {
            if (CanBeAccessedAcrossThreads)
            {
                lock(((ICollection)this).SyncRoot) 
                {
                    RemoveWithoutLock(key); 
                } 
            }
            else 
            {
                RemoveWithoutLock(key);
            }
        } 

        private void RemoveWithoutLock(object key) 
        { 
            if (IsReadOnly)
            { 
                throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryIsReadOnly));
            }

            // We need to validate all the deferred references that refer 
            // to the old resource before we remove it.
            ValidateDeferredResourceReferences(key); 
 
            // remove the inheritance context from the value, if it came from
            // this dictionary 
            RemoveInheritanceContext(_baseDictionary[key]);

            _baseDictionary.Remove(key);
 
            // Notify owners of the change and fire invalidate if already initialized
            NotifyOwners(new ResourcesChangeInfo(key)); 
        } 

        #endregion IDictionary 

        #region ICollection

        ///  
        ///     Gets the number of elements contained in the ICollection.
        ///  
        public int Count 
        {
            get { return _baseDictionary.Count; } 
        }

        /// 
        ///     Gets a value indicating whether access to the ICollection is synchronized (thread-safe). 
        /// 
        bool ICollection.IsSynchronized 
        { 
            get { return _baseDictionary.IsSynchronized; }
        } 

        /// 
        ///     Gets an object that can be used to synchronize access to the ICollection.
        ///  
        object ICollection.SyncRoot
        { 
            get 
            {
                if (CanBeAccessedAcrossThreads) 
                {
                    // Notice that we are acquiring the ThemeDictionaryLock. This
                    // is because the _parserContext used for template expansion
                    // shares data-structures such as the BamlMapTable and 
                    // XamlTypeMapper with the parent ParserContext that was used
                    // to build the template in the first place. So if this template 
                    // is from the App.Resources then the ParserContext that is used for 
                    // loading deferred content in the app dictionary and the
                    // _parserContext used to load template content share the same 
                    // instances of BamlMapTable and XamlTypeMapper. Hence we need to
                    // make sure that we lock on the same object inorder to serialize
                    // access to these data-structures in multi-threaded scenarios.
                    // Look at comment in Frameworktemplate.LoadContent to understand 
                    // why we use the ThemeDictionaryLock for template expansion.
 
                    return SystemResources.ThemeDictionaryLock; 
                }
                else 
                {
                    return _baseDictionary.SyncRoot;
                }
            } 
        }
 
        ///  
        ///     Copies the dictionary's elements to a one-dimensional
        ///     Array instance at the specified index. 
        /// 
        /// 
        ///     The one-dimensional Array that is the destination of the
        ///     DictionaryEntry objects copied from Hashtable. The Array 
        ///     must have zero-based indexing.
        ///  
        ///  
        ///     The zero-based index in array at which copying begins.
        ///  
        void ICollection.CopyTo(Array array, int arrayIndex)
        {
            CopyTo(array as DictionaryEntry[], arrayIndex);
        } 

        #endregion ICollection 
 
        #region IEnumerable
 
        IEnumerator IEnumerable.GetEnumerator()
        {
            return ((IDictionary)this).GetEnumerator();
        } 

        #endregion IEnumerable 
 
        #region ISupportInitialize
 
        /// 
        ///     Mark the begining of the Init phase
        /// 
        ///  
        ///     BeginInit and EndInit follow a transaction model. BeginInit marks the
        ///     dictionary uninitialized and EndInit marks it initialized. 
        ///  
        public void BeginInit()
        { 
            // Nested BeginInits on the same instance aren't permitted
            if (IsInitializePending)
            {
                throw new InvalidOperationException(SR.Get(SRID.NestedBeginInitNotSupported)); 
            }
 
            IsInitializePending = true; 
            IsInitialized = false;
        } 

        /// 
        ///     Fire Invalidation at the end of Init phase
        ///  
        /// 
        ///     BeginInit and EndInit follow a transaction model. BeginInit marks the 
        ///     dictionary uninitialized and EndInit marks it initialized. 
        /// 
        public void EndInit() 
        {
            // EndInit without a BeginInit isn't permitted
            if (!IsInitializePending)
            { 
                throw new InvalidOperationException(SR.Get(SRID.EndInitWithoutBeginInitNotSupported));
            } 
            Debug.Assert(IsInitialized == false, "Dictionary should not be initialized when EndInit is called"); 

            IsInitializePending = false; 
            IsInitialized = true;

            // Fire Invalidations collectively for all changes made during the Init Phase
            NotifyOwners(new ResourcesChangeInfo(null, this)); 
        }
 
        #endregion ISupportInitialize 

        #region DeferContent 

        private bool CanCache(IBamlDictionaryKey keyRecord, object value)
        {
            if (keyRecord.SharedSet) 
            {
                return keyRecord.Shared; 
            } 
            else
            { 
                return true;
            }
        }
 
        private bool RealizeDeferContent(ref object value)
        { 
            bool canCache; 
            return RealizeDeferContent(null, ref value, out canCache);
        } 

        private bool RealizeDeferContent(object key, ref object value, out bool canCache)
        {
            IBamlDictionaryKey keyRecord = value as IBamlDictionaryKey; 
            if (keyRecord != null)
            { 
                Debug.Assert(_numDefer > 0, "The stream was closed before all deferred content was loaded."); 

                Int32 valuePosition = keyRecord.ValuePosition; 

                // Store the StaticResources list for the current key record into the parserContext so that
                // StaticResourceId records within the current value can use it for lookup.
                _context.StaticResourcesStack.Add(keyRecord.StaticResourceValues); 
                try
                { 
                    if( TraceResourceDictionary.IsEnabled ) 
                    {
                        TraceResourceDictionary.Trace( 
                            TraceEventType.Start,
                            TraceResourceDictionary.RealizeDeferContent,
                            this,
                            key, 
                            value );
                    } 
 
                    value = CreateObject(valuePosition, key);
 
                }
                finally
                {
                    if( TraceResourceDictionary.IsEnabled ) 
                    {
                        TraceResourceDictionary.Trace( 
                            TraceEventType.Stop, 
                            TraceResourceDictionary.RealizeDeferContent,
                            this, 
                            key,
                            value );
                    }
 
                    _context.StaticResourcesStack.RemoveAt(_context.StaticResourcesStack.Count-1);
                } 
 
                if (key != null)
                { 
                    canCache = CanCache(keyRecord, value);
                    if (canCache)
                    {
                        // Seal styles and templates within App and Theme dictionary 
                        SealValue(value);
 
                        _numDefer--; 
                        _baseDictionary[key] = value;
 
                        if (_numDefer == 0)
                        {
                            _reader = null;
                            _context = null; 

                            // Only close the stream if it was a Memory Stream 
                            // built over our buffer. 
                            if(null != _buffer)
                            { 
                                _bamlStream.Close();
                                _bamlStream = null;
                                _buffer = null;
                            } 
                        }
                    } 
                } 
                else
                { 
                    canCache = true;
                }

                return true; /* Defer content */ 
            }
 
            canCache = true; 
            return false;   /* Not defer content */
        } 

        /// 
        ///  Add a byte array that contains deferable content
        ///  
        internal void SetDeferableContent(
            byte[]                          buffer, 
            ParserContext                   context, 
            object                          rootElement,
            ArrayList                       keyCollection, 
            List                  staticResourceValuesList)
        {
            if (buffer == null)
            { 
                throw new ArgumentNullException("buffer");
            } 
            if (context == null) 
            {
                throw new ArgumentNullException("context"); 
            }
            if (keyCollection == null)
            {
                throw new ArgumentNullException("keyCollection"); 
            }
 
            // If we already have the Source set then we can ignore 
            // this deferable content section
            if (_source == null) 
            {
                if (_context == null)
                {
                    _buffer = buffer; 
                    _bamlStream = new MemoryStream(buffer);
                    _startPosition = 0; 
                    _contentSize = buffer.Length; 
                    _context = context.Clone();
                    _rootElement = rootElement; 

                    SetKeys(keyCollection, staticResourceValuesList, context);
                }
                else 
                {
                    throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryDuplicateDeferredContent)); 
                } 
            }
            else if (keyCollection.Count > 0) 
            {
                throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryDeferredContentFailure));
            }
        } 

 
        ///  
        ///  Add a stream that contains deferable content
        ///  
        internal void SetDeferableContent(
            Stream                          bamlStream,
            Int64                           startPosition,
            Int32                           contentSize, 
            ParserContext                   context,
            object                          rootElement, 
            ArrayList                       keyCollection, 
            List                  staticResourceValuesList)
        { 
            if (bamlStream == null)
            {
                throw new ArgumentNullException("bamlStream");
            } 
            if (!bamlStream.CanRead)
            { 
                throw new ArgumentException(SR.Get(SRID.InputStreamMustBeReadable,"bamlStream")); 
            }
            if (context == null) 
            {
                throw new ArgumentNullException("context");
            }
            if (keyCollection == null) 
            {
                throw new ArgumentNullException("keyCollection"); 
            } 
            if (startPosition < 0)
            { 
                throw new ArgumentOutOfRangeException("startPosition");
            }
            if (contentSize < 0)
            { 
                throw new ArgumentOutOfRangeException("contentSize");
            } 
 
            // If we already have the Source set then we can ignore
            // this deferable content section 
            if (_source == null)
            {
                if (_context == null)
                { 
                    _bamlStream = bamlStream;
                    _startPosition = startPosition; 
                    _contentSize = contentSize; 
                    _context = context.Clone();
 
                    // We need to clear the Journal bit, because we know we won't be able to honor it correctly.
                    // Journaling journals the properties in the logical tree, so doesn't journal properties in the
                    // Template/Resources.  This shouldn't be hard-coded here, but is an internal solution for V1.
                    _context.SkipJournaledProperties = false; 
                    _rootElement = rootElement;
 
                    SetKeys(keyCollection, staticResourceValuesList, context); 
                }
                else 
                {
                    throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryDuplicateDeferredContent));
                }
            } 
            else if (keyCollection.Count > 0)
            { 
                throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryDeferredContentFailure)); 
            }
        } 

        private void SetKeys(
            ArrayList      keyCollection,
            List staticResourceValuesList, 
            ParserContext  context)
        { 
            _numDefer = keyCollection.Count; 

            // Use the array Count property to avoid range checking inside the loop 
            for (int i = 0; i < keyCollection.Count; i++)
            {
                IBamlDictionaryKey keyRecord = keyCollection[i] as IBamlDictionaryKey;
                if (keyRecord != null) 
                {
                    SetStaticResources(staticResourceValuesList[i], context); 
                    keyRecord.StaticResourceValues = staticResourceValuesList[i]; 

                    // Update the HasImplicitStyles flag 
                    UpdateHasImplicitStyles(keyRecord.KeyObject);

                    _baseDictionary.Add(keyRecord.KeyObject, keyRecord);
 
                    if( TraceResourceDictionary.IsEnabled )
                    { 
                        TraceResourceDictionary.TraceActivityItem( 
                            TraceResourceDictionary.SetKey,
                            this, 
                            keyRecord.KeyObject );
                    }

                } 
                else
                { 
                    throw new ArgumentException(SR.Get(SRID.KeyCollectionHasInvalidKey)); 
                }
            } 

            // Notify owners of the HasImplicitStyles flag value
            // but there is not need to fire an invalidation.
            NotifyOwners(new ResourcesChangeInfo(null, this)); 

            // Get the XamlObjectIds (Name, Uid, and Key) that are currently in our context. 
            // When we realize tese resources, we'll pass in that information, so that they 
            // can generate good exception messages.
 
            Type objectType;
            XamlParseException.GetObjectContext(context.BamlReader,
                                                null, // currentObjectIdentifiers
                                                _contextXamlObjectIds, 
                                                out objectType );
 
        } 

        private void SetStaticResources(object[] staticResourceValues, ParserContext context) 
        {
            if (staticResourceValues != null && staticResourceValues.Length > 0)
            {
                bool inDeferredSection = context.InDeferredSection; 

                for (int i=0; i(1);
                } 
                else if (_ownerFEs.Contains(fe) && ContainsCycle(this))
                { 
                    throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryInvalidMergedDictionary)); 
                }
 
                // Propagate the HasImplicitStyles flag to the new owner
                if (HasImplicitStyles)
                {
                    fe.ShouldLookupImplicitStyles = true; 
                }
 
                _ownerFEs.Add(fe); 
            }
            else 
            {
                FrameworkContentElement fce = owner as FrameworkContentElement;
                if (fce != null)
                { 
                    if (_ownerFCEs == null)
                    { 
                        _ownerFCEs = new List(1); 
                    }
                    else if (_ownerFCEs.Contains(fce) && ContainsCycle(this)) 
                    {
                        throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryInvalidMergedDictionary));
                    }
 
                    // Propagate the HasImplicitStyles flag to the new owner
                    if (HasImplicitStyles) 
                    { 
                        fce.ShouldLookupImplicitStyles = true;
                    } 

                    _ownerFCEs.Add(fce);
                }
                else 
                {
                    Application app = owner as Application; 
                    if (app != null) 
                    {
                        if (_ownerApps == null) 
                        {
                            _ownerApps = new List(1);
                        }
                        else if (_ownerApps.Contains(app) && ContainsCycle(this)) 
                        {
                            throw new InvalidOperationException(SR.Get(SRID.ResourceDictionaryInvalidMergedDictionary)); 
                        } 

                        // Propagate the HasImplicitStyles flag to the new owner 
                        if (HasImplicitStyles)
                        {
                            app.HasImplicitStylesInResources = true;
                        } 

                        _ownerApps.Add(app); 
 
                        // An Application ResourceDictionary can be accessed across threads
                        CanBeAccessedAcrossThreads = true; 

                        // Seal all the styles and templates in this app dictionary
                        SealValues();
                    } 
                }
            } 
 
            AddOwnerToAllMergedDictionaries(owner);
 
            // This dictionary will be marked initialized if no one has called BeginInit on it.
            // This is done now because having an owner is like a parenting operation for the dictionary.
            TryInitialize();
        } 

        // Remove an owner for this dictionary 
        internal void RemoveOwner(DispatcherObject owner) 
        {
            FrameworkElement fe = owner as FrameworkElement; 
            if (fe != null)
            {
                if (_ownerFEs != null)
                { 
                    _ownerFEs.Remove(fe);
 
                    if (_ownerFEs.Count == 0) 
                    {
                        _ownerFEs = null; 
                    }
                }
            }
            else 
            {
                FrameworkContentElement fce = owner as FrameworkContentElement; 
                if (fce != null) 
                {
                    if (_ownerFCEs != null) 
                    {
                        _ownerFCEs.Remove(fce);

                        if (_ownerFCEs.Count == 0) 
                        {
                            _ownerFCEs = null; 
                        } 
                    }
                } 
                else
                {
                    Application app = owner as Application;
                    if (app != null) 
                    {
                        if (_ownerApps != null) 
                        { 
                            _ownerApps.Remove(app);
 
                            if (_ownerApps.Count == 0)
                            {
                                _ownerApps = null;
                            } 
                        }
                    } 
                } 
            }
 
            RemoveOwnerFromAllMergedDictionaries(owner);
        }

        // Check if the given is an owner to this dictionary 
        internal bool ContainsOwner(DispatcherObject owner)
        { 
            FrameworkElement fe = owner as FrameworkElement; 
            if (fe != null)
            { 
                return (_ownerFEs != null && _ownerFEs.Contains(fe));
            }
            else
            { 
                FrameworkContentElement fce = owner as FrameworkContentElement;
                if (fce != null) 
                { 
                    return (_ownerFCEs != null && _ownerFCEs.Contains(fce));
                } 
                else
                {
                    Application app = owner as Application;
                    if (app != null) 
                    {
                        return (_ownerApps != null && _ownerApps.Contains(app)); 
                    } 
                }
            } 

            return false;
        }
 
        // Helper method that tries to set IsInitialized to true if BeginInit hasn't been called before this.
        // This method is called on AddOwner 
        private void TryInitialize() 
        {
            if (!IsInitializePending && 
                !IsInitialized)
            {
                IsInitialized = true;
            } 
        }
 
        // Call FrameworkElement.InvalidateTree with the right data 
        private void NotifyOwners(ResourcesChangeInfo info)
        { 
            bool shouldInvalidate   = IsInitialized;
            bool hasImplicitStyles  = info.IsResourceAddOperation && HasImplicitStyles;

            if (shouldInvalidate || hasImplicitStyles) 
            {
                // Invalidate all FE owners 
                if (_ownerFEs != null) 
                {
                    for (int i=0; i<_ownerFEs.Count; i++) 
                    {
                        // Set the HasImplicitStyles flag on the owner
                        if (hasImplicitStyles)
                            _ownerFEs[i].ShouldLookupImplicitStyles = true; 

                        // If this dictionary has been initialized fire an invalidation 
                        // to let the tree know of this change. 
                        if (shouldInvalidate)
                            TreeWalkHelper.InvalidateOnResourcesChange(_ownerFEs[i], null, info); 
                    }
                }

                // Invalidate all FCE owners 
                if (_ownerFCEs != null)
                { 
                    for (int i=0; i<_ownerFCEs.Count; i++) 
                    {
                        // Set the HasImplicitStyles flag on the owner 
                        if (hasImplicitStyles)
                            _ownerFCEs[i].ShouldLookupImplicitStyles = true;

                        // If this dictionary has been initialized fire an invalidation 
                        // to let the tree know of this change.
                        if (shouldInvalidate) 
                            TreeWalkHelper.InvalidateOnResourcesChange(null, _ownerFCEs[i], info); 
                    }
                } 

                // Invalidate all App owners
                if (_ownerApps != null)
                { 
                    for (int i=0; i<_ownerApps.Count; i++)
                    { 
                        // Set the HasImplicitStyles flag on the owner 
                        if (hasImplicitStyles)
                            _ownerApps[i].HasImplicitStylesInResources = true; 

                        // If this dictionary has been initialized fire an invalidation
                        // to let the tree know of this change.
                        if (shouldInvalidate) 
                            _ownerApps[i].InvalidateResourceReferences(info);
                    } 
                } 
            }
        } 

        /// 
        /// Fetches the resource corresponding to the given key from this dictionary.
        /// Returns a DeferredResourceReference if the object has not been inflated yet. 
        /// 
        internal object FetchResource( 
            object      resourceKey, 
            bool        allowDeferredResourceReference,
            bool        mustReturnDeferredResourceReference, 
            out bool    canCache)
        {
            Debug.Assert(resourceKey != null, "ResourceKey cannot be null");
 
            if (allowDeferredResourceReference)
            { 
                if (ContainsBamlObjectFactory(resourceKey) || 
                    (mustReturnDeferredResourceReference && Contains(resourceKey)))
                { 
                    canCache = false;

                    DeferredResourceReference deferredResourceReference;
                    if (!IsThemeDictionary) 
                    {
                        if (_ownerApps != null) 
                        { 
                            deferredResourceReference = new DeferredAppResourceReference(this, resourceKey);
                        } 
                        else
                        {
                            deferredResourceReference = new DeferredResourceReference(this, resourceKey);
                        } 

                        // Cache the deferredResourceReference so that it can be validated 
                        // in case of a dictionary change prior to its inflation 
                        if (_deferredResourceReferences == null)
                        { 
                            _deferredResourceReferences = new List();
                        }

                        _deferredResourceReferences.Add(deferredResourceReference); 
                    }
                    else 
                    { 
                        deferredResourceReference = new DeferredThemeResourceReference(this, resourceKey);
                    } 

                    return deferredResourceReference;
                }
            } 

            return GetValue(resourceKey, out canCache); 
        } 

        ///  
        /// Validate the deferredResourceReference with the given key. Key could be null meaning
        /// some catastrophic operation occurred so simply validate all DeferredResourceReferences
        /// 
        private void ValidateDeferredResourceReferences(object resourceKey) 
        {
            if (_deferredResourceReferences != null) 
            { 
                for (int i=0; i<_deferredResourceReferences.Count; i++)
                { 
                    DeferredResourceReference deferredResourceReference = _deferredResourceReferences[i];
                    if (resourceKey == null || Object.Equals(resourceKey, deferredResourceReference.Key))
                    {
#if DEBUG 
                        int oldCount = _deferredResourceReferences.Count;
#endif 
                        deferredResourceReference.GetValue(BaseValueSourceInternal.Unknown); 

#if DEBUG 
                        int newCount = _deferredResourceReferences.Count;
                        Debug.Assert(newCount == oldCount-1,
                            "The deferredResourceReference that was just validated should have also been removed from the list as part of the GetValue call.");
#endif 

                        // Adjust i to accomodate the removal of an entry 
                        i--; 
                    }
                } 
            }
        }

 
        /// 
        /// Called when the MergedDictionaries collection changes 
        ///  
        /// 
        ///  
        private void OnMergedDictionariesChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            List oldDictionaries = null;
            List newDictionaries = null; 
            ResourceDictionary mergedDictionary;
            ResourcesChangeInfo info; 
 
            if (e.Action != NotifyCollectionChangedAction.Reset)
            { 
                Invariant.Assert(
                    (e.NewItems != null && e.NewItems.Count > 0) ||
                    (e.OldItems != null && e.OldItems.Count > 0),
                    "The NotifyCollectionChanged event fired when no dictionaries were added or removed"); 

 
                // If one or more resource dictionaries were removed we 
                // need to remove the owners they were given by their
                // parent ResourceDictionary. 

                if (e.Action == NotifyCollectionChangedAction.Remove
                    || e.Action == NotifyCollectionChangedAction.Replace)
                { 
                    oldDictionaries = new List(e.OldItems.Count);
 
                    for (int i = 0; i < e.OldItems.Count; i++) 
                    {
                        mergedDictionary = (ResourceDictionary)e.OldItems[i]; 
                        oldDictionaries.Add(mergedDictionary);

                        RemoveParentOwners(mergedDictionary);
                    } 
                }
 
                // If one or more resource dictionaries were added to the merged 
                // dictionaries collection we need to send down the parent
                // ResourceDictionary's owners. 

                if (e.Action == NotifyCollectionChangedAction.Add
                    || e.Action == NotifyCollectionChangedAction.Replace)
                { 
                    newDictionaries = new List(e.NewItems.Count);
 
                    for (int i = 0; i < e.NewItems.Count; i++) 
                    {
                        mergedDictionary = (ResourceDictionary)e.NewItems[i]; 
                        newDictionaries.Add(mergedDictionary);

                        // If the merged dictionary HasImplicitStyle mark the outer dictionary the same.
                        if (!HasImplicitStyles && mergedDictionary.HasImplicitStyles) 
                        {
                            HasImplicitStyles = true; 
                        } 

                        // (03/12/08) Backing out the change for binary compat reasons. 
                        // If the parent dictionary is a theme dictionary mark the merged dictionary the same.
                        // if (IsThemeDictionary)
                        // {
                        //     mergedDictionary.IsThemeDictionary = true; 
                        // }
 
                        PropagateParentOwners(mergedDictionary); 
                    }
                } 

                info = new ResourcesChangeInfo(oldDictionaries, newDictionaries, false, false, null);
            }
            else 
            {
                // Case when MergedDictionary collection is cleared 
                info = ResourcesChangeInfo.CatastrophicDictionaryChangeInfo; 
            }
 
            // Notify the owners of the change and fire
            // invalidation if already initialized

            NotifyOwners(info); 
        }
 
        ///  
        /// Adds the given owner to all merged dictionaries of this ResourceDictionary
        ///  
        /// 
        private void AddOwnerToAllMergedDictionaries(DispatcherObject owner)
        {
            if (_mergedDictionaries != null) 
            {
                for (int i = 0; i < _mergedDictionaries.Count; i++) 
                { 
                    _mergedDictionaries[i].AddOwner(owner);
                } 
            }
        }

        ///  
        ///
        ///  
        ///  
        private void RemoveOwnerFromAllMergedDictionaries(DispatcherObject owner)
        { 
            if (_mergedDictionaries != null)
            {
                for (int i = 0; i < _mergedDictionaries.Count; i++)
                { 
                    _mergedDictionaries[i].RemoveOwner(owner);
                } 
            } 
        }
 
        /// 
        /// This sends down the owners of this ResourceDictionary into the given
        /// merged dictionary.  We do this because whenever a merged dictionary
        /// changes it should invalidate all owners of its parent ResourceDictionary. 
        ///
        /// Note that AddOwners throw if the merged dictionary already has one of the 
        /// parent's owners.  This implies that either we're putting a dictionary 
        /// into its own MergedDictionaries collection or we're putting the same
        /// dictionary into the collection twice, neither of which are legal. 
        /// 
        /// 
        private void PropagateParentOwners(ResourceDictionary mergedDictionary)
        { 
            if (_ownerFEs != null)
            { 
                Invariant.Assert(_ownerFEs.Count > 0); 

                if (mergedDictionary._ownerFEs == null) 
                {
                    mergedDictionary._ownerFEs = new List(_ownerFEs.Count);
                }
 
                for (int i = 0; i < _ownerFEs.Count; i++)
                { 
                    mergedDictionary.AddOwner(_ownerFEs[i]); 
                }
            } 

            if (_ownerFCEs != null)
            {
                Invariant.Assert(_ownerFCEs.Count > 0); 

                if (mergedDictionary._ownerFCEs == null) 
                { 
                    mergedDictionary._ownerFCEs = new List(_ownerFCEs.Count);
                } 

                for (int i = 0; i < _ownerFCEs.Count; i++)
                {
                    mergedDictionary.AddOwner(_ownerFCEs[i]); 
                }
            } 
 
            if (_ownerApps != null)
            { 
                Invariant.Assert(_ownerApps.Count > 0);

                if (mergedDictionary._ownerApps == null)
                { 
                    mergedDictionary._ownerApps = new List(_ownerApps.Count);
                } 
 
                for (int i = 0; i < _ownerApps.Count; i++)
                { 
                    mergedDictionary.AddOwner(_ownerApps[i]);
                }
            }
        } 

 
        ///  
        /// Removes the owners of this ResourceDictionary from the given
        /// merged dictionary.  The merged dictionary will be left with 
        /// whatever owners it had before being merged.
        /// 
        /// 
        internal void RemoveParentOwners(ResourceDictionary mergedDictionary) 
        {
            if (_ownerFEs != null) 
            { 
                Invariant.Assert(_ownerFEs.Count > 0);
 
                for (int i = 0; i < _ownerFEs.Count; i++)
                {
                    mergedDictionary.RemoveOwner(_ownerFEs[i]);
                } 
            }
 
            if (_ownerFCEs != null) 
            {
                Invariant.Assert(_ownerFCEs.Count > 0); 

                for (int i = 0; i < _ownerFCEs.Count; i++)
                {
                    mergedDictionary.RemoveOwner(_ownerFCEs[i]); 
                }
            } 
 
            if (_ownerApps != null)
            { 
                Invariant.Assert(_ownerApps.Count > 0);

                for (int i = 0; i < _ownerApps.Count; i++)
                { 
                    mergedDictionary.RemoveOwner(_ownerApps[i]);
                } 
            } 
        }
 
        private bool ContainsCycle(ResourceDictionary origin)
        {
            for (int i=0; i DeferredResourceReferences
        {
            get { return _deferredResourceReferences; }
        } 

        #endregion Properties 
 
        #region Enumeration
 
        /// 
        ///     Iterates the dictionary's entries, handling deferred content.
        /// 
        private class ResourceDictionaryEnumerator : IDictionaryEnumerator 
        {
            internal ResourceDictionaryEnumerator(ResourceDictionary owner) 
            { 
                _owner = owner;
                _keysEnumerator = _owner.Keys.GetEnumerator(); 
            }

            #region IEnumerator
 
            object IEnumerator.Current
            { 
                get 
                {
                    return ((IDictionaryEnumerator)this).Entry; 
                }
            }

            bool IEnumerator.MoveNext() 
            {
                return _keysEnumerator.MoveNext(); 
            } 

            void IEnumerator.Reset() 
            {
                _keysEnumerator.Reset();
            }
 
            #endregion
 
            #region IDictionaryEnumerator 

            DictionaryEntry IDictionaryEnumerator.Entry 
            {
                get
                {
                    object key = _keysEnumerator.Current; 
                    object value = _owner[key];
                    return new DictionaryEntry(key, value); 
                } 
            }
 
            object IDictionaryEnumerator.Key
            {
                get
                { 
                    return _keysEnumerator.Current;
                } 
            } 

            object IDictionaryEnumerator.Value 
            {
                get
                {
                    return _owner[_keysEnumerator.Current]; 
                }
            } 
 
            #endregion
 
            #region Data

            private ResourceDictionary _owner;
            private IEnumerator _keysEnumerator; 

            #endregion 
        } 

        ///  
        ///     Iterator for the dictionary's Values collection, handling deferred content.
        /// 
        private class ResourceValuesEnumerator : IEnumerator
        { 
            internal ResourceValuesEnumerator(ResourceDictionary owner)
            { 
                _owner = owner; 
                _keysEnumerator = _owner.Keys.GetEnumerator();
            } 

            #region IEnumerator

            object IEnumerator.Current 
            {
                get 
                { 
                    return _owner[_keysEnumerator.Current];
                } 
            }

            bool IEnumerator.MoveNext()
            { 
                return _keysEnumerator.MoveNext();
            } 
 
            void IEnumerator.Reset()
            { 
                _keysEnumerator.Reset();
            }

            #endregion 

            #region Data 
 
            private ResourceDictionary _owner;
            private IEnumerator _keysEnumerator; 

            #endregion
        }
 
        /// 
        ///     Represents the dictionary's Values collection, handling deferred content. 
        ///  
        private class ResourceValuesCollection : ICollection
        { 
            internal ResourceValuesCollection(ResourceDictionary owner)
            {
                _owner = owner;
            } 

            #region ICollection 
 
            int ICollection.Count
            { 
                get
                {
                    return _owner.Count;
                } 
            }
 
            bool ICollection.IsSynchronized 
            {
                get 
                {
                    return false;
                }
            } 

            object ICollection.SyncRoot 
            { 
                get
                { 
                    return this;
                }
            }
 
            void ICollection.CopyTo(Array array, int index)
            { 
                foreach(object key in _owner.Keys) 
                {
                    array.SetValue(_owner[key], index++); 
                }
            }

            IEnumerator IEnumerable.GetEnumerator() 
            {
                return new ResourceValuesEnumerator(_owner); 
            } 

            #endregion 

            #region Data

            private ResourceDictionary _owner; 

            #endregion 
        } 

        #endregion Enumeration 

        #region PrivateMethods

        // 
        //  This method
        //  1. Seals all the freezables/styles/templates that belong to this App/Theme/Style/Template ResourceDictionary 
        // 
        private void SealValues()
        { 
            Debug.Assert(IsThemeDictionary || _ownerApps != null || IsReadOnly, "This must be an App/Theme/Style/Template ResourceDictionary");

            foreach (object value in _baseDictionary.Values)
            { 
                SealValue(value);
            } 
        } 

        // 
        //  This method
        //  1. Sets the InheritanceContext of the value to the dictionary's principal owner
        //  2. Seals the freezable/style/template that is to be placed in an App/Theme/Style/Template ResourceDictionary
        // 
        private void SealValue(object value)
        { 
            if (_inheritanceContext != null) 
            {
                AddInheritanceContext(value); 
            }

            if (IsThemeDictionary || _ownerApps != null || IsReadOnly)
            { 
                // If the value is a ISealable then seal it
                StyleHelper.SealIfSealable(value); 
            } 
        }
 
        // add inheritance context to a value
        private void AddInheritanceContext(object value)
        {
            // The VisualBrush.Visual property is the "friendliest", i.e. the 
            // most likely to be accepted by the resource as FEs need to accept
            // being rooted by a VisualBrush. 
            // 
            // NOTE:  Freezable.Debug_VerifyContextIsValid() contains a special
            //        case to allow this with the VisualBrush.Visual property. 
            //        Changes made here will require updates in Freezable.cs
            if (_inheritanceContext.ProvideSelfAsInheritanceContext(value, VisualBrush.VisualProperty))
            {
                // if the assignment was successful, seal the value's InheritanceContext. 
                // This makes sure the resource always gets inheritance-related information
                // from its point of definition, not from its point of use. 
                DependencyObject doValue = value as DependencyObject; 
                if (doValue != null)
                { 
                    doValue.IsInheritanceContextSealed = true;
                }
            }
        } 

        // add inheritance context to all values that came from this dictionary 
        private void AddInheritanceContextToValues() 
        {
            foreach (object value in _baseDictionary.Values) 
            {
                AddInheritanceContext(value);
            }
        } 

        // remove inheritance context from a value, if it came from this dictionary 
        private void RemoveInheritanceContext(object value) 
        {
            DependencyObject doValue = value as DependencyObject; 
            if (doValue != null && _inheritanceContext != null &&
                doValue.IsInheritanceContextSealed &&
                doValue.InheritanceContext == _inheritanceContext)
            { 
                doValue.IsInheritanceContextSealed = false;
                _inheritanceContext.RemoveSelfAsInheritanceContext(doValue, VisualBrush.VisualProperty); 
            } 
        }
 
        // remove inheritance context from all values that came from this dictionary
        private void RemoveInheritanceContextFromValues()
        {
            foreach (object value in _baseDictionary.Values) 
            {
                RemoveInheritanceContext(value); 
            } 
        }
 
        private BamlRecordReader Reader
        {
            get
            { 
                if (_reader == null)
                { 
                    _reader = new BamlRecordReader(_bamlStream, _context); 
                    _reader.RootElement = _rootElement;
                    _reader.ComponentConnector = _rootElement as IComponentConnector; 
                }

                return _reader;
            } 
        }
 
        // Sets the HasImplicitStyles flag if the given key is of type Type. 
        private void UpdateHasImplicitStyles(object key)
        { 
            // Update the HasImplicitStyles flag
            if (!HasImplicitStyles && key is Type)
            {
                HasImplicitStyles = true; 
            }
        } 
 
        private bool IsInitialized
        { 
            get { return ReadPrivateFlag(PrivateFlags.IsInitialized); }
            set { WritePrivateFlag(PrivateFlags.IsInitialized, value); }
        }
 
        private bool IsInitializePending
        { 
            get { return ReadPrivateFlag(PrivateFlags.IsInitializePending); } 
            set { WritePrivateFlag(PrivateFlags.IsInitializePending, value); }
        } 

        private bool IsThemeDictionary
        {
            get { return ReadPrivateFlag(PrivateFlags.IsThemeDictionary); } 
            set { WritePrivateFlag(PrivateFlags.IsThemeDictionary, value); }
            // (03/12/08) Backing out the change for binary compat reasons. 
            // { 
            //     if (IsThemeDictionary != value)
            //     { 
            //        WritePrivateFlag(PrivateFlags.IsThemeDictionary, value);
            //
            //         if (_mergedDictionaries != null)
            //         { 
            //             for (int i=0; i<_mergedDictionaries.Count; i++)
            //             { 
            //                 _mergedDictionaries[i].IsThemeDictionary = value; 
            //             }
            //         } 
            //     }
            // }
        }
 
        internal bool HasImplicitStyles
        { 
            get { return ReadPrivateFlag(PrivateFlags.HasImplicitStyles); } 
            set { WritePrivateFlag(PrivateFlags.HasImplicitStyles, value); }
        } 

        internal bool CanBeAccessedAcrossThreads
        {
            get { return ReadPrivateFlag(PrivateFlags.CanBeAccessedAcrossThreads); } 
            set { WritePrivateFlag(PrivateFlags.CanBeAccessedAcrossThreads, value); }
        } 
 
        private void WritePrivateFlag(PrivateFlags bit, bool value)
        { 
            if (value)
            {
                _flags |= bit;
            } 
            else
            { 
                _flags &= ~bit; 
            }
        } 

        private bool ReadPrivateFlag(PrivateFlags bit)
        {
            return (_flags & bit) != 0; 
        }
 
        #endregion PrivateMethods 

        #region PrivateDataStructures 

        private enum PrivateFlags : byte
        {
            IsInitialized               = 0x01, 
            IsInitializePending         = 0x02,
            IsReadOnly                  = 0x04, 
            IsThemeDictionary           = 0x08, 
            HasImplicitStyles           = 0x10,
            CanBeAccessedAcrossThreads  = 0x20, 

            // Unused bit = 0x40,
            // Unused bit = 0x80,
        } 

        #endregion PrivateDataStructures 
 
        #region Data
 
        private Hashtable                                 _baseDictionary = null;
        private List                    _ownerFEs = null;
        private List             _ownerFCEs = null;
        private List                         _ownerApps = null; 
        private List           _deferredResourceReferences = null;
        private ObservableCollection  _mergedDictionaries = null; 
        private Uri                                       _source = null; 
        private Uri                                       _baseUri = null;
        private PrivateFlags                              _flags = 0; 

        // Buffer that contains deferable content.  This may be null if a stream was passed
        // instead of a buffer.  If a buffer was passed, then a memory stream is made on the buffer
        private byte[]          _buffer; 

        // Persistent Stream that contains values. 
        private Stream          _bamlStream; 

        // Start position in the stream where the first value record is located.  All offsets for 
        // the keys are relative to this position.
        private Int64           _startPosition;

        // Size of the delay loaded content, which only includes the value section and not the keys. 
        private Int32           _contentSize;
 
        // Parser context that is in effect when the Defer load block is encountered in the baml 
        // stream.  This should include all information, types, properties, etc that is needed to
        // parse ALL of the values in the defer load section. 
        private ParserContext   _context;

        // The root element at the time the deferred content information was given to the dictionary.
        private object          _rootElement; 

        // Baml reader associated with this chunk of defer loaded content. 
        private BamlRecordReader _reader; 

        // The number of keys that correspond to deferred content. When this reaches 0, 
        // the stream can be closed.
        private int             _numDefer;

        // The object that becomes the InheritanceContext of all eligible 
        // values in the dictionary - typically the principal owner of the dictionary.
        private DependencyObject _inheritanceContext; 
 
        XamlObjectIds _contextXamlObjectIds  = new XamlObjectIds();
 

        #endregion Data
    }
} 


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK