BamlRecordWriter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / System / Windows / Markup / BamlRecordWriter.cs / 1305600 / BamlRecordWriter.cs

                            /****************************************************************************\ 
*
* File: BamlRecordWriter.cs
*
* Purpose:  Helper class for writing BAML records 
*
* History: 
*    6/06/01:    rogerg        Created 
*    5/28/03:    peterost      Ported to wcp
*    10/6/03:    peterost      Reorganized to remove DP - clr distinction 
*
* Copyright (C) 2002 by Microsoft Corporation.  All rights reserved.
*
\***************************************************************************/ 

using System; 
using System.Xml; 
using System.IO;
using System.Text; 
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
 
using System.Diagnostics;
using System.Reflection; 
 
using MS.Utility;
 
#if !PBTCOMPILER

using System.Windows;
using System.Windows.Threading; 

#endif 
 
#if PBTCOMPILER
using System.Globalization; 

namespace MS.Internal.Markup
#else
namespace System.Windows.Markup 
#endif
{ 
 
    /// 
    /// Class for writing baml to a stream from XamlParser calls 
    /// 
    internal class BamlRecordWriter
    {
#region Constructor 

        ///  
        /// Constructor that allows defer loading feature to be enabled, even 
        /// for non-compile cases.
        ///  
        public BamlRecordWriter(
            Stream        stream,
            ParserContext parserContext,
            bool          deferLoadingSupport) 
        {
            _bamlStream = stream; 
            _xamlTypeMapper = parserContext.XamlTypeMapper; 
            _deferLoadingSupport = deferLoadingSupport;
            _bamlMapTable = parserContext.MapTable; 
            _parserContext = parserContext;

            _debugBamlStream = false;
            _lineNumber = -1; 
            _linePosition = -1;
 
            _bamlBinaryWriter = new BamlBinaryWriter(stream,new System.Text.UTF8Encoding()); 
            _bamlRecordManager = new BamlRecordManager();
        } 

#endregion Constructor

#region Methods 

 
        // Called by BamlRecordWriter records to persist a record. 
        internal virtual void WriteBamlRecord(
            BamlRecord bamlRecord, 
            int        lineNumber,
            int        linePosition)
        {
            try 
            {
                bamlRecord.Write(BinaryWriter); 
 
                if(DebugBamlStream)
                { 
                    if(BamlRecordHelper.DoesRecordTypeHaveDebugExtension(bamlRecord.RecordType))
                    {
                        WriteDebugExtensionRecord(lineNumber, linePosition);
                    } 
                }
            } 
            catch (XamlParseException e) 
            {
                _xamlTypeMapper.ThrowExceptionWithLine(e.Message, e.InnerException); 
            }
        }

        // Indicates if ParentNodes should be updated. 
        // This is only used when loading compiled baml so can have node information
        internal virtual bool UpdateParentNodes 
        { 
            get
            { 
                return true;
            }
        }
 
#if !PBTCOMPILER
        // review - this needs to check that setparseMode is called only 
        // once and only on the Root tag. 
        internal void SetParseMode(XamlParseMode xamlParseMode)
        { 
            // only update if we are allowed to update the parent nodes
            if (UpdateParentNodes)
            {
                 // update the parseMode in the StartRecord. 
                if (xamlParseMode == XamlParseMode.Asynchronous)
                { 
                    Debug.Assert(null != DocumentStartRecord); 
                    if (null != DocumentStartRecord)
                    { 
                        DocumentStartRecord.LoadAsync = true;
                        DocumentStartRecord.UpdateWrite(BinaryWriter);
                    }
                } 
            }
        } 
#endif 

        // Sets the number of Records that can be read at a time 
        // in async mode. Main use is for debugging.
        internal virtual void SetMaxAsyncRecords(int maxAsyncRecords)
        {
            // only update if we are allowed to update the parent nodes 
            if (UpdateParentNodes)
            { 
 
                Debug.Assert(null != DocumentStartRecord);
                if (null != DocumentStartRecord) 
                {
                    DocumentStartRecord.MaxAsyncRecords = maxAsyncRecords;
                    DocumentStartRecord.UpdateWrite(BinaryWriter);
                } 
            }
        } 
 
#region Record Writing
 
#region Debug Record Writing

        public bool DebugBamlStream
        { 
            get { return _debugBamlStream; }
#if PBTCOMPILER 
            set { _debugBamlStream = value; } 
#endif
        } 

        internal BamlLineAndPositionRecord LineAndPositionRecord
        {
            get 
            {
                if(_bamlLineAndPositionRecord == null) 
                { 
                    _bamlLineAndPositionRecord = new BamlLineAndPositionRecord();
                } 
                return _bamlLineAndPositionRecord;
            }
        }
 
        internal BamlLinePositionRecord LinePositionRecord
        { 
            get 
            {
                if(_bamlLinePositionRecord == null) 
                {
                    _bamlLinePositionRecord = new BamlLinePositionRecord();
                }
                return _bamlLinePositionRecord; 
            }
        } 
 
        internal void WriteDebugExtensionRecord(int lineNumber, int linePosition)
        { 
            // if the Linenumber has changed then the Position had also.
            // So write out a record with both Line and Position.
            if(lineNumber != _lineNumber)
            { 
                BamlLineAndPositionRecord rec = LineAndPositionRecord;
                _lineNumber = lineNumber; 
                rec.LineNumber = (uint)lineNumber; 

                _linePosition = linePosition; 
                rec.LinePosition = (uint)linePosition;

                rec.Write(BinaryWriter);
            } 
            // if the Line has NOT changed but the position has then
            // write a smaller record with just the position. 
            else if(linePosition != _linePosition) 
            {
                _linePosition = linePosition; 
                BamlLinePositionRecord rec = LinePositionRecord;
                rec.LinePosition = (uint)linePosition;
                rec.Write(BinaryWriter);
            } 
            // if neither has changed then don't waste space and
            // don't write a record. 
        } 

#endregion Debug Record Writing 

        // called to start writing the BAML
        internal void WriteDocumentStart(XamlDocumentStartNode xamlDocumentNode)
        { 
            // Always put a Version Block before the Document Start record.
            BamlVersionHeader bamlVersion = new BamlVersionHeader(); 
            bamlVersion.WriteVersion(BinaryWriter); 

            DocumentStartRecord = (BamlDocumentStartRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.DocumentStart); 
            DocumentStartRecord.DebugBaml = DebugBamlStream;

            // go ahead and write initial values to the Stream, will back fill.
            // the rootElement. 
            WriteBamlRecord(DocumentStartRecord, xamlDocumentNode.LineNumber,
                            xamlDocumentNode.LinePosition); 
 
            BamlRecordManager.ReleaseWriteRecord(DocumentStartRecord);
        } 

        // called when BAML is completely written
        internal void WriteDocumentEnd(XamlDocumentEndNode xamlDocumentEndNode)
        { 
            // write end of document record
            BamlDocumentEndRecord endDocument = 
                (BamlDocumentEndRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.DocumentEnd); 

            WriteBamlRecord(endDocument, xamlDocumentEndNode.LineNumber, 
                            xamlDocumentEndNode.LinePosition);

            BamlRecordManager.ReleaseWriteRecord(endDocument);
 
            // should be done now and evertying fully initialized.
        } 
 
        internal void WriteConnectionId(Int32 connectionId)
        { 
            BamlConnectionIdRecord bamlCxnId =
                   (BamlConnectionIdRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.ConnectionId);

            bamlCxnId.ConnectionId = connectionId; 
            WriteAndReleaseRecord(bamlCxnId, null);
        } 
 
        // following are for writing to the BAML
        // Somewhat mimics XMLTextWriter 
        internal void WriteElementStart(XamlElementStartNode xamlElementNode)
        {
            // initialize the element and add to the stack
            BamlElementStartRecord bamlElement = 
                   (BamlElementStartRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.ElementStart);
 
            // If we do not already have a type record for the type of this element, 
            // then add a new TypeInfo record to the map table.
            short typeId; 
            if (!MapTable.GetTypeInfoId(BinaryWriter,
                                        xamlElementNode.AssemblyName,
                                        xamlElementNode.TypeFullName,
                                        out typeId)) 
            {
                string serializerAssemblyName = string.Empty; 
                if (xamlElementNode.SerializerType != null) 
                {
                    serializerAssemblyName = xamlElementNode.SerializerType.Assembly.FullName; 
                }
                typeId = MapTable.AddTypeInfoMap(BinaryWriter,
                                                 xamlElementNode.AssemblyName,
                                                 xamlElementNode.TypeFullName, 
                                                 xamlElementNode.ElementType,
                                                 serializerAssemblyName, 
                                                 xamlElementNode.SerializerTypeFullName); 
            }
            bamlElement.TypeId = typeId; 
            bamlElement.CreateUsingTypeConverter = xamlElementNode.CreateUsingTypeConverter;
            bamlElement.IsInjected = xamlElementNode.IsInjected;

            // Check if the element we are about to write supports deferable content. 
            // If so, then we have to queue up all the baml records that are contained
            // within this element and extract key information (if this is a dictionary). 
            // At the end tag, the queued records will be written in an optimal order 
            // and offsets inserted to permit fast runtime indexing of content.
            if (_deferLoadingSupport && _deferElementDepth > 0) 
            {
                _deferElementDepth++;

                if (InStaticResourceSection) 
                {
                    // Gather all the BamlRecords within the StaticResource section 
                    _staticResourceElementDepth++; 
                    _staticResourceRecordList.Add(new ValueDeferRecord(bamlElement, xamlElementNode.LineNumber, xamlElementNode.LinePosition));
                } 
                else if (CollectingValues && KnownTypes.Types[(int)KnownElements.StaticResourceExtension] == xamlElementNode.ElementType)
                {
                    // Mark the beginning of a StaticResource section
                    _staticResourceElementDepth = 1; 
                    _staticResourceRecordList = new List(5);
                    _staticResourceRecordList.Add(new ValueDeferRecord(bamlElement, xamlElementNode.LineNumber, xamlElementNode.LinePosition)); 
                } 
                else
                { 
                    // Detect that we are within a DynamicResource Section.
                    if (InDynamicResourceSection)
                    {
                        _dynamicResourceElementDepth++; 
                    }
                    else if (CollectingValues && KnownTypes.Types[(int)KnownElements.DynamicResourceExtension] == xamlElementNode.ElementType) 
                    { 
                        _dynamicResourceElementDepth = 1;
                    } 

                    ValueDeferRecord deferRecord = new ValueDeferRecord(bamlElement,
                                            xamlElementNode.LineNumber,
                                            xamlElementNode.LinePosition); 

                    if(_deferComplexPropertyDepth > 0) 
                    { 
                        // If we are in the middle of a complex property specified for a defered
                        // type, we need to append to the _deferElement array. 
                        _deferElement.Add(deferRecord);
                    }
                    else if (_deferElementDepth == 2)
                    { 
                        // If this element is directly below the dictionary root, then put a
                        // placeholder record in the key collection.  If this is not filled 
                        // in before we reach the end of this element's scope, then we don't 
                        // have a key, and that's an error.
 
                        _deferKeys.Add(new KeyDeferRecord(xamlElementNode.LineNumber,
                                                          xamlElementNode.LinePosition));

                        // Remember that this element record is for the start of a value, 
                        // so that the offset in the associated key record should be set
                        // when this record is actually written out to the baml stream. 
                        deferRecord.UpdateOffset = true; 
                        _deferValues.Add(deferRecord);
                    } 
                    else if (_deferKeyCollecting)
                    {
                        // Don't allow a bind or resource reference in a deferable key, since this
                        // causes problems for resolution.  Multi-pass or recursive key resolution 
                        // would be needed to robustly support this feature.
                        if (typeof(String).IsAssignableFrom(xamlElementNode.ElementType) || 
                            KnownTypes.Types[(int)KnownElements.StaticExtension].IsAssignableFrom(xamlElementNode.ElementType) || 
                            KnownTypes.Types[(int)KnownElements.TypeExtension].IsAssignableFrom(xamlElementNode.ElementType))
                        { 
                            ((KeyDeferRecord)_deferKeys[_deferKeys.Count-1]).RecordList.Add(deferRecord);
                        }
                        else
                        { 
                            XamlParser.ThrowException(SRID.ParserBadKey,
                                                      xamlElementNode.TypeFullName, 
                                                      xamlElementNode.LineNumber, 
                                                      xamlElementNode.LinePosition);
                        } 

                    }
                    else
                    { 
                        _deferValues.Add(deferRecord);
                    } 
                } 
            }
            else if (_deferLoadingSupport && KnownTypes.Types[(int)KnownElements.ResourceDictionary].IsAssignableFrom(xamlElementNode.ElementType)) 
            {
                _deferElementDepth = 1;
                _deferEndOfStartReached = false;
                _deferElement = new ArrayList(2); 
                _deferKeys = new ArrayList(10);
                _deferValues = new ArrayList(100); 
 
                _deferElement.Add(new ValueDeferRecord(bamlElement,
                                        xamlElementNode.LineNumber, 
                                        xamlElementNode.LinePosition));
            }

            else 
            {
                WriteBamlRecord(bamlElement, xamlElementNode.LineNumber, 
                                xamlElementNode.LinePosition); 

                BamlRecordManager.ReleaseWriteRecord(bamlElement); 
            }
          }

        // The end of an element has been reached, so write out the end indication 
        internal void WriteElementEnd(XamlElementEndNode xamlElementEndNode)
        { 
             BamlElementEndRecord bamlElementEnd = 
                (BamlElementEndRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.ElementEnd);
 
            // Check if we're queuing up deferable content.  If so and we're at the
            // end tag for that content, now is the time to actually write everything
            // to the baml stream and rewrite in the file locations for the values
            // sections. 
            if (_deferLoadingSupport && _deferElementDepth > 0 && _deferElementDepth-- == 1)
            { 
                WriteDeferableContent(xamlElementEndNode); 

                // Clear all defer related instance data 
                Debug.Assert(_deferElementDepth == 0);
                Debug.Assert(_deferComplexPropertyDepth == 0);
                Debug.Assert(_staticResourceElementDepth == 0);
                Debug.Assert(_dynamicResourceElementDepth == 0); 
                Debug.Assert(_staticResourceRecordList == null);
                _deferKeys = null; 
                _deferValues = null; 
                _deferElement = null;
            } 
            else
            {
                WriteAndReleaseRecord(bamlElementEnd, xamlElementEndNode);
 
                if (_deferLoadingSupport && _staticResourceElementDepth > 0 && _staticResourceElementDepth-- == 1)
                { 
                    // This marks the end of a StaticResource section 

                    // Process the StaticResourceRecordList that we 
                    // have been gathering this far
                    WriteStaticResource();

                    // Cleanup the list after processing 
                    Debug.Assert(_staticResourceElementDepth == 0);
                    _staticResourceRecordList = null; 
                } 
                else if (_deferLoadingSupport && _dynamicResourceElementDepth > 0 && _dynamicResourceElementDepth-- == 1)
                { 
                    // We have now exited the dynamic resource section
                }
            }
 
            // we've come to the end of the element.
         } 
 
        // The end of the start tag has been reached.  For compile cases, check
        // if we are accumulating a deferable block of records. 
        internal void WriteEndAttributes(XamlEndAttributesNode xamlEndAttributesNode)
        {
            if (_deferLoadingSupport && _deferElementDepth > 0)
            { 
                _deferEndOfStartReached = true;
            } 
        } 

        // Write a literal content blob to BAML 
        internal void WriteLiteralContent(XamlLiteralContentNode xamlLiteralContentNode)
        {
            // initialize the element and add to the stack
            BamlLiteralContentRecord bamlLiteralContent = 
                (BamlLiteralContentRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.LiteralContent);
            bamlLiteralContent.Value = xamlLiteralContentNode.Content; 
 
            WriteAndReleaseRecord(bamlLiteralContent, xamlLiteralContentNode);
        } 

        // Write an x:Key="value" where value has been resolved to a Type object
        // at compile or parse time.  This means less reflection at runtime.
        internal void WriteDefAttributeKeyType(XamlDefAttributeKeyTypeNode xamlDefNode) 
        {
            Debug.Assert(!InStaticResourceSection, "We do not support x:Key within a StaticResource Section"); 
 
            // If we do not already have a type record for the type of this key,
            // then add a new TypeInfo record to the map table. 
            short typeId;
            if (!MapTable.GetTypeInfoId(BinaryWriter,
                                        xamlDefNode.AssemblyName,
                                        xamlDefNode.Value, 
                                        out typeId))
            { 
                typeId = MapTable.AddTypeInfoMap(BinaryWriter, 
                                                 xamlDefNode.AssemblyName,
                                                 xamlDefNode.Value, 
                                                 xamlDefNode.ValueType,
                                                 string.Empty,
                                                 string.Empty);
            } 

 
            BamlDefAttributeKeyTypeRecord bamlDefRecord = BamlRecordManager.GetWriteRecord( 
                                                          BamlRecordType.DefAttributeKeyType)
                                                          as BamlDefAttributeKeyTypeRecord; 

            bamlDefRecord.TypeId = typeId;
            ((IBamlDictionaryKey)bamlDefRecord).KeyObject = xamlDefNode.ValueType;
 
            // If we are currently parsing a deferable content section then store it
            // in the keys collection. 
            if (_deferLoadingSupport && 
                _deferElementDepth == 2)
            { 
                KeyDeferRecord keyRecord = (KeyDeferRecord)(_deferKeys[_deferKeys.Count-1]);

                TransferOldSharedData(keyRecord.Record as IBamlDictionaryKey, bamlDefRecord as IBamlDictionaryKey);
                keyRecord.Record = bamlDefRecord; 

                keyRecord.LineNumber = xamlDefNode.LineNumber; 
                keyRecord.LinePosition = xamlDefNode.LinePosition; 
                return;
            } 

            if (_deferLoadingSupport && _deferElementDepth > 0)
            {
                _deferValues.Add(new ValueDeferRecord(bamlDefRecord, 
                                            xamlDefNode.LineNumber,
                                            xamlDefNode.LinePosition)); 
            } 
            else
            { 
                WriteBamlRecord(bamlDefRecord, xamlDefNode.LineNumber,
                                    xamlDefNode.LinePosition);

                BamlRecordManager.ReleaseWriteRecord(bamlDefRecord); 
            }
        } 
 
        private void TransferOldSharedData(IBamlDictionaryKey oldRecord, IBamlDictionaryKey newRecord)
        { 
            if ((oldRecord != null) && (newRecord != null))
            {
                newRecord.Shared = oldRecord.Shared;
                newRecord.SharedSet = oldRecord.SharedSet; 
            }
        } 
 
        private IBamlDictionaryKey FindBamlDictionaryKey(KeyDeferRecord record)
        { 
            if (record != null)
            {
                if (record.RecordList != null)
                { 
                    for (int i = 0; i < record.RecordList.Count; i++)
                    { 
                        ValueDeferRecord valueDeferRecord = (ValueDeferRecord)record.RecordList[i]; 
                        IBamlDictionaryKey dictionaryKey = valueDeferRecord.Record as IBamlDictionaryKey;
                        if (dictionaryKey != null) 
                        {
                            return dictionaryKey;
                        }
                    } 
                }
 
                return record.Record as IBamlDictionaryKey; 
            }
 
            return null;
        }

        // Write a x:attribute="value" record.  One typical use of this is 
        // to specify the key to use when inserting the current object into
        // a Dictionary, but there can be other uses also 
        internal void WriteDefAttribute(XamlDefAttributeNode xamlDefNode) 
        {
 
            // If we are currently parsing a deferable content section, then check
            // to see if we have a dictionary key value here.  If so, then store it
            // in the keys collection.
            if (_deferLoadingSupport && 
                _deferElementDepth == 2 &&
                xamlDefNode.Name == XamlReaderHelper.DefinitionName) 
            { 
                Debug.Assert(!InStaticResourceSection, "We do not support x:Key within a StaticResource Section");
 
                // Note that if we get to here the assumption is that the value of the Name
                // attribute is *NOT* a MarkupExtension.  A MarkupExtension would cause
                // WriteKeyElementStart being called.
                KeyDeferRecord keyRecord = (KeyDeferRecord)(_deferKeys[_deferKeys.Count-1]); 
                BamlDefAttributeKeyStringRecord defKeyRecord = keyRecord.Record as BamlDefAttributeKeyStringRecord;
                if (defKeyRecord == null) 
                { 
                    defKeyRecord =
                        (BamlDefAttributeKeyStringRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.DefAttributeKeyString); 
                    TransferOldSharedData(keyRecord.Record as IBamlDictionaryKey, defKeyRecord as IBamlDictionaryKey);
                    keyRecord.Record = defKeyRecord;
                }
 
                // Store the string value in the string table, since there will mostly be a
                // [Static/Dynamic]Resource referring to it and we can combine the storage 
                // for both these string into a single StringInfoRecord. 
                short valueId;
                if (!MapTable.GetStringInfoId(xamlDefNode.Value, 
                                              out valueId))
                {
                    valueId = MapTable.AddStringInfoMap(BinaryWriter,
                                                         xamlDefNode.Value); 
                }
 
                defKeyRecord.Value = xamlDefNode.Value; 
                defKeyRecord.ValueId = valueId;
 
                keyRecord.LineNumber = xamlDefNode.LineNumber;
                keyRecord.LinePosition = xamlDefNode.LinePosition;
                return;
            } 
            else if (_deferLoadingSupport &&
                     _deferElementDepth == 2 && 
                     xamlDefNode.Name == XamlReaderHelper.DefinitionShared) 
            {
                Debug.Assert(!InStaticResourceSection, "We do not support x:Shared within a StaticResource Section"); 

                // NOTE:  This does not properly handle MarkupExtensions....
                KeyDeferRecord keyRecord = (KeyDeferRecord)(_deferKeys[_deferKeys.Count-1]);
 
                IBamlDictionaryKey defKeyRecord = FindBamlDictionaryKey(keyRecord);
                if (defKeyRecord == null) 
                { 
                    BamlDefAttributeKeyStringRecord defStringKeyRecord =
                        (BamlDefAttributeKeyStringRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.DefAttributeKeyString); 
                    keyRecord.Record = defStringKeyRecord;
                    defKeyRecord = (IBamlDictionaryKey)defStringKeyRecord;
                }
 
                defKeyRecord.Shared = Boolean.Parse(xamlDefNode.Value);
                defKeyRecord.SharedSet = true; 
                keyRecord.LineNumber = xamlDefNode.LineNumber; 
                keyRecord.LinePosition = xamlDefNode.LinePosition;
                return; 
            }

            // Add definition attribute record.  Store the attribute name in the string table, since
            // the names are likely to be repeated. 
            short stringId;
            if (!MapTable.GetStringInfoId(xamlDefNode.Name, 
                                          out stringId)) 
            {
                stringId = MapTable.AddStringInfoMap(BinaryWriter, 
                                                     xamlDefNode.Name);
            }

            BamlDefAttributeRecord defRecord = 
                (BamlDefAttributeRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.DefAttribute);
 
            defRecord.Value  = xamlDefNode.Value; 
            defRecord.Name   = xamlDefNode.Name;
            defRecord.AttributeUsage = xamlDefNode.AttributeUsage; 
            defRecord.NameId = stringId;

            WriteAndReleaseRecord(defRecord, xamlDefNode);
        } 

        // Attributes used to specify WPF-specific parsing options 
        internal void WritePresentationOptionsAttribute(XamlPresentationOptionsAttributeNode xamlPresentationOptionsNode) 
        {
            // Add definition attribute record.  Store the attribute name in the string table, since 
            // the names are likely to be repeated.
            short stringId;
            if (!MapTable.GetStringInfoId(xamlPresentationOptionsNode.Name,
                                          out stringId)) 
            {
                stringId = MapTable.AddStringInfoMap(BinaryWriter, 
                                                     xamlPresentationOptionsNode.Name); 
            }
 
            BamlPresentationOptionsAttributeRecord attributeRecord =
                (BamlPresentationOptionsAttributeRecord) BamlRecordManager.GetWriteRecord(
                                        BamlRecordType.PresentationOptionsAttribute);
 
            attributeRecord.Value = xamlPresentationOptionsNode.Value;
            attributeRecord.Name = xamlPresentationOptionsNode.Name; 
            attributeRecord.NameId = stringId; 

            WriteAndReleaseRecord(attributeRecord, xamlPresentationOptionsNode); 
        }


        // The current element contains xmlns combinations we want scoped in case 
        // InnerXAML is done at runtime.
        internal void WriteNamespacePrefix(XamlXmlnsPropertyNode xamlXmlnsPropertyNode) 
        { 
            BamlXmlnsPropertyRecord xmlnsRecord =
                (BamlXmlnsPropertyRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.XmlnsProperty); 

            xmlnsRecord.Prefix = xamlXmlnsPropertyNode.Prefix;
            xmlnsRecord.XmlNamespace  = xamlXmlnsPropertyNode.XmlNamespace;
 
#if PBTCOMPILER
 
            // 
            // Get a list of Assemblies that contain XmlnsDefinitionAttribute for the
            // specific XmlNamespace. Add the relevant assemblies into MapTable. 
            //

            if (xamlXmlnsPropertyNode.XmlNamespace.StartsWith(XamlReaderHelper.MappingProtocol, StringComparison.Ordinal) == false)
            { 
                NamespaceMapEntry[] nsMapEntry = _xamlTypeMapper.GetNamespaceMapEntries(xamlXmlnsPropertyNode.XmlNamespace);
 
                if (nsMapEntry != null && nsMapEntry.Length > 0) 
                {
                    ArrayList asmList = new ArrayList(); 
                    for (int i = 0; i < nsMapEntry.Length; i++)
                    {
                        string asmName = nsMapEntry[i].AssemblyName;
 
                        if (!asmList.Contains(asmName))
                        { 
                            asmList.Add(asmName); 
                        }
                    } 

                    if (asmList.Count > 0)
                    {
                        short[] assemblyIds = new short[asmList.Count]; 

                        for (int i = 0; i < asmList.Count; i++) 
                        { 
                            BamlAssemblyInfoRecord bamlAssemblyInfoRecord = MapTable.AddAssemblyMap(BinaryWriter, (string)asmList[i]);
 
                            assemblyIds[i] = bamlAssemblyInfoRecord.AssemblyId;
                        }

                        xmlnsRecord.AssemblyIds = assemblyIds; 
                    }
                } 
            } 

#endif 


            // NOTE:  If we are defining a new namespace prefix in the value object's
            //        start record, AND using that prefix in x:Key, then we have a 
            //        problem, since the x:Key keys are hoisted out before this
            //        record in the baml stream....  I don't have a solution for 
            //        this yet, but this isn't an issue for theme files... 
            WriteAndReleaseRecord(xmlnsRecord, xamlXmlnsPropertyNode);
        } 

        // Write a xml to clr namespace mapping record
        internal void WritePIMapping(XamlPIMappingNode xamlPIMappingNode)
        { 
            BamlPIMappingRecord piMappingRecord =
                (BamlPIMappingRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PIMapping); 
 
            BamlAssemblyInfoRecord bamlAssemblyInfoRecord = MapTable.AddAssemblyMap(BinaryWriter,
                                                                  xamlPIMappingNode.AssemblyName); 

            piMappingRecord.XmlNamespace = xamlPIMappingNode.XmlNamespace;
            piMappingRecord.ClrNamespace = xamlPIMappingNode.ClrNamespace;
            piMappingRecord.AssemblyId   = bamlAssemblyInfoRecord.AssemblyId; 

            WriteBamlRecord(piMappingRecord, xamlPIMappingNode.LineNumber, 
                            xamlPIMappingNode.LinePosition); 

            BamlRecordManager.ReleaseWriteRecord(piMappingRecord); 
        }

        // Write the start of a complex property
        internal void WritePropertyComplexStart(XamlPropertyComplexStartNode 
                                    xamlComplexPropertyNode)
        { 
            // review same as property + flag, combine code 
            BamlPropertyComplexStartRecord bamlComplexProperty =
                (BamlPropertyComplexStartRecord) BamlRecordManager.GetWriteRecord( 
                                                        BamlRecordType.PropertyComplexStart);

            bamlComplexProperty.AttributeId =
                MapTable.AddAttributeInfoMap(BinaryWriter, 
                                             xamlComplexPropertyNode.AssemblyName,
                                             xamlComplexPropertyNode.TypeFullName, 
                                             xamlComplexPropertyNode.PropDeclaringType, 
                                             xamlComplexPropertyNode.PropName,
                                             xamlComplexPropertyNode.PropValidType, 
                                             BamlAttributeUsage.Default);

            WriteAndReleaseRecord(bamlComplexProperty, xamlComplexPropertyNode);
        } 

        // Write the end of a complex property 
        internal void WritePropertyComplexEnd( 
            XamlPropertyComplexEndNode xamlPropertyComplexEnd)
        { 
            BamlPropertyComplexEndRecord endPropertyRecord =
                (BamlPropertyComplexEndRecord) BamlRecordManager.GetWriteRecord(
                                                         BamlRecordType.PropertyComplexEnd);
 
            WriteAndReleaseRecord(endPropertyRecord, xamlPropertyComplexEnd);
        } 
 
        // Write the start of a def attribute element used as the key in an
        // IDictionary 
        public void WriteKeyElementStart(
            XamlElementStartNode xamlKeyElementNode)
        {
            Debug.Assert(!InStaticResourceSection, "We do not support x:Key within a StaticResource Section"); 

            // Don't allow a bind or resource reference in a key element, since this 
            // causes problems for resolution.  Multi-pass or recursive key resolution 
            // would be needed to robustly support this feature.
            if (!typeof(String).IsAssignableFrom(xamlKeyElementNode.ElementType) && 
                !KnownTypes.Types[(int)KnownElements.StaticExtension].IsAssignableFrom(xamlKeyElementNode.ElementType) &&
                !KnownTypes.Types[(int)KnownElements.TypeExtension].IsAssignableFrom(xamlKeyElementNode.ElementType) &&
                !KnownTypes.Types[(int)KnownElements.ResourceKey].IsAssignableFrom(xamlKeyElementNode.ElementType))
            { 
                XamlParser.ThrowException(SRID.ParserBadKey,
                                          xamlKeyElementNode.TypeFullName, 
                                          xamlKeyElementNode.LineNumber, 
                                          xamlKeyElementNode.LinePosition);
            } 

            // initialize the element and add to the stack
            BamlKeyElementStartRecord bamlElement =
                   (BamlKeyElementStartRecord) BamlRecordManager.GetWriteRecord( 
                                               BamlRecordType.KeyElementStart);
 
            // If we do not already have a type record for the type of this element, 
            // then add a new TypeInfo record to the map table.
            short typeId; 
            if (!MapTable.GetTypeInfoId(BinaryWriter,
                                        xamlKeyElementNode.AssemblyName,
                                        xamlKeyElementNode.TypeFullName,
                                        out typeId)) 
            {
                string serializerAssemblyName = string.Empty; 
                if (xamlKeyElementNode.SerializerType != null) 
                {
                    serializerAssemblyName = xamlKeyElementNode.SerializerType.Assembly.FullName; 
                }
                typeId = MapTable.AddTypeInfoMap(BinaryWriter,
                                                 xamlKeyElementNode.AssemblyName,
                                                 xamlKeyElementNode.TypeFullName, 
                                                 xamlKeyElementNode.ElementType,
                                                 serializerAssemblyName, 
                                                 xamlKeyElementNode.SerializerTypeFullName); 
            }
            bamlElement.TypeId = typeId; 

            // Check if the element we are about to write supports deferable content.
            // If so, then we have to queue up all the baml records that are contained
            // within this element and use this as a key (if this is a dictionary). 
            // At the end tag, the queued records will be written in an optimal order
            // and offsets inserted to permit fast runtime indexing of content. 
            if (_deferLoadingSupport && _deferElementDepth == 2) 
            {
                _deferElementDepth++; 
                _deferKeyCollecting = true;

                KeyDeferRecord keyRecord = (KeyDeferRecord)(_deferKeys[_deferKeys.Count-1]);
                keyRecord.RecordList = new ArrayList(5); 

                Debug.Assert(keyRecord.RecordList.Count == 0, "Should have empty record list"); 
                keyRecord.RecordList.Add(new ValueDeferRecord(bamlElement, 
                                                              xamlKeyElementNode.LineNumber,
                                                              xamlKeyElementNode.LinePosition)); 

                if (keyRecord.Record != null)
                {
                    TransferOldSharedData(keyRecord.Record as IBamlDictionaryKey, bamlElement as IBamlDictionaryKey); 
                    keyRecord.Record = null;
                } 
 
                keyRecord.LineNumber = xamlKeyElementNode.LineNumber;
                keyRecord.LinePosition = xamlKeyElementNode.LinePosition; 
                return;
            }
            else
            { 
                WriteAndReleaseRecord(bamlElement, xamlKeyElementNode);
            } 
        } 

        // Write the end of a def attribute tree section used as the key 
        // in an IDictionary
        internal void WriteKeyElementEnd(
            XamlElementEndNode xamlKeyElementEnd)
        { 
            Debug.Assert(!InStaticResourceSection, "We do not support x:Key within a StaticResource Section");
 
            BamlKeyElementEndRecord endRecord = 
                (BamlKeyElementEndRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.KeyElementEnd);
 
            WriteAndReleaseRecord(endRecord, xamlKeyElementEnd);

            if (_deferLoadingSupport && _deferKeyCollecting)
            { 
                _deferKeyCollecting = false;
                _deferElementDepth--; 
                Debug.Assert(_deferElementDepth == 2); 
            }
        } 

#if PBTCOMPILER
        /// 
        /// Write the constructor parameter that has been resolved to a Type 
        /// 
        internal void WriteConstructorParameterType( 
            XamlConstructorParameterTypeNode xamlConstructorParameterTypeNode) 
        {
            // If we do not already have a type record for the type of this property, 
            // then add a new TypeInfo record to the map table.
            short typeId;
            if (!MapTable.GetTypeInfoId(BinaryWriter,
                                        xamlConstructorParameterTypeNode.ValueTypeAssemblyName, 
                                        xamlConstructorParameterTypeNode.ValueTypeFullName,
                                        out typeId)) 
            { 
                typeId = MapTable.AddTypeInfoMap(BinaryWriter,
                                                 xamlConstructorParameterTypeNode.ValueTypeAssemblyName, 
                                                 xamlConstructorParameterTypeNode.ValueTypeFullName,
                                                 xamlConstructorParameterTypeNode.ValueElementType,
                                                 string.Empty,
                                                 string.Empty); 
            }
 
 
            BamlConstructorParameterTypeRecord bamlConstructor = BamlRecordManager.GetWriteRecord(
                                                          BamlRecordType.ConstructorParameterType) 
                                                          as BamlConstructorParameterTypeRecord;
            bamlConstructor.TypeId = typeId;

            WriteAndReleaseRecord(bamlConstructor, xamlConstructorParameterTypeNode); 
        }
#endif 
 
        /// 
        /// Write the start of a constructor parameter section 
        /// 
        internal void WriteConstructorParametersStart(
            XamlConstructorParametersStartNode xamlConstructorParametersStartNode)
        { 
            // Create a new baml record
            BamlConstructorParametersStartRecord startRecord = 
                (BamlConstructorParametersStartRecord) BamlRecordManager.GetWriteRecord( 
                     BamlRecordType.ConstructorParametersStart);
 
            WriteAndReleaseRecord(startRecord, xamlConstructorParametersStartNode);
        }

        ///  
        /// Write the end of a constructor parameter section
        ///  
        internal void WriteConstructorParametersEnd( 
            XamlConstructorParametersEndNode xamlConstructorParametersEndNode)
        { 
            // Create a new baml record
            BamlConstructorParametersEndRecord startRecord =
                (BamlConstructorParametersEndRecord) BamlRecordManager.GetWriteRecord(
                     BamlRecordType.ConstructorParametersEnd); 

            WriteAndReleaseRecord(startRecord, xamlConstructorParametersEndNode); 
        } 

        internal virtual void WriteContentProperty(XamlContentPropertyNode xamlContentPropertyNode) 
        {
            BamlContentPropertyRecord bamlContentPropertyRecord =
                (BamlContentPropertyRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.ContentProperty);
 
            bamlContentPropertyRecord.AttributeId =
                MapTable.AddAttributeInfoMap(BinaryWriter, 
                                             xamlContentPropertyNode.AssemblyName, 
                                             xamlContentPropertyNode.TypeFullName,
                                             xamlContentPropertyNode.PropDeclaringType, 
                                             xamlContentPropertyNode.PropName,
                                             xamlContentPropertyNode.PropValidType,
                                             BamlAttributeUsage.Default);
 
            WriteAndReleaseRecord(bamlContentPropertyRecord, xamlContentPropertyNode);
        } 
 
        // Write a property baml record.  If the type of this property supports
        // custom serialization or type conversion, then write out a special property 
        // record.  Otherwise write out a 'normal' record, which will cause type
        // converter resolution to happen at load time.

 
        internal virtual void WriteProperty(XamlPropertyNode xamlProperty)
        { 
            short attributeId = 
                    MapTable.AddAttributeInfoMap(BinaryWriter,
                                                 xamlProperty.AssemblyName, 
                                                 xamlProperty.TypeFullName,
                                                 xamlProperty.PropDeclaringType,
                                                 xamlProperty.PropName,
                                                 xamlProperty.PropValidType, 
                                                 xamlProperty.AttributeUsage);
 
            if (xamlProperty.AssemblyName != string.Empty && xamlProperty.TypeFullName != string.Empty) 
            {
                short converterOrSerializerTypeId; 
                Type  converterOrSerializerType;
                bool isCustomSerializer = MapTable.GetCustomSerializerOrConverter(
                              BinaryWriter,
                              xamlProperty.ValueDeclaringType, 
                              xamlProperty.ValuePropertyType,
                              xamlProperty.ValuePropertyMember, 
                              xamlProperty.ValuePropertyName, 
                          out converterOrSerializerTypeId,
                          out converterOrSerializerType); 

                if (converterOrSerializerType != null)
                {
                    if (isCustomSerializer) 
                    {
                        BamlPropertyCustomWriteInfoRecord bamlPropertyCustom = 
                            (BamlPropertyCustomWriteInfoRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyCustom); 
                        bamlPropertyCustom.AttributeId = attributeId;
                        bamlPropertyCustom.Value = xamlProperty.Value; 
                        bamlPropertyCustom.ValueType = xamlProperty.ValuePropertyType;
                        bamlPropertyCustom.SerializerTypeId = converterOrSerializerTypeId;
                        bamlPropertyCustom.SerializerType = converterOrSerializerType;
                        bamlPropertyCustom.TypeContext = TypeConvertContext; 
                        if (converterOrSerializerTypeId == (short)KnownElements.DependencyPropertyConverter)
                        { 
                            // if ValueId\MemberName have alredy been resolved, just write it out. 
                            if (xamlProperty.HasValueId)
                            { 
                                bamlPropertyCustom.ValueId = xamlProperty.ValueId;
                                bamlPropertyCustom.ValueMemberName = xamlProperty.MemberName;
                            }
                            else 
                            {
                                // else try to resolve the DP value of this property now 
                                string dpName; 

                                // get the ownerType and name of the DP value 
                                Type ownerType = _xamlTypeMapper.GetDependencyPropertyOwnerAndName(xamlProperty.Value,
                                                                                                   ParserContext,
                                                                                                   xamlProperty.DefaultTargetType,
                                                                                               out dpName); 
                                short typeId;
 
                                // get the known property Id or TypeId of the owner of the DP value 
                                short propertyId = MapTable.GetAttributeOrTypeId(BinaryWriter,
                                                                                 ownerType, 
                                                                                 dpName,
                                                                             out typeId);

                                // write it out as appropriate. 
                                if (propertyId < 0)
                                { 
                                    bamlPropertyCustom.ValueId = propertyId; 
                                    bamlPropertyCustom.ValueMemberName = null;
                                } 
                                else
                                {
                                    bamlPropertyCustom.ValueId = typeId;
                                    bamlPropertyCustom.ValueMemberName = dpName; 
                                }
                            } 
                        } 

                        WriteAndReleaseRecord(bamlPropertyCustom, xamlProperty); 
                    }
                    else
                    {
                        BamlPropertyWithConverterRecord bamlPropertyWithConverter = (BamlPropertyWithConverterRecord)BamlRecordManager.GetWriteRecord( 
                                                              BamlRecordType.PropertyWithConverter);
                        bamlPropertyWithConverter.AttributeId = attributeId; 
                        bamlPropertyWithConverter.Value = xamlProperty.Value; 
                        bamlPropertyWithConverter.ConverterTypeId = converterOrSerializerTypeId;
                        WriteAndReleaseRecord(bamlPropertyWithConverter, xamlProperty); 
                    }

                    return;
                } 
            }
 
            BaseWriteProperty(xamlProperty); 
        }
 
        internal virtual void WritePropertyWithExtension(XamlPropertyWithExtensionNode xamlPropertyNode)
        {
            short valueId = 0;
            short extensionTypeId = xamlPropertyNode.ExtensionTypeId; 
            bool isValueTypeExtension = false;
            bool isValueStaticExtension = false; 
            Debug.Assert(extensionTypeId != (short)KnownElements.TypeExtension); 

            // if the extension is a DynamicResourceExtension or a StaticResourceExtension 
            // dig in to see if its param is a simple extension or just a string.
            if ((extensionTypeId == (short)KnownElements.DynamicResourceExtension) ||
                (extensionTypeId == (short)KnownElements.StaticResourceExtension))
            { 
                // if the value is a simple nested extension
                if (xamlPropertyNode.IsValueNestedExtension) 
                { 
                    // Yes, see if it is a TypeExtension or StaticExtension
                    if (xamlPropertyNode.IsValueTypeExtension) 
                    {
                        // nested TypeExtension value
                        Type typeValue = _xamlTypeMapper.GetTypeFromBaseString(xamlPropertyNode.Value,
                                                                               ParserContext, 
                                                                               true);
                        Debug.Assert(typeValue != null); 
                        if (!MapTable.GetTypeInfoId(BinaryWriter, 
                                                    typeValue.Assembly.FullName,
                                                    typeValue.FullName, 
                                                    out valueId))
                        {
                            valueId = MapTable.AddTypeInfoMap(BinaryWriter,
                                                              typeValue.Assembly.FullName, 
                                                              typeValue.FullName,
                                                              typeValue, 
                                                              string.Empty, 
                                                              string.Empty);
                        } 

                        isValueTypeExtension = true;
                    }
                    else 
                    {
                        // nested StaticExtension value 
                        valueId = MapTable.GetStaticMemberId(BinaryWriter, 
                                                             ParserContext,
                                                             (short)KnownElements.StaticExtension, 
                                                             xamlPropertyNode.Value,
                                                             xamlPropertyNode.DefaultTargetType);

                        isValueStaticExtension = true; 
                    }
                } 
                else 
                {
                    // No, it is a string value. 
                    // Store the string value in the string table, since these records
                    // are already used as the key for a [Static/Dynamic]Resource.
                    if (!MapTable.GetStringInfoId(xamlPropertyNode.Value, out valueId))
                    { 
                        valueId = MapTable.AddStringInfoMap(BinaryWriter, xamlPropertyNode.Value);
                    } 
                } 
            }
            else 
            {
                // toplevel StaticExtension or TemplateBindingExtension value
                valueId = MapTable.GetStaticMemberId(BinaryWriter,
                                                     ParserContext, 
                                                     extensionTypeId,
                                                     xamlPropertyNode.Value, 
                                                     xamlPropertyNode.DefaultTargetType); 
            }
 
            short attributeId = MapTable.AddAttributeInfoMap(BinaryWriter,
                                                             xamlPropertyNode.AssemblyName,
                                                             xamlPropertyNode.TypeFullName,
                                                             xamlPropertyNode.PropDeclaringType, 
                                                             xamlPropertyNode.PropName,
                                                             xamlPropertyNode.PropValidType, 
                                                             BamlAttributeUsage.Default); 

            if (_deferLoadingSupport && _deferElementDepth > 0 && CollectingValues && 
                extensionTypeId == (short)KnownElements.StaticResourceExtension)
            {
                // If we are currently processing a StaticResourceExtension
                // within a deferable content section then the information in 
                // the xamlPropertyNode is distributed among two separate
                // BamlRecords viz. BamlOptimizedStaticResourceRecord which 
                // belongs in the header of the deferred section and a 
                // BamlPropertyWithStaticResourceIdRecord which is an inline
                // place holder for the same. 


                // Create and populate the BamlOptimizedStaticResourceRecord that
                // is stored in the header of the deferred section. 

                BamlOptimizedStaticResourceRecord bamlOptimizedStaticResource = 
                    (BamlOptimizedStaticResourceRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.OptimizedStaticResource); 

                bamlOptimizedStaticResource.IsValueTypeExtension = isValueTypeExtension; 
                bamlOptimizedStaticResource.IsValueStaticExtension = isValueStaticExtension;
                bamlOptimizedStaticResource.ValueId = valueId;

                _staticResourceRecordList = new List(1); 
                _staticResourceRecordList.Add(new ValueDeferRecord(
                    bamlOptimizedStaticResource, 
                    xamlPropertyNode.LineNumber, 
                    xamlPropertyNode.LinePosition));
 
                // Add the current StaticResource to the list on the current key record
                KeyDeferRecord keyDeferRecord = ((KeyDeferRecord)_deferKeys[_deferKeys.Count-1]);
                keyDeferRecord.StaticResourceRecordList.Add(_staticResourceRecordList);
 
                // Write a PropertyWithStaticResourceId to the values collection
                BamlPropertyWithStaticResourceIdRecord bamlPropertyWithStaticResourceId = 
                    (BamlPropertyWithStaticResourceIdRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyWithStaticResourceId); 

                bamlPropertyWithStaticResourceId.AttributeId = attributeId; 
                bamlPropertyWithStaticResourceId.StaticResourceId = (short)(keyDeferRecord.StaticResourceRecordList.Count-1);

                _deferValues.Add(new ValueDeferRecord(
                    bamlPropertyWithStaticResourceId, 
                    xamlPropertyNode.LineNumber,
                    xamlPropertyNode.LinePosition)); 
 
                _staticResourceRecordList = null;
            } 
            else
            {
                BamlPropertyWithExtensionRecord bamlPropertyWithExtension =
                    (BamlPropertyWithExtensionRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyWithExtension); 

                bamlPropertyWithExtension.AttributeId = attributeId; 
                bamlPropertyWithExtension.ExtensionTypeId = extensionTypeId; 
                bamlPropertyWithExtension.IsValueTypeExtension = isValueTypeExtension;
                bamlPropertyWithExtension.IsValueStaticExtension = isValueStaticExtension; 
                bamlPropertyWithExtension.ValueId = valueId;

                WriteAndReleaseRecord(bamlPropertyWithExtension, xamlPropertyNode);
            } 
        }
 
        // Write a property baml record for a property that is of type 'Type'.  This means 
        // that the baml record contains a typeid reference for a type which was resolved at
        // compile time. 
        internal virtual void WritePropertyWithType(XamlPropertyWithTypeNode xamlPropertyWithType)
        {
            short attributeId =
                    MapTable.AddAttributeInfoMap(BinaryWriter, 
                                                 xamlPropertyWithType.AssemblyName,
                                                 xamlPropertyWithType.TypeFullName, 
                                                 xamlPropertyWithType.PropDeclaringType, 
                                                 xamlPropertyWithType.PropName,
                                                 xamlPropertyWithType.PropValidType, 
                                                 BamlAttributeUsage.Default);

            // If we do not already have a type record for the type of this property,
            // then add a new TypeInfo record to the map table. 
            short typeId;
            if (!MapTable.GetTypeInfoId(BinaryWriter, 
                                        xamlPropertyWithType.ValueTypeAssemblyName, 
                                        xamlPropertyWithType.ValueTypeFullName,
                                        out typeId)) 
            {
                typeId = MapTable.AddTypeInfoMap(BinaryWriter,
                                                 xamlPropertyWithType.ValueTypeAssemblyName,
                                                 xamlPropertyWithType.ValueTypeFullName, 
                                                 xamlPropertyWithType.ValueElementType,
                                                 xamlPropertyWithType.ValueSerializerTypeAssemblyName, 
                                                 xamlPropertyWithType.ValueSerializerTypeFullName); 
            }
 
            BamlPropertyTypeReferenceRecord bamlProperty = BamlRecordManager.GetWriteRecord(
                                                          BamlRecordType.PropertyTypeReference) as BamlPropertyTypeReferenceRecord;

            bamlProperty.AttributeId = attributeId; 
            bamlProperty.TypeId = typeId;
 
            WriteAndReleaseRecord(bamlProperty, xamlPropertyWithType); 
        }
 
        // Write out property to BAML record, with the property value as a string.
        // This is used if the value cannot stream itself out directly, or if we
        // are creating a tree directly and not storing BAML to a file.
        internal void BaseWriteProperty(XamlPropertyNode xamlProperty) 
        {
            short attributeId = 
                    MapTable.AddAttributeInfoMap(BinaryWriter, 
                                                 xamlProperty.AssemblyName,
                                                 xamlProperty.TypeFullName, 
                                                 xamlProperty.PropDeclaringType,
                                                 xamlProperty.PropName,
                                                 xamlProperty.PropValidType,
                                                 xamlProperty.AttributeUsage); 

            BamlPropertyRecord bamlClrProperty = 
            (BamlPropertyRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.Property); 
            bamlClrProperty.AttributeId = attributeId;
            bamlClrProperty.Value = xamlProperty.Value; 
            WriteAndReleaseRecord(bamlClrProperty, xamlProperty);
        }

        internal void WriteClrEvent(XamlClrEventNode xamlClrEventNode) 
        {
            // This should have been overridden by AC to catch the CLR event case before 
            // this point is reached.  If not it means we have a designer which 
            // should have been given the pertinent information, so keep this as a placeholder,
            // but don't do anything now. 
        }

        // Write the start of an array property
        internal void WritePropertyArrayStart( 
            XamlPropertyArrayStartNode xamlPropertyArrayStartNode)
        { 
            // initialize the element and add to the stack 
            BamlPropertyArrayStartRecord bamlPropertyArrayStart =
                (BamlPropertyArrayStartRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyArrayStart); 

            bamlPropertyArrayStart.AttributeId =
                MapTable.AddAttributeInfoMap(BinaryWriter,
                                             xamlPropertyArrayStartNode.AssemblyName, 
                                             xamlPropertyArrayStartNode.TypeFullName,
                                             xamlPropertyArrayStartNode.PropDeclaringType, 
                                             xamlPropertyArrayStartNode.PropName, 
                                             null,
                                             BamlAttributeUsage.Default); 

            WriteAndReleaseRecord(bamlPropertyArrayStart, xamlPropertyArrayStartNode);
        }
 
        // Write the end of an array property
        internal virtual void WritePropertyArrayEnd( 
            XamlPropertyArrayEndNode xamlPropertyArrayEndNode) 
        {
            // initialize the element and add to the stack 
            BamlPropertyArrayEndRecord bamlPropertyArrayEndRecord =
                (BamlPropertyArrayEndRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyArrayEnd);

            WriteAndReleaseRecord(bamlPropertyArrayEndRecord, xamlPropertyArrayEndNode); 
        }
 
        // Write the start of a complex property that implements IList 
        internal void WritePropertyIListStart(
                XamlPropertyIListStartNode xamlPropertyIListStart) 
        {
            // initialize the element and add to the stack
            BamlPropertyIListStartRecord bamlPropertyIListStart =
                (BamlPropertyIListStartRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyIListStart); 

            bamlPropertyIListStart.AttributeId = 
                MapTable.AddAttributeInfoMap(BinaryWriter, 
                                             xamlPropertyIListStart.AssemblyName,
                                             xamlPropertyIListStart.TypeFullName, 
                                             xamlPropertyIListStart.PropDeclaringType,
                                             xamlPropertyIListStart.PropName,
                                             null,
                                             BamlAttributeUsage.Default); 

            WriteAndReleaseRecord(bamlPropertyIListStart, xamlPropertyIListStart); 
        } 

        // Write the end of a complex property that implements IList 
        internal virtual void WritePropertyIListEnd(
                XamlPropertyIListEndNode xamlPropertyIListEndNode)
        {
            // initialize the element and add to the stack 
            BamlPropertyIListEndRecord bamlPropertyIListEndRecord =
                (BamlPropertyIListEndRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyIListEnd); 
 
            WriteAndReleaseRecord(bamlPropertyIListEndRecord, xamlPropertyIListEndNode);
        } 

        // Write the start of a complex property that implements IDictionary
        internal void WritePropertyIDictionaryStart(
                XamlPropertyIDictionaryStartNode xamlPropertyIDictionaryStartNode) 
        {
            // initialize the element and add to the stack 
            BamlPropertyIDictionaryStartRecord bamlPropertyIDictionaryStart = 
                (BamlPropertyIDictionaryStartRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyIDictionaryStart);
 
            bamlPropertyIDictionaryStart.AttributeId =
                MapTable.AddAttributeInfoMap(BinaryWriter,
                                             xamlPropertyIDictionaryStartNode.AssemblyName,
                                             xamlPropertyIDictionaryStartNode.TypeFullName, 
                                             xamlPropertyIDictionaryStartNode.PropDeclaringType,
                                             xamlPropertyIDictionaryStartNode.PropName, 
                                             null, 
                                             BamlAttributeUsage.Default);
 
            WriteAndReleaseRecord(bamlPropertyIDictionaryStart, xamlPropertyIDictionaryStartNode);
       }

        // Write the end of a complex property that implements IDictionary 
        internal virtual void WritePropertyIDictionaryEnd(
                XamlPropertyIDictionaryEndNode xamlPropertyIDictionaryEndNode) 
        { 
            // initialize the element and add to the stack
            BamlPropertyIDictionaryEndRecord bamlPropertyIDictionaryEndRecord = 
                (BamlPropertyIDictionaryEndRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyIDictionaryEnd);

            WriteAndReleaseRecord(bamlPropertyIDictionaryEndRecord, xamlPropertyIDictionaryEndNode);
        } 

#if !PBTCOMPILER 
 
        // Write a routed event record
        internal void WriteRoutedEvent(XamlRoutedEventNode xamlRoutedEventNode) 
        {
            BamlRoutedEventRecord bamlEvent =
                (BamlRoutedEventRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.RoutedEvent);
 
            BamlAttributeInfoRecord bamlAttributeInfoRecord;
            MapTable.AddAttributeInfoMap(BinaryWriter, 
                                         xamlRoutedEventNode.AssemblyName, 
                                         xamlRoutedEventNode.TypeFullName,
                                         null, 
                                         xamlRoutedEventNode.EventName,
                                         null,
                                         BamlAttributeUsage.Default,
                                         out bamlAttributeInfoRecord); 

            bamlAttributeInfoRecord.Event = xamlRoutedEventNode.Event; // set the table value 
 
            bamlEvent.AttributeId = bamlAttributeInfoRecord.AttributeId;
            bamlEvent.Value = xamlRoutedEventNode.Value; 

            WriteAndReleaseRecord(bamlEvent, xamlRoutedEventNode);
        }
 
#endif
 
        // Write text content to baml 
        internal void WriteText(XamlTextNode xamlTextNode)
        { 
            BamlTextRecord bamlText;
            if (xamlTextNode.ConverterType == null)
            {
                if (!InStaticResourceSection && !InDynamicResourceSection) 
                {
                    bamlText = (BamlTextRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.Text); 
                } 
                else
                { 
                    bamlText = (BamlTextWithIdRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.TextWithId);

                    // Store the string value in the string table, since these records
                    // are often used as the key for a [Static/Dynamic]Resource. 
                    short valueId;
                    if (!MapTable.GetStringInfoId(xamlTextNode.Text, 
                                                  out valueId)) 
                    {
                        valueId = MapTable.AddStringInfoMap(BinaryWriter, 
                                                             xamlTextNode.Text);
                    }

                    ((BamlTextWithIdRecord)bamlText).ValueId = valueId; 
                }
            } 
            else 
            {
                bamlText = (BamlTextWithConverterRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.TextWithConverter); 

                short typeId;
                string converterAssemblyFullName = xamlTextNode.ConverterType.Assembly.FullName;
                string converterTypeFullName = xamlTextNode.ConverterType.FullName; 

                // If we do not already have a type record for the type of this converter, 
                // then add a new TypeInfo record to the map table. 
                if (!MapTable.GetTypeInfoId(BinaryWriter, converterAssemblyFullName,
                                            converterTypeFullName, 
                                            out typeId))
                {
                    typeId = MapTable.AddTypeInfoMap(BinaryWriter,
                                                     converterAssemblyFullName, 
                                                     converterTypeFullName,
                                                     xamlTextNode.ConverterType, 
                                                     string.Empty, 
                                                     string.Empty);
                } 
                ((BamlTextWithConverterRecord)bamlText).ConverterTypeId = typeId;
            }

             bamlText.Value = xamlTextNode.Text; 

             // up the parent node count, wait to update until endElement. 
 
             // add text to the Tree.
            WriteAndReleaseRecord(bamlText, xamlTextNode); 
        }

        // Helper to write out the baml record, with line numbers obtained from
        // the associated xaml node. 
        private void WriteAndReleaseRecord(
            BamlRecord    bamlRecord, 
            XamlNode      xamlNode) 
        {
            int lineNumber = xamlNode != null ? xamlNode.LineNumber : 0; 
            int linePosition = xamlNode != null ? xamlNode.LinePosition : 0;

            // If we are currently parsing a deferable content section, then queue
            // up the records for later writing 
            if (_deferLoadingSupport && _deferElementDepth > 0)
            { 
                if (InStaticResourceSection) 
                {
                    // Gather all the BamlRecords within the StaticResource section 
                    _staticResourceRecordList.Add(new ValueDeferRecord(bamlRecord, lineNumber, linePosition));
                }
                else
                { 
                    ValueDeferRecord deferRec = new ValueDeferRecord(bamlRecord,
                                                                     lineNumber, 
                                                                     linePosition); 
                    if (_deferEndOfStartReached)
                    { 
                        // If we are starting/ending a complex property, and we are at the same
                        // depth as the defered element, then track a mode so that we write to
                        // the _deferElement array instead of the key/value arrays.
                        if(_deferElementDepth == 1 && xamlNode is XamlPropertyComplexStartNode) 
                        {
                            _deferComplexPropertyDepth++; 
                        } 

                        if(_deferComplexPropertyDepth > 0) 
                        {
                            _deferElement.Add(deferRec);

                            if(_deferElementDepth == 1 && xamlNode is XamlPropertyComplexEndNode) 
                            {
                                _deferComplexPropertyDepth--; 
                            } 
                        }
                        else if (_deferKeyCollecting) 
                        {
                            ((KeyDeferRecord)_deferKeys[_deferKeys.Count-1]).RecordList.Add(deferRec);
                        }
                        else 
                        {
                            _deferValues.Add(deferRec); 
                        } 
                    }
                    else 
                    {
                        _deferElement.Add(deferRec);
                    }
                } 
            }
            else 
            { 
                WriteBamlRecord(bamlRecord,
                                lineNumber, 
                                linePosition);

                BamlRecordManager.ReleaseWriteRecord(bamlRecord);
            } 
        }
 
        // We've reached the end tag of a deferable content section.  Write out 
        // the following information, in order:
        //   1) Start record for deferable content element, and any properties 
        //      that are set on that element
        //   2) All keys for keyed content (if this is a dictionary)
        //   3) All value sections.  If this is a dictionary, then go back
        //      and update the positions in the key records to point to the value 
        //   4) End record for the deferable content element.
        private void WriteDeferableContent(XamlElementEndNode xamlNode) 
        { 
            // 1) Write Start record and all property information for the start tag
            for (int h = 0; h<_deferElement.Count; h++) 
            {
                ValueDeferRecord deferRecord = (ValueDeferRecord)_deferElement[h];
                WriteBamlRecord(deferRecord.Record,
                                deferRecord.LineNumber, 
                                deferRecord.LinePosition);
            } 
 
            // Find where the deferable content starts, which is after the end
            // of the start tag for the deferable element, and insert a deferable 
            // block start record here.
            BamlDeferableContentStartRecord bamlDeferableContentStart =
                (BamlDeferableContentStartRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.DeferableContentStart);
            WriteBamlRecord(bamlDeferableContentStart, 
                            xamlNode.LineNumber,
                            xamlNode.LinePosition); 
            Int64 endOfStart = BinaryWriter.Seek(0, SeekOrigin.Current); 

            // 2) Write key collection 
            for (int i = 0; i<_deferKeys.Count; i++)
            {
                KeyDeferRecord keyRecord = (KeyDeferRecord)_deferKeys[i];
                // If we don't have a Record stored here, then we didn't find a key 
                // for this dictionary entry.  In that case, throw an exception.
                // Otherwise loop through the records if there is a collection, or 
                // write out the single record if it is a simple key. 
                // NOTE:  Make sure to check the List before the individual record because
                //        the list of records takes precedence over a single record.  It is 
                //        possible for a single record to be stored first, and then later a
                //        Key Element in complex property is found which overrides the
                //        original key value.
                if (keyRecord.RecordList != null && 
                    keyRecord.RecordList.Count > 0)
                { 
                    for (int j = 0; j < keyRecord.RecordList.Count; j++) 
                    {
                        ValueDeferRecord keyValueRec = (ValueDeferRecord)keyRecord.RecordList[j]; 
                        WriteBamlRecord(keyValueRec.Record,
                                        keyValueRec.LineNumber,
                                        keyValueRec.LinePosition);
                    } 
                }
                else 
                { 
                    if (keyRecord.Record == null)
                    { 
                        XamlParser.ThrowException(SRID.ParserNoDictionaryKey,
                                              keyRecord.LineNumber,
                                              keyRecord.LinePosition);
                    } 
                    else
                    { 
                        WriteBamlRecord(keyRecord.Record, 
                                        keyRecord.LineNumber,
                                        keyRecord.LinePosition); 
                    }
                }

                // Write out the BamlRecords for all the StaticResources belonging to this key 
                List> staticResourceRecordList = keyRecord.StaticResourceRecordList;
                if (staticResourceRecordList.Count > 0) 
                { 
                    // Iterate through each one of the StaticResources in the list
                    for (int j=0; j srRecords = staticResourceRecordList[j];
                        for (int k=0; k 0)
                    {
                        ValueDeferRecord elementDeferRec = (ValueDeferRecord)(deferKeyRecord.RecordList[0]); 
                        keyRecord = (IBamlDictionaryKey)elementDeferRec.Record;
                    } 
                    else 
                    {
                        keyRecord = (IBamlDictionaryKey)deferKeyRecord.Record; 
                    }
                    Debug.Assert(keyRecord != null, "Unknown key record type in defer load dictionary");
                    if (keyRecord != null)
                    { 
                        keyRecord.UpdateValuePosition((Int32)(position-endOfKeys), BinaryWriter);
                    } 
                } 
                WriteBamlRecord(deferRecord.Record,
                                deferRecord.LineNumber, 
                                deferRecord.LinePosition);
            }

            Debug.Assert(keyIndex == _deferKeys.Count, 
                "Number of keys and values don't match");
 
            // 4) Write end record and update the content size in start record 
            Int64 startOfEnd = BinaryWriter.Seek(0, SeekOrigin.Current);
            bamlDeferableContentStart.UpdateContentSize((Int32)(startOfEnd - endOfStart), 
                                           BinaryWriter);

            BamlElementEndRecord bamlElementEnd =
                (BamlElementEndRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.ElementEnd); 
            WriteBamlRecord(bamlElementEnd,
                            xamlNode.LineNumber, 
                            xamlNode.LinePosition); 

            BamlRecordManager.ReleaseWriteRecord(bamlElementEnd); 

        }

        ///  
        /// This method is responsible for processing and writing out the StaticResource
        /// records that we have been gathering this far to DeferredContent 
        ///  
        private void WriteStaticResource()
        { 
            Debug.Assert(_deferElementDepth > 0 && CollectingValues,
                "Special processing of StaticResources happens only when collecting values within a deferred section");

            // Replace the first record in the list with the StaticResource start record 
            ValueDeferRecord valueDeferRecord = _staticResourceRecordList[0];
            int lineNumber = valueDeferRecord.LineNumber; 
            int linePosition = valueDeferRecord.LinePosition; 

            Debug.Assert(valueDeferRecord.Record != null && 
                         valueDeferRecord.Record.RecordType == BamlRecordType.ElementStart &&
                         ((BamlElementStartRecord)valueDeferRecord.Record).TypeId == BamlMapTable.GetKnownTypeIdFromType(KnownTypes.Types[(int)KnownElements.StaticResourceExtension]),
                "The first record in the list must be the ElementStart record for the StaticResourceExtension tag");
 
            BamlStaticResourceStartRecord bamlStaticResourceStart =
                (BamlStaticResourceStartRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.StaticResourceStart); 
            bamlStaticResourceStart.TypeId = ((BamlElementStartRecord)valueDeferRecord.Record).TypeId; 
            valueDeferRecord.Record = bamlStaticResourceStart;
 
            // Replace last record in the list with the StaticResource end record
            valueDeferRecord = _staticResourceRecordList[_staticResourceRecordList.Count-1];
            Debug.Assert(valueDeferRecord.Record != null && valueDeferRecord.Record.RecordType == BamlRecordType.ElementEnd,
                "The last record in the list must be the ElementEnd record for the StaticResourceExtension tag"); 

            BamlStaticResourceEndRecord bamlStaticResourceEnd = 
                (BamlStaticResourceEndRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.StaticResourceEnd); 
            valueDeferRecord.Record = bamlStaticResourceEnd;
 
            // Add the current StaticResource to the list on the current key record
            KeyDeferRecord keyDeferRecord = ((KeyDeferRecord)_deferKeys[_deferKeys.Count-1]);
            keyDeferRecord.StaticResourceRecordList.Add(_staticResourceRecordList);
 
            // Write a StaticResourceId to the values collection
            BamlStaticResourceIdRecord bamlStaticResourceId = 
                (BamlStaticResourceIdRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.StaticResourceId); 
            bamlStaticResourceId.StaticResourceId = (short)(keyDeferRecord.StaticResourceRecordList.Count-1);
 
            _deferValues.Add(new ValueDeferRecord(bamlStaticResourceId, lineNumber, linePosition));
        }

#endregion Record Writing 

#endregion Methods 
 
#region Private Classes
 
        // DeferRecord contains information about a BamlRecord or list of
        // BamlRecords that has not been written to the baml stream yet
        // because we are processing a deferable content element.
        private class DeferRecord 
        {
            internal DeferRecord ( 
                int        lineNumber, 
                int        linePosition)
            { 
                _lineNumber = lineNumber;
                _linePosition = linePosition;
            }
 
            internal int LineNumber
            { 
                get { return _lineNumber; } 
                set { _lineNumber = value; }
            } 

            internal int LinePosition
            {
                get { return _linePosition; } 
                set { _linePosition = value; }
            } 
 
            private int        _lineNumber;
            private int        _linePosition; 

        }

        private class ValueDeferRecord : DeferRecord 
        {
            internal ValueDeferRecord ( 
                BamlRecord record, 
                int        lineNumber,
                int        linePosition) : base(lineNumber, linePosition) 
            {
                _record = record;
                _updateOffset = false;
            } 

            internal BamlRecord Record 
            { 
                get { return _record; }
                set { _record = value; } 
            }

            internal bool UpdateOffset
            { 
                get { return _updateOffset; }
                set { _updateOffset = value; } 
            } 

            private bool       _updateOffset; 
            private BamlRecord _record;
        }

        private class KeyDeferRecord : DeferRecord 
        {
            internal KeyDeferRecord ( 
                int        lineNumber, 
                int        linePosition) : base(lineNumber, linePosition)
            { 
            }

            internal BamlRecord Record
            { 
                get { return _record; }
                set { _record = value; } 
            } 

            internal ArrayList RecordList 
            {
                get { return _recordList; }
                set { _recordList = value; }
            } 

            internal List> StaticResourceRecordList 
            { 
                get
                { 
                    if (_staticResourceRecordList == null)
                    {
                        _staticResourceRecordList = new List>(1);
                    } 

                    return _staticResourceRecordList; 
                } 
            }
 
            private BamlRecord _record;
            private ArrayList _recordList;
            private List> _staticResourceRecordList;
        } 

#endregion Private Classes 
 
#region Properties
 
#if PBTCOMPILER

        internal bool InDeferLoadedSection
        { 
            get { return _deferElementDepth > 0; }
        } 
 
#endif
 
        /// 
        /// returns stream that BamlRecordWriter is writing Baml records to
        /// 
        ///  
        public Stream BamlStream
        { 
            get { return _bamlStream; } 
        }
 
        internal BamlBinaryWriter BinaryWriter
        {
            get { return _bamlBinaryWriter; }
        } 

        internal BamlMapTable MapTable 
        { 
            get { return _bamlMapTable ; }
        } 

        internal ParserContext ParserContext
        {
            get { return _parserContext ; } 
        }
 
        internal virtual BamlRecordManager BamlRecordManager 
        {
            get { return _bamlRecordManager; } 
        }

        BamlDocumentStartRecord DocumentStartRecord
        { 
            get { return _startDocumentRecord; }
            set {  _startDocumentRecord = value; } 
        } 

        private bool CollectingValues 
        {
            get { return _deferEndOfStartReached && !_deferKeyCollecting && _deferComplexPropertyDepth <= 0; }
        }
 
        // ITypeDescriptorContext used when running type convertors on serializable
        // DP values. 
        ITypeDescriptorContext TypeConvertContext 
        {
            get 
            {
#if !PBTCOMPILER  // Don't run type converters for compilation
                if (null == _typeConvertContext)
                { 
                    _typeConvertContext = new TypeConvertContext(_parserContext);
                } 
 
                return _typeConvertContext;
#else 
                _typeConvertContext = null;
                return _typeConvertContext;
#endif
            } 
        }
 
        ///  
        /// Are we currently processing a StaticResource section?
        ///  
        private bool InStaticResourceSection
        {
            get { return _staticResourceElementDepth > 0; }
        } 

        ///  
        /// Are we currently processing a DynamicResource section? 
        /// 
        private bool InDynamicResourceSection 
        {
            get { return _dynamicResourceElementDepth > 0; }
        }
 
#endregion Properties
 
 
#region Data
        XamlTypeMapper          _xamlTypeMapper; 
        Stream                  _bamlStream;
        BamlBinaryWriter        _bamlBinaryWriter;

        BamlDocumentStartRecord _startDocumentRecord; 
        ParserContext           _parserContext;
        BamlMapTable            _bamlMapTable; 
        BamlRecordManager       _bamlRecordManager; 
        ITypeDescriptorContext  _typeConvertContext;
 
        bool                    _deferLoadingSupport;  // true if defer load of ResourceDictionary
                                                       // is enabled.
        int                     _deferElementDepth = 0;
 
        // True if we are processing a defered content element and we have reached the end
        // end of the start record for the element.  At this point all properties for that 
        // element have been collected. 
        bool                    _deferEndOfStartReached = false;
 
        // How deep are we in a complex property of a defered type?
        int                    _deferComplexPropertyDepth = 0;

        // True if we are processing a defered content block and we are collecting all the 
        // baml records that make up a single key for the keys section of defered content
        bool                    _deferKeyCollecting = false; 
 
        // List of keys for a defered content section.  Each item is a KeyDeferRecord
        ArrayList               _deferKeys; 

        // List of values for a defered content section.  Each item is a ValueDeferRecord
        ArrayList               _deferValues;       // Values in the dictionary
 
        // List of properties set on an element that is the root of a defered content
        // section.  Each item is a ValueDeferRecord. 
        ArrayList               _deferElement;      // Start tag and properties 
                                                    // of deferable content
 
        short                   _staticResourceElementDepth = 0; // Used to identify the StaticResource EndRecord

        short                   _dynamicResourceElementDepth = 0; // Used to identify the DynamicResource EndRecord
 
        List  _staticResourceRecordList;  // List of BamlRecords between the start and end of a StaticResource definition (both ends inclusive).
 
        bool                    _debugBamlStream; 
        int                     _lineNumber;
        int                     _linePosition; 
        BamlLineAndPositionRecord  _bamlLineAndPositionRecord;
        BamlLinePositionRecord     _bamlLinePositionRecord;

#endregion Data 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
/****************************************************************************\ 
*
* File: BamlRecordWriter.cs
*
* Purpose:  Helper class for writing BAML records 
*
* History: 
*    6/06/01:    rogerg        Created 
*    5/28/03:    peterost      Ported to wcp
*    10/6/03:    peterost      Reorganized to remove DP - clr distinction 
*
* Copyright (C) 2002 by Microsoft Corporation.  All rights reserved.
*
\***************************************************************************/ 

using System; 
using System.Xml; 
using System.IO;
using System.Text; 
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
 
using System.Diagnostics;
using System.Reflection; 
 
using MS.Utility;
 
#if !PBTCOMPILER

using System.Windows;
using System.Windows.Threading; 

#endif 
 
#if PBTCOMPILER
using System.Globalization; 

namespace MS.Internal.Markup
#else
namespace System.Windows.Markup 
#endif
{ 
 
    /// 
    /// Class for writing baml to a stream from XamlParser calls 
    /// 
    internal class BamlRecordWriter
    {
#region Constructor 

        ///  
        /// Constructor that allows defer loading feature to be enabled, even 
        /// for non-compile cases.
        ///  
        public BamlRecordWriter(
            Stream        stream,
            ParserContext parserContext,
            bool          deferLoadingSupport) 
        {
            _bamlStream = stream; 
            _xamlTypeMapper = parserContext.XamlTypeMapper; 
            _deferLoadingSupport = deferLoadingSupport;
            _bamlMapTable = parserContext.MapTable; 
            _parserContext = parserContext;

            _debugBamlStream = false;
            _lineNumber = -1; 
            _linePosition = -1;
 
            _bamlBinaryWriter = new BamlBinaryWriter(stream,new System.Text.UTF8Encoding()); 
            _bamlRecordManager = new BamlRecordManager();
        } 

#endregion Constructor

#region Methods 

 
        // Called by BamlRecordWriter records to persist a record. 
        internal virtual void WriteBamlRecord(
            BamlRecord bamlRecord, 
            int        lineNumber,
            int        linePosition)
        {
            try 
            {
                bamlRecord.Write(BinaryWriter); 
 
                if(DebugBamlStream)
                { 
                    if(BamlRecordHelper.DoesRecordTypeHaveDebugExtension(bamlRecord.RecordType))
                    {
                        WriteDebugExtensionRecord(lineNumber, linePosition);
                    } 
                }
            } 
            catch (XamlParseException e) 
            {
                _xamlTypeMapper.ThrowExceptionWithLine(e.Message, e.InnerException); 
            }
        }

        // Indicates if ParentNodes should be updated. 
        // This is only used when loading compiled baml so can have node information
        internal virtual bool UpdateParentNodes 
        { 
            get
            { 
                return true;
            }
        }
 
#if !PBTCOMPILER
        // review - this needs to check that setparseMode is called only 
        // once and only on the Root tag. 
        internal void SetParseMode(XamlParseMode xamlParseMode)
        { 
            // only update if we are allowed to update the parent nodes
            if (UpdateParentNodes)
            {
                 // update the parseMode in the StartRecord. 
                if (xamlParseMode == XamlParseMode.Asynchronous)
                { 
                    Debug.Assert(null != DocumentStartRecord); 
                    if (null != DocumentStartRecord)
                    { 
                        DocumentStartRecord.LoadAsync = true;
                        DocumentStartRecord.UpdateWrite(BinaryWriter);
                    }
                } 
            }
        } 
#endif 

        // Sets the number of Records that can be read at a time 
        // in async mode. Main use is for debugging.
        internal virtual void SetMaxAsyncRecords(int maxAsyncRecords)
        {
            // only update if we are allowed to update the parent nodes 
            if (UpdateParentNodes)
            { 
 
                Debug.Assert(null != DocumentStartRecord);
                if (null != DocumentStartRecord) 
                {
                    DocumentStartRecord.MaxAsyncRecords = maxAsyncRecords;
                    DocumentStartRecord.UpdateWrite(BinaryWriter);
                } 
            }
        } 
 
#region Record Writing
 
#region Debug Record Writing

        public bool DebugBamlStream
        { 
            get { return _debugBamlStream; }
#if PBTCOMPILER 
            set { _debugBamlStream = value; } 
#endif
        } 

        internal BamlLineAndPositionRecord LineAndPositionRecord
        {
            get 
            {
                if(_bamlLineAndPositionRecord == null) 
                { 
                    _bamlLineAndPositionRecord = new BamlLineAndPositionRecord();
                } 
                return _bamlLineAndPositionRecord;
            }
        }
 
        internal BamlLinePositionRecord LinePositionRecord
        { 
            get 
            {
                if(_bamlLinePositionRecord == null) 
                {
                    _bamlLinePositionRecord = new BamlLinePositionRecord();
                }
                return _bamlLinePositionRecord; 
            }
        } 
 
        internal void WriteDebugExtensionRecord(int lineNumber, int linePosition)
        { 
            // if the Linenumber has changed then the Position had also.
            // So write out a record with both Line and Position.
            if(lineNumber != _lineNumber)
            { 
                BamlLineAndPositionRecord rec = LineAndPositionRecord;
                _lineNumber = lineNumber; 
                rec.LineNumber = (uint)lineNumber; 

                _linePosition = linePosition; 
                rec.LinePosition = (uint)linePosition;

                rec.Write(BinaryWriter);
            } 
            // if the Line has NOT changed but the position has then
            // write a smaller record with just the position. 
            else if(linePosition != _linePosition) 
            {
                _linePosition = linePosition; 
                BamlLinePositionRecord rec = LinePositionRecord;
                rec.LinePosition = (uint)linePosition;
                rec.Write(BinaryWriter);
            } 
            // if neither has changed then don't waste space and
            // don't write a record. 
        } 

#endregion Debug Record Writing 

        // called to start writing the BAML
        internal void WriteDocumentStart(XamlDocumentStartNode xamlDocumentNode)
        { 
            // Always put a Version Block before the Document Start record.
            BamlVersionHeader bamlVersion = new BamlVersionHeader(); 
            bamlVersion.WriteVersion(BinaryWriter); 

            DocumentStartRecord = (BamlDocumentStartRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.DocumentStart); 
            DocumentStartRecord.DebugBaml = DebugBamlStream;

            // go ahead and write initial values to the Stream, will back fill.
            // the rootElement. 
            WriteBamlRecord(DocumentStartRecord, xamlDocumentNode.LineNumber,
                            xamlDocumentNode.LinePosition); 
 
            BamlRecordManager.ReleaseWriteRecord(DocumentStartRecord);
        } 

        // called when BAML is completely written
        internal void WriteDocumentEnd(XamlDocumentEndNode xamlDocumentEndNode)
        { 
            // write end of document record
            BamlDocumentEndRecord endDocument = 
                (BamlDocumentEndRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.DocumentEnd); 

            WriteBamlRecord(endDocument, xamlDocumentEndNode.LineNumber, 
                            xamlDocumentEndNode.LinePosition);

            BamlRecordManager.ReleaseWriteRecord(endDocument);
 
            // should be done now and evertying fully initialized.
        } 
 
        internal void WriteConnectionId(Int32 connectionId)
        { 
            BamlConnectionIdRecord bamlCxnId =
                   (BamlConnectionIdRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.ConnectionId);

            bamlCxnId.ConnectionId = connectionId; 
            WriteAndReleaseRecord(bamlCxnId, null);
        } 
 
        // following are for writing to the BAML
        // Somewhat mimics XMLTextWriter 
        internal void WriteElementStart(XamlElementStartNode xamlElementNode)
        {
            // initialize the element and add to the stack
            BamlElementStartRecord bamlElement = 
                   (BamlElementStartRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.ElementStart);
 
            // If we do not already have a type record for the type of this element, 
            // then add a new TypeInfo record to the map table.
            short typeId; 
            if (!MapTable.GetTypeInfoId(BinaryWriter,
                                        xamlElementNode.AssemblyName,
                                        xamlElementNode.TypeFullName,
                                        out typeId)) 
            {
                string serializerAssemblyName = string.Empty; 
                if (xamlElementNode.SerializerType != null) 
                {
                    serializerAssemblyName = xamlElementNode.SerializerType.Assembly.FullName; 
                }
                typeId = MapTable.AddTypeInfoMap(BinaryWriter,
                                                 xamlElementNode.AssemblyName,
                                                 xamlElementNode.TypeFullName, 
                                                 xamlElementNode.ElementType,
                                                 serializerAssemblyName, 
                                                 xamlElementNode.SerializerTypeFullName); 
            }
            bamlElement.TypeId = typeId; 
            bamlElement.CreateUsingTypeConverter = xamlElementNode.CreateUsingTypeConverter;
            bamlElement.IsInjected = xamlElementNode.IsInjected;

            // Check if the element we are about to write supports deferable content. 
            // If so, then we have to queue up all the baml records that are contained
            // within this element and extract key information (if this is a dictionary). 
            // At the end tag, the queued records will be written in an optimal order 
            // and offsets inserted to permit fast runtime indexing of content.
            if (_deferLoadingSupport && _deferElementDepth > 0) 
            {
                _deferElementDepth++;

                if (InStaticResourceSection) 
                {
                    // Gather all the BamlRecords within the StaticResource section 
                    _staticResourceElementDepth++; 
                    _staticResourceRecordList.Add(new ValueDeferRecord(bamlElement, xamlElementNode.LineNumber, xamlElementNode.LinePosition));
                } 
                else if (CollectingValues && KnownTypes.Types[(int)KnownElements.StaticResourceExtension] == xamlElementNode.ElementType)
                {
                    // Mark the beginning of a StaticResource section
                    _staticResourceElementDepth = 1; 
                    _staticResourceRecordList = new List(5);
                    _staticResourceRecordList.Add(new ValueDeferRecord(bamlElement, xamlElementNode.LineNumber, xamlElementNode.LinePosition)); 
                } 
                else
                { 
                    // Detect that we are within a DynamicResource Section.
                    if (InDynamicResourceSection)
                    {
                        _dynamicResourceElementDepth++; 
                    }
                    else if (CollectingValues && KnownTypes.Types[(int)KnownElements.DynamicResourceExtension] == xamlElementNode.ElementType) 
                    { 
                        _dynamicResourceElementDepth = 1;
                    } 

                    ValueDeferRecord deferRecord = new ValueDeferRecord(bamlElement,
                                            xamlElementNode.LineNumber,
                                            xamlElementNode.LinePosition); 

                    if(_deferComplexPropertyDepth > 0) 
                    { 
                        // If we are in the middle of a complex property specified for a defered
                        // type, we need to append to the _deferElement array. 
                        _deferElement.Add(deferRecord);
                    }
                    else if (_deferElementDepth == 2)
                    { 
                        // If this element is directly below the dictionary root, then put a
                        // placeholder record in the key collection.  If this is not filled 
                        // in before we reach the end of this element's scope, then we don't 
                        // have a key, and that's an error.
 
                        _deferKeys.Add(new KeyDeferRecord(xamlElementNode.LineNumber,
                                                          xamlElementNode.LinePosition));

                        // Remember that this element record is for the start of a value, 
                        // so that the offset in the associated key record should be set
                        // when this record is actually written out to the baml stream. 
                        deferRecord.UpdateOffset = true; 
                        _deferValues.Add(deferRecord);
                    } 
                    else if (_deferKeyCollecting)
                    {
                        // Don't allow a bind or resource reference in a deferable key, since this
                        // causes problems for resolution.  Multi-pass or recursive key resolution 
                        // would be needed to robustly support this feature.
                        if (typeof(String).IsAssignableFrom(xamlElementNode.ElementType) || 
                            KnownTypes.Types[(int)KnownElements.StaticExtension].IsAssignableFrom(xamlElementNode.ElementType) || 
                            KnownTypes.Types[(int)KnownElements.TypeExtension].IsAssignableFrom(xamlElementNode.ElementType))
                        { 
                            ((KeyDeferRecord)_deferKeys[_deferKeys.Count-1]).RecordList.Add(deferRecord);
                        }
                        else
                        { 
                            XamlParser.ThrowException(SRID.ParserBadKey,
                                                      xamlElementNode.TypeFullName, 
                                                      xamlElementNode.LineNumber, 
                                                      xamlElementNode.LinePosition);
                        } 

                    }
                    else
                    { 
                        _deferValues.Add(deferRecord);
                    } 
                } 
            }
            else if (_deferLoadingSupport && KnownTypes.Types[(int)KnownElements.ResourceDictionary].IsAssignableFrom(xamlElementNode.ElementType)) 
            {
                _deferElementDepth = 1;
                _deferEndOfStartReached = false;
                _deferElement = new ArrayList(2); 
                _deferKeys = new ArrayList(10);
                _deferValues = new ArrayList(100); 
 
                _deferElement.Add(new ValueDeferRecord(bamlElement,
                                        xamlElementNode.LineNumber, 
                                        xamlElementNode.LinePosition));
            }

            else 
            {
                WriteBamlRecord(bamlElement, xamlElementNode.LineNumber, 
                                xamlElementNode.LinePosition); 

                BamlRecordManager.ReleaseWriteRecord(bamlElement); 
            }
          }

        // The end of an element has been reached, so write out the end indication 
        internal void WriteElementEnd(XamlElementEndNode xamlElementEndNode)
        { 
             BamlElementEndRecord bamlElementEnd = 
                (BamlElementEndRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.ElementEnd);
 
            // Check if we're queuing up deferable content.  If so and we're at the
            // end tag for that content, now is the time to actually write everything
            // to the baml stream and rewrite in the file locations for the values
            // sections. 
            if (_deferLoadingSupport && _deferElementDepth > 0 && _deferElementDepth-- == 1)
            { 
                WriteDeferableContent(xamlElementEndNode); 

                // Clear all defer related instance data 
                Debug.Assert(_deferElementDepth == 0);
                Debug.Assert(_deferComplexPropertyDepth == 0);
                Debug.Assert(_staticResourceElementDepth == 0);
                Debug.Assert(_dynamicResourceElementDepth == 0); 
                Debug.Assert(_staticResourceRecordList == null);
                _deferKeys = null; 
                _deferValues = null; 
                _deferElement = null;
            } 
            else
            {
                WriteAndReleaseRecord(bamlElementEnd, xamlElementEndNode);
 
                if (_deferLoadingSupport && _staticResourceElementDepth > 0 && _staticResourceElementDepth-- == 1)
                { 
                    // This marks the end of a StaticResource section 

                    // Process the StaticResourceRecordList that we 
                    // have been gathering this far
                    WriteStaticResource();

                    // Cleanup the list after processing 
                    Debug.Assert(_staticResourceElementDepth == 0);
                    _staticResourceRecordList = null; 
                } 
                else if (_deferLoadingSupport && _dynamicResourceElementDepth > 0 && _dynamicResourceElementDepth-- == 1)
                { 
                    // We have now exited the dynamic resource section
                }
            }
 
            // we've come to the end of the element.
         } 
 
        // The end of the start tag has been reached.  For compile cases, check
        // if we are accumulating a deferable block of records. 
        internal void WriteEndAttributes(XamlEndAttributesNode xamlEndAttributesNode)
        {
            if (_deferLoadingSupport && _deferElementDepth > 0)
            { 
                _deferEndOfStartReached = true;
            } 
        } 

        // Write a literal content blob to BAML 
        internal void WriteLiteralContent(XamlLiteralContentNode xamlLiteralContentNode)
        {
            // initialize the element and add to the stack
            BamlLiteralContentRecord bamlLiteralContent = 
                (BamlLiteralContentRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.LiteralContent);
            bamlLiteralContent.Value = xamlLiteralContentNode.Content; 
 
            WriteAndReleaseRecord(bamlLiteralContent, xamlLiteralContentNode);
        } 

        // Write an x:Key="value" where value has been resolved to a Type object
        // at compile or parse time.  This means less reflection at runtime.
        internal void WriteDefAttributeKeyType(XamlDefAttributeKeyTypeNode xamlDefNode) 
        {
            Debug.Assert(!InStaticResourceSection, "We do not support x:Key within a StaticResource Section"); 
 
            // If we do not already have a type record for the type of this key,
            // then add a new TypeInfo record to the map table. 
            short typeId;
            if (!MapTable.GetTypeInfoId(BinaryWriter,
                                        xamlDefNode.AssemblyName,
                                        xamlDefNode.Value, 
                                        out typeId))
            { 
                typeId = MapTable.AddTypeInfoMap(BinaryWriter, 
                                                 xamlDefNode.AssemblyName,
                                                 xamlDefNode.Value, 
                                                 xamlDefNode.ValueType,
                                                 string.Empty,
                                                 string.Empty);
            } 

 
            BamlDefAttributeKeyTypeRecord bamlDefRecord = BamlRecordManager.GetWriteRecord( 
                                                          BamlRecordType.DefAttributeKeyType)
                                                          as BamlDefAttributeKeyTypeRecord; 

            bamlDefRecord.TypeId = typeId;
            ((IBamlDictionaryKey)bamlDefRecord).KeyObject = xamlDefNode.ValueType;
 
            // If we are currently parsing a deferable content section then store it
            // in the keys collection. 
            if (_deferLoadingSupport && 
                _deferElementDepth == 2)
            { 
                KeyDeferRecord keyRecord = (KeyDeferRecord)(_deferKeys[_deferKeys.Count-1]);

                TransferOldSharedData(keyRecord.Record as IBamlDictionaryKey, bamlDefRecord as IBamlDictionaryKey);
                keyRecord.Record = bamlDefRecord; 

                keyRecord.LineNumber = xamlDefNode.LineNumber; 
                keyRecord.LinePosition = xamlDefNode.LinePosition; 
                return;
            } 

            if (_deferLoadingSupport && _deferElementDepth > 0)
            {
                _deferValues.Add(new ValueDeferRecord(bamlDefRecord, 
                                            xamlDefNode.LineNumber,
                                            xamlDefNode.LinePosition)); 
            } 
            else
            { 
                WriteBamlRecord(bamlDefRecord, xamlDefNode.LineNumber,
                                    xamlDefNode.LinePosition);

                BamlRecordManager.ReleaseWriteRecord(bamlDefRecord); 
            }
        } 
 
        private void TransferOldSharedData(IBamlDictionaryKey oldRecord, IBamlDictionaryKey newRecord)
        { 
            if ((oldRecord != null) && (newRecord != null))
            {
                newRecord.Shared = oldRecord.Shared;
                newRecord.SharedSet = oldRecord.SharedSet; 
            }
        } 
 
        private IBamlDictionaryKey FindBamlDictionaryKey(KeyDeferRecord record)
        { 
            if (record != null)
            {
                if (record.RecordList != null)
                { 
                    for (int i = 0; i < record.RecordList.Count; i++)
                    { 
                        ValueDeferRecord valueDeferRecord = (ValueDeferRecord)record.RecordList[i]; 
                        IBamlDictionaryKey dictionaryKey = valueDeferRecord.Record as IBamlDictionaryKey;
                        if (dictionaryKey != null) 
                        {
                            return dictionaryKey;
                        }
                    } 
                }
 
                return record.Record as IBamlDictionaryKey; 
            }
 
            return null;
        }

        // Write a x:attribute="value" record.  One typical use of this is 
        // to specify the key to use when inserting the current object into
        // a Dictionary, but there can be other uses also 
        internal void WriteDefAttribute(XamlDefAttributeNode xamlDefNode) 
        {
 
            // If we are currently parsing a deferable content section, then check
            // to see if we have a dictionary key value here.  If so, then store it
            // in the keys collection.
            if (_deferLoadingSupport && 
                _deferElementDepth == 2 &&
                xamlDefNode.Name == XamlReaderHelper.DefinitionName) 
            { 
                Debug.Assert(!InStaticResourceSection, "We do not support x:Key within a StaticResource Section");
 
                // Note that if we get to here the assumption is that the value of the Name
                // attribute is *NOT* a MarkupExtension.  A MarkupExtension would cause
                // WriteKeyElementStart being called.
                KeyDeferRecord keyRecord = (KeyDeferRecord)(_deferKeys[_deferKeys.Count-1]); 
                BamlDefAttributeKeyStringRecord defKeyRecord = keyRecord.Record as BamlDefAttributeKeyStringRecord;
                if (defKeyRecord == null) 
                { 
                    defKeyRecord =
                        (BamlDefAttributeKeyStringRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.DefAttributeKeyString); 
                    TransferOldSharedData(keyRecord.Record as IBamlDictionaryKey, defKeyRecord as IBamlDictionaryKey);
                    keyRecord.Record = defKeyRecord;
                }
 
                // Store the string value in the string table, since there will mostly be a
                // [Static/Dynamic]Resource referring to it and we can combine the storage 
                // for both these string into a single StringInfoRecord. 
                short valueId;
                if (!MapTable.GetStringInfoId(xamlDefNode.Value, 
                                              out valueId))
                {
                    valueId = MapTable.AddStringInfoMap(BinaryWriter,
                                                         xamlDefNode.Value); 
                }
 
                defKeyRecord.Value = xamlDefNode.Value; 
                defKeyRecord.ValueId = valueId;
 
                keyRecord.LineNumber = xamlDefNode.LineNumber;
                keyRecord.LinePosition = xamlDefNode.LinePosition;
                return;
            } 
            else if (_deferLoadingSupport &&
                     _deferElementDepth == 2 && 
                     xamlDefNode.Name == XamlReaderHelper.DefinitionShared) 
            {
                Debug.Assert(!InStaticResourceSection, "We do not support x:Shared within a StaticResource Section"); 

                // NOTE:  This does not properly handle MarkupExtensions....
                KeyDeferRecord keyRecord = (KeyDeferRecord)(_deferKeys[_deferKeys.Count-1]);
 
                IBamlDictionaryKey defKeyRecord = FindBamlDictionaryKey(keyRecord);
                if (defKeyRecord == null) 
                { 
                    BamlDefAttributeKeyStringRecord defStringKeyRecord =
                        (BamlDefAttributeKeyStringRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.DefAttributeKeyString); 
                    keyRecord.Record = defStringKeyRecord;
                    defKeyRecord = (IBamlDictionaryKey)defStringKeyRecord;
                }
 
                defKeyRecord.Shared = Boolean.Parse(xamlDefNode.Value);
                defKeyRecord.SharedSet = true; 
                keyRecord.LineNumber = xamlDefNode.LineNumber; 
                keyRecord.LinePosition = xamlDefNode.LinePosition;
                return; 
            }

            // Add definition attribute record.  Store the attribute name in the string table, since
            // the names are likely to be repeated. 
            short stringId;
            if (!MapTable.GetStringInfoId(xamlDefNode.Name, 
                                          out stringId)) 
            {
                stringId = MapTable.AddStringInfoMap(BinaryWriter, 
                                                     xamlDefNode.Name);
            }

            BamlDefAttributeRecord defRecord = 
                (BamlDefAttributeRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.DefAttribute);
 
            defRecord.Value  = xamlDefNode.Value; 
            defRecord.Name   = xamlDefNode.Name;
            defRecord.AttributeUsage = xamlDefNode.AttributeUsage; 
            defRecord.NameId = stringId;

            WriteAndReleaseRecord(defRecord, xamlDefNode);
        } 

        // Attributes used to specify WPF-specific parsing options 
        internal void WritePresentationOptionsAttribute(XamlPresentationOptionsAttributeNode xamlPresentationOptionsNode) 
        {
            // Add definition attribute record.  Store the attribute name in the string table, since 
            // the names are likely to be repeated.
            short stringId;
            if (!MapTable.GetStringInfoId(xamlPresentationOptionsNode.Name,
                                          out stringId)) 
            {
                stringId = MapTable.AddStringInfoMap(BinaryWriter, 
                                                     xamlPresentationOptionsNode.Name); 
            }
 
            BamlPresentationOptionsAttributeRecord attributeRecord =
                (BamlPresentationOptionsAttributeRecord) BamlRecordManager.GetWriteRecord(
                                        BamlRecordType.PresentationOptionsAttribute);
 
            attributeRecord.Value = xamlPresentationOptionsNode.Value;
            attributeRecord.Name = xamlPresentationOptionsNode.Name; 
            attributeRecord.NameId = stringId; 

            WriteAndReleaseRecord(attributeRecord, xamlPresentationOptionsNode); 
        }


        // The current element contains xmlns combinations we want scoped in case 
        // InnerXAML is done at runtime.
        internal void WriteNamespacePrefix(XamlXmlnsPropertyNode xamlXmlnsPropertyNode) 
        { 
            BamlXmlnsPropertyRecord xmlnsRecord =
                (BamlXmlnsPropertyRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.XmlnsProperty); 

            xmlnsRecord.Prefix = xamlXmlnsPropertyNode.Prefix;
            xmlnsRecord.XmlNamespace  = xamlXmlnsPropertyNode.XmlNamespace;
 
#if PBTCOMPILER
 
            // 
            // Get a list of Assemblies that contain XmlnsDefinitionAttribute for the
            // specific XmlNamespace. Add the relevant assemblies into MapTable. 
            //

            if (xamlXmlnsPropertyNode.XmlNamespace.StartsWith(XamlReaderHelper.MappingProtocol, StringComparison.Ordinal) == false)
            { 
                NamespaceMapEntry[] nsMapEntry = _xamlTypeMapper.GetNamespaceMapEntries(xamlXmlnsPropertyNode.XmlNamespace);
 
                if (nsMapEntry != null && nsMapEntry.Length > 0) 
                {
                    ArrayList asmList = new ArrayList(); 
                    for (int i = 0; i < nsMapEntry.Length; i++)
                    {
                        string asmName = nsMapEntry[i].AssemblyName;
 
                        if (!asmList.Contains(asmName))
                        { 
                            asmList.Add(asmName); 
                        }
                    } 

                    if (asmList.Count > 0)
                    {
                        short[] assemblyIds = new short[asmList.Count]; 

                        for (int i = 0; i < asmList.Count; i++) 
                        { 
                            BamlAssemblyInfoRecord bamlAssemblyInfoRecord = MapTable.AddAssemblyMap(BinaryWriter, (string)asmList[i]);
 
                            assemblyIds[i] = bamlAssemblyInfoRecord.AssemblyId;
                        }

                        xmlnsRecord.AssemblyIds = assemblyIds; 
                    }
                } 
            } 

#endif 


            // NOTE:  If we are defining a new namespace prefix in the value object's
            //        start record, AND using that prefix in x:Key, then we have a 
            //        problem, since the x:Key keys are hoisted out before this
            //        record in the baml stream....  I don't have a solution for 
            //        this yet, but this isn't an issue for theme files... 
            WriteAndReleaseRecord(xmlnsRecord, xamlXmlnsPropertyNode);
        } 

        // Write a xml to clr namespace mapping record
        internal void WritePIMapping(XamlPIMappingNode xamlPIMappingNode)
        { 
            BamlPIMappingRecord piMappingRecord =
                (BamlPIMappingRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PIMapping); 
 
            BamlAssemblyInfoRecord bamlAssemblyInfoRecord = MapTable.AddAssemblyMap(BinaryWriter,
                                                                  xamlPIMappingNode.AssemblyName); 

            piMappingRecord.XmlNamespace = xamlPIMappingNode.XmlNamespace;
            piMappingRecord.ClrNamespace = xamlPIMappingNode.ClrNamespace;
            piMappingRecord.AssemblyId   = bamlAssemblyInfoRecord.AssemblyId; 

            WriteBamlRecord(piMappingRecord, xamlPIMappingNode.LineNumber, 
                            xamlPIMappingNode.LinePosition); 

            BamlRecordManager.ReleaseWriteRecord(piMappingRecord); 
        }

        // Write the start of a complex property
        internal void WritePropertyComplexStart(XamlPropertyComplexStartNode 
                                    xamlComplexPropertyNode)
        { 
            // review same as property + flag, combine code 
            BamlPropertyComplexStartRecord bamlComplexProperty =
                (BamlPropertyComplexStartRecord) BamlRecordManager.GetWriteRecord( 
                                                        BamlRecordType.PropertyComplexStart);

            bamlComplexProperty.AttributeId =
                MapTable.AddAttributeInfoMap(BinaryWriter, 
                                             xamlComplexPropertyNode.AssemblyName,
                                             xamlComplexPropertyNode.TypeFullName, 
                                             xamlComplexPropertyNode.PropDeclaringType, 
                                             xamlComplexPropertyNode.PropName,
                                             xamlComplexPropertyNode.PropValidType, 
                                             BamlAttributeUsage.Default);

            WriteAndReleaseRecord(bamlComplexProperty, xamlComplexPropertyNode);
        } 

        // Write the end of a complex property 
        internal void WritePropertyComplexEnd( 
            XamlPropertyComplexEndNode xamlPropertyComplexEnd)
        { 
            BamlPropertyComplexEndRecord endPropertyRecord =
                (BamlPropertyComplexEndRecord) BamlRecordManager.GetWriteRecord(
                                                         BamlRecordType.PropertyComplexEnd);
 
            WriteAndReleaseRecord(endPropertyRecord, xamlPropertyComplexEnd);
        } 
 
        // Write the start of a def attribute element used as the key in an
        // IDictionary 
        public void WriteKeyElementStart(
            XamlElementStartNode xamlKeyElementNode)
        {
            Debug.Assert(!InStaticResourceSection, "We do not support x:Key within a StaticResource Section"); 

            // Don't allow a bind or resource reference in a key element, since this 
            // causes problems for resolution.  Multi-pass or recursive key resolution 
            // would be needed to robustly support this feature.
            if (!typeof(String).IsAssignableFrom(xamlKeyElementNode.ElementType) && 
                !KnownTypes.Types[(int)KnownElements.StaticExtension].IsAssignableFrom(xamlKeyElementNode.ElementType) &&
                !KnownTypes.Types[(int)KnownElements.TypeExtension].IsAssignableFrom(xamlKeyElementNode.ElementType) &&
                !KnownTypes.Types[(int)KnownElements.ResourceKey].IsAssignableFrom(xamlKeyElementNode.ElementType))
            { 
                XamlParser.ThrowException(SRID.ParserBadKey,
                                          xamlKeyElementNode.TypeFullName, 
                                          xamlKeyElementNode.LineNumber, 
                                          xamlKeyElementNode.LinePosition);
            } 

            // initialize the element and add to the stack
            BamlKeyElementStartRecord bamlElement =
                   (BamlKeyElementStartRecord) BamlRecordManager.GetWriteRecord( 
                                               BamlRecordType.KeyElementStart);
 
            // If we do not already have a type record for the type of this element, 
            // then add a new TypeInfo record to the map table.
            short typeId; 
            if (!MapTable.GetTypeInfoId(BinaryWriter,
                                        xamlKeyElementNode.AssemblyName,
                                        xamlKeyElementNode.TypeFullName,
                                        out typeId)) 
            {
                string serializerAssemblyName = string.Empty; 
                if (xamlKeyElementNode.SerializerType != null) 
                {
                    serializerAssemblyName = xamlKeyElementNode.SerializerType.Assembly.FullName; 
                }
                typeId = MapTable.AddTypeInfoMap(BinaryWriter,
                                                 xamlKeyElementNode.AssemblyName,
                                                 xamlKeyElementNode.TypeFullName, 
                                                 xamlKeyElementNode.ElementType,
                                                 serializerAssemblyName, 
                                                 xamlKeyElementNode.SerializerTypeFullName); 
            }
            bamlElement.TypeId = typeId; 

            // Check if the element we are about to write supports deferable content.
            // If so, then we have to queue up all the baml records that are contained
            // within this element and use this as a key (if this is a dictionary). 
            // At the end tag, the queued records will be written in an optimal order
            // and offsets inserted to permit fast runtime indexing of content. 
            if (_deferLoadingSupport && _deferElementDepth == 2) 
            {
                _deferElementDepth++; 
                _deferKeyCollecting = true;

                KeyDeferRecord keyRecord = (KeyDeferRecord)(_deferKeys[_deferKeys.Count-1]);
                keyRecord.RecordList = new ArrayList(5); 

                Debug.Assert(keyRecord.RecordList.Count == 0, "Should have empty record list"); 
                keyRecord.RecordList.Add(new ValueDeferRecord(bamlElement, 
                                                              xamlKeyElementNode.LineNumber,
                                                              xamlKeyElementNode.LinePosition)); 

                if (keyRecord.Record != null)
                {
                    TransferOldSharedData(keyRecord.Record as IBamlDictionaryKey, bamlElement as IBamlDictionaryKey); 
                    keyRecord.Record = null;
                } 
 
                keyRecord.LineNumber = xamlKeyElementNode.LineNumber;
                keyRecord.LinePosition = xamlKeyElementNode.LinePosition; 
                return;
            }
            else
            { 
                WriteAndReleaseRecord(bamlElement, xamlKeyElementNode);
            } 
        } 

        // Write the end of a def attribute tree section used as the key 
        // in an IDictionary
        internal void WriteKeyElementEnd(
            XamlElementEndNode xamlKeyElementEnd)
        { 
            Debug.Assert(!InStaticResourceSection, "We do not support x:Key within a StaticResource Section");
 
            BamlKeyElementEndRecord endRecord = 
                (BamlKeyElementEndRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.KeyElementEnd);
 
            WriteAndReleaseRecord(endRecord, xamlKeyElementEnd);

            if (_deferLoadingSupport && _deferKeyCollecting)
            { 
                _deferKeyCollecting = false;
                _deferElementDepth--; 
                Debug.Assert(_deferElementDepth == 2); 
            }
        } 

#if PBTCOMPILER
        /// 
        /// Write the constructor parameter that has been resolved to a Type 
        /// 
        internal void WriteConstructorParameterType( 
            XamlConstructorParameterTypeNode xamlConstructorParameterTypeNode) 
        {
            // If we do not already have a type record for the type of this property, 
            // then add a new TypeInfo record to the map table.
            short typeId;
            if (!MapTable.GetTypeInfoId(BinaryWriter,
                                        xamlConstructorParameterTypeNode.ValueTypeAssemblyName, 
                                        xamlConstructorParameterTypeNode.ValueTypeFullName,
                                        out typeId)) 
            { 
                typeId = MapTable.AddTypeInfoMap(BinaryWriter,
                                                 xamlConstructorParameterTypeNode.ValueTypeAssemblyName, 
                                                 xamlConstructorParameterTypeNode.ValueTypeFullName,
                                                 xamlConstructorParameterTypeNode.ValueElementType,
                                                 string.Empty,
                                                 string.Empty); 
            }
 
 
            BamlConstructorParameterTypeRecord bamlConstructor = BamlRecordManager.GetWriteRecord(
                                                          BamlRecordType.ConstructorParameterType) 
                                                          as BamlConstructorParameterTypeRecord;
            bamlConstructor.TypeId = typeId;

            WriteAndReleaseRecord(bamlConstructor, xamlConstructorParameterTypeNode); 
        }
#endif 
 
        /// 
        /// Write the start of a constructor parameter section 
        /// 
        internal void WriteConstructorParametersStart(
            XamlConstructorParametersStartNode xamlConstructorParametersStartNode)
        { 
            // Create a new baml record
            BamlConstructorParametersStartRecord startRecord = 
                (BamlConstructorParametersStartRecord) BamlRecordManager.GetWriteRecord( 
                     BamlRecordType.ConstructorParametersStart);
 
            WriteAndReleaseRecord(startRecord, xamlConstructorParametersStartNode);
        }

        ///  
        /// Write the end of a constructor parameter section
        ///  
        internal void WriteConstructorParametersEnd( 
            XamlConstructorParametersEndNode xamlConstructorParametersEndNode)
        { 
            // Create a new baml record
            BamlConstructorParametersEndRecord startRecord =
                (BamlConstructorParametersEndRecord) BamlRecordManager.GetWriteRecord(
                     BamlRecordType.ConstructorParametersEnd); 

            WriteAndReleaseRecord(startRecord, xamlConstructorParametersEndNode); 
        } 

        internal virtual void WriteContentProperty(XamlContentPropertyNode xamlContentPropertyNode) 
        {
            BamlContentPropertyRecord bamlContentPropertyRecord =
                (BamlContentPropertyRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.ContentProperty);
 
            bamlContentPropertyRecord.AttributeId =
                MapTable.AddAttributeInfoMap(BinaryWriter, 
                                             xamlContentPropertyNode.AssemblyName, 
                                             xamlContentPropertyNode.TypeFullName,
                                             xamlContentPropertyNode.PropDeclaringType, 
                                             xamlContentPropertyNode.PropName,
                                             xamlContentPropertyNode.PropValidType,
                                             BamlAttributeUsage.Default);
 
            WriteAndReleaseRecord(bamlContentPropertyRecord, xamlContentPropertyNode);
        } 
 
        // Write a property baml record.  If the type of this property supports
        // custom serialization or type conversion, then write out a special property 
        // record.  Otherwise write out a 'normal' record, which will cause type
        // converter resolution to happen at load time.

 
        internal virtual void WriteProperty(XamlPropertyNode xamlProperty)
        { 
            short attributeId = 
                    MapTable.AddAttributeInfoMap(BinaryWriter,
                                                 xamlProperty.AssemblyName, 
                                                 xamlProperty.TypeFullName,
                                                 xamlProperty.PropDeclaringType,
                                                 xamlProperty.PropName,
                                                 xamlProperty.PropValidType, 
                                                 xamlProperty.AttributeUsage);
 
            if (xamlProperty.AssemblyName != string.Empty && xamlProperty.TypeFullName != string.Empty) 
            {
                short converterOrSerializerTypeId; 
                Type  converterOrSerializerType;
                bool isCustomSerializer = MapTable.GetCustomSerializerOrConverter(
                              BinaryWriter,
                              xamlProperty.ValueDeclaringType, 
                              xamlProperty.ValuePropertyType,
                              xamlProperty.ValuePropertyMember, 
                              xamlProperty.ValuePropertyName, 
                          out converterOrSerializerTypeId,
                          out converterOrSerializerType); 

                if (converterOrSerializerType != null)
                {
                    if (isCustomSerializer) 
                    {
                        BamlPropertyCustomWriteInfoRecord bamlPropertyCustom = 
                            (BamlPropertyCustomWriteInfoRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyCustom); 
                        bamlPropertyCustom.AttributeId = attributeId;
                        bamlPropertyCustom.Value = xamlProperty.Value; 
                        bamlPropertyCustom.ValueType = xamlProperty.ValuePropertyType;
                        bamlPropertyCustom.SerializerTypeId = converterOrSerializerTypeId;
                        bamlPropertyCustom.SerializerType = converterOrSerializerType;
                        bamlPropertyCustom.TypeContext = TypeConvertContext; 
                        if (converterOrSerializerTypeId == (short)KnownElements.DependencyPropertyConverter)
                        { 
                            // if ValueId\MemberName have alredy been resolved, just write it out. 
                            if (xamlProperty.HasValueId)
                            { 
                                bamlPropertyCustom.ValueId = xamlProperty.ValueId;
                                bamlPropertyCustom.ValueMemberName = xamlProperty.MemberName;
                            }
                            else 
                            {
                                // else try to resolve the DP value of this property now 
                                string dpName; 

                                // get the ownerType and name of the DP value 
                                Type ownerType = _xamlTypeMapper.GetDependencyPropertyOwnerAndName(xamlProperty.Value,
                                                                                                   ParserContext,
                                                                                                   xamlProperty.DefaultTargetType,
                                                                                               out dpName); 
                                short typeId;
 
                                // get the known property Id or TypeId of the owner of the DP value 
                                short propertyId = MapTable.GetAttributeOrTypeId(BinaryWriter,
                                                                                 ownerType, 
                                                                                 dpName,
                                                                             out typeId);

                                // write it out as appropriate. 
                                if (propertyId < 0)
                                { 
                                    bamlPropertyCustom.ValueId = propertyId; 
                                    bamlPropertyCustom.ValueMemberName = null;
                                } 
                                else
                                {
                                    bamlPropertyCustom.ValueId = typeId;
                                    bamlPropertyCustom.ValueMemberName = dpName; 
                                }
                            } 
                        } 

                        WriteAndReleaseRecord(bamlPropertyCustom, xamlProperty); 
                    }
                    else
                    {
                        BamlPropertyWithConverterRecord bamlPropertyWithConverter = (BamlPropertyWithConverterRecord)BamlRecordManager.GetWriteRecord( 
                                                              BamlRecordType.PropertyWithConverter);
                        bamlPropertyWithConverter.AttributeId = attributeId; 
                        bamlPropertyWithConverter.Value = xamlProperty.Value; 
                        bamlPropertyWithConverter.ConverterTypeId = converterOrSerializerTypeId;
                        WriteAndReleaseRecord(bamlPropertyWithConverter, xamlProperty); 
                    }

                    return;
                } 
            }
 
            BaseWriteProperty(xamlProperty); 
        }
 
        internal virtual void WritePropertyWithExtension(XamlPropertyWithExtensionNode xamlPropertyNode)
        {
            short valueId = 0;
            short extensionTypeId = xamlPropertyNode.ExtensionTypeId; 
            bool isValueTypeExtension = false;
            bool isValueStaticExtension = false; 
            Debug.Assert(extensionTypeId != (short)KnownElements.TypeExtension); 

            // if the extension is a DynamicResourceExtension or a StaticResourceExtension 
            // dig in to see if its param is a simple extension or just a string.
            if ((extensionTypeId == (short)KnownElements.DynamicResourceExtension) ||
                (extensionTypeId == (short)KnownElements.StaticResourceExtension))
            { 
                // if the value is a simple nested extension
                if (xamlPropertyNode.IsValueNestedExtension) 
                { 
                    // Yes, see if it is a TypeExtension or StaticExtension
                    if (xamlPropertyNode.IsValueTypeExtension) 
                    {
                        // nested TypeExtension value
                        Type typeValue = _xamlTypeMapper.GetTypeFromBaseString(xamlPropertyNode.Value,
                                                                               ParserContext, 
                                                                               true);
                        Debug.Assert(typeValue != null); 
                        if (!MapTable.GetTypeInfoId(BinaryWriter, 
                                                    typeValue.Assembly.FullName,
                                                    typeValue.FullName, 
                                                    out valueId))
                        {
                            valueId = MapTable.AddTypeInfoMap(BinaryWriter,
                                                              typeValue.Assembly.FullName, 
                                                              typeValue.FullName,
                                                              typeValue, 
                                                              string.Empty, 
                                                              string.Empty);
                        } 

                        isValueTypeExtension = true;
                    }
                    else 
                    {
                        // nested StaticExtension value 
                        valueId = MapTable.GetStaticMemberId(BinaryWriter, 
                                                             ParserContext,
                                                             (short)KnownElements.StaticExtension, 
                                                             xamlPropertyNode.Value,
                                                             xamlPropertyNode.DefaultTargetType);

                        isValueStaticExtension = true; 
                    }
                } 
                else 
                {
                    // No, it is a string value. 
                    // Store the string value in the string table, since these records
                    // are already used as the key for a [Static/Dynamic]Resource.
                    if (!MapTable.GetStringInfoId(xamlPropertyNode.Value, out valueId))
                    { 
                        valueId = MapTable.AddStringInfoMap(BinaryWriter, xamlPropertyNode.Value);
                    } 
                } 
            }
            else 
            {
                // toplevel StaticExtension or TemplateBindingExtension value
                valueId = MapTable.GetStaticMemberId(BinaryWriter,
                                                     ParserContext, 
                                                     extensionTypeId,
                                                     xamlPropertyNode.Value, 
                                                     xamlPropertyNode.DefaultTargetType); 
            }
 
            short attributeId = MapTable.AddAttributeInfoMap(BinaryWriter,
                                                             xamlPropertyNode.AssemblyName,
                                                             xamlPropertyNode.TypeFullName,
                                                             xamlPropertyNode.PropDeclaringType, 
                                                             xamlPropertyNode.PropName,
                                                             xamlPropertyNode.PropValidType, 
                                                             BamlAttributeUsage.Default); 

            if (_deferLoadingSupport && _deferElementDepth > 0 && CollectingValues && 
                extensionTypeId == (short)KnownElements.StaticResourceExtension)
            {
                // If we are currently processing a StaticResourceExtension
                // within a deferable content section then the information in 
                // the xamlPropertyNode is distributed among two separate
                // BamlRecords viz. BamlOptimizedStaticResourceRecord which 
                // belongs in the header of the deferred section and a 
                // BamlPropertyWithStaticResourceIdRecord which is an inline
                // place holder for the same. 


                // Create and populate the BamlOptimizedStaticResourceRecord that
                // is stored in the header of the deferred section. 

                BamlOptimizedStaticResourceRecord bamlOptimizedStaticResource = 
                    (BamlOptimizedStaticResourceRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.OptimizedStaticResource); 

                bamlOptimizedStaticResource.IsValueTypeExtension = isValueTypeExtension; 
                bamlOptimizedStaticResource.IsValueStaticExtension = isValueStaticExtension;
                bamlOptimizedStaticResource.ValueId = valueId;

                _staticResourceRecordList = new List(1); 
                _staticResourceRecordList.Add(new ValueDeferRecord(
                    bamlOptimizedStaticResource, 
                    xamlPropertyNode.LineNumber, 
                    xamlPropertyNode.LinePosition));
 
                // Add the current StaticResource to the list on the current key record
                KeyDeferRecord keyDeferRecord = ((KeyDeferRecord)_deferKeys[_deferKeys.Count-1]);
                keyDeferRecord.StaticResourceRecordList.Add(_staticResourceRecordList);
 
                // Write a PropertyWithStaticResourceId to the values collection
                BamlPropertyWithStaticResourceIdRecord bamlPropertyWithStaticResourceId = 
                    (BamlPropertyWithStaticResourceIdRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyWithStaticResourceId); 

                bamlPropertyWithStaticResourceId.AttributeId = attributeId; 
                bamlPropertyWithStaticResourceId.StaticResourceId = (short)(keyDeferRecord.StaticResourceRecordList.Count-1);

                _deferValues.Add(new ValueDeferRecord(
                    bamlPropertyWithStaticResourceId, 
                    xamlPropertyNode.LineNumber,
                    xamlPropertyNode.LinePosition)); 
 
                _staticResourceRecordList = null;
            } 
            else
            {
                BamlPropertyWithExtensionRecord bamlPropertyWithExtension =
                    (BamlPropertyWithExtensionRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyWithExtension); 

                bamlPropertyWithExtension.AttributeId = attributeId; 
                bamlPropertyWithExtension.ExtensionTypeId = extensionTypeId; 
                bamlPropertyWithExtension.IsValueTypeExtension = isValueTypeExtension;
                bamlPropertyWithExtension.IsValueStaticExtension = isValueStaticExtension; 
                bamlPropertyWithExtension.ValueId = valueId;

                WriteAndReleaseRecord(bamlPropertyWithExtension, xamlPropertyNode);
            } 
        }
 
        // Write a property baml record for a property that is of type 'Type'.  This means 
        // that the baml record contains a typeid reference for a type which was resolved at
        // compile time. 
        internal virtual void WritePropertyWithType(XamlPropertyWithTypeNode xamlPropertyWithType)
        {
            short attributeId =
                    MapTable.AddAttributeInfoMap(BinaryWriter, 
                                                 xamlPropertyWithType.AssemblyName,
                                                 xamlPropertyWithType.TypeFullName, 
                                                 xamlPropertyWithType.PropDeclaringType, 
                                                 xamlPropertyWithType.PropName,
                                                 xamlPropertyWithType.PropValidType, 
                                                 BamlAttributeUsage.Default);

            // If we do not already have a type record for the type of this property,
            // then add a new TypeInfo record to the map table. 
            short typeId;
            if (!MapTable.GetTypeInfoId(BinaryWriter, 
                                        xamlPropertyWithType.ValueTypeAssemblyName, 
                                        xamlPropertyWithType.ValueTypeFullName,
                                        out typeId)) 
            {
                typeId = MapTable.AddTypeInfoMap(BinaryWriter,
                                                 xamlPropertyWithType.ValueTypeAssemblyName,
                                                 xamlPropertyWithType.ValueTypeFullName, 
                                                 xamlPropertyWithType.ValueElementType,
                                                 xamlPropertyWithType.ValueSerializerTypeAssemblyName, 
                                                 xamlPropertyWithType.ValueSerializerTypeFullName); 
            }
 
            BamlPropertyTypeReferenceRecord bamlProperty = BamlRecordManager.GetWriteRecord(
                                                          BamlRecordType.PropertyTypeReference) as BamlPropertyTypeReferenceRecord;

            bamlProperty.AttributeId = attributeId; 
            bamlProperty.TypeId = typeId;
 
            WriteAndReleaseRecord(bamlProperty, xamlPropertyWithType); 
        }
 
        // Write out property to BAML record, with the property value as a string.
        // This is used if the value cannot stream itself out directly, or if we
        // are creating a tree directly and not storing BAML to a file.
        internal void BaseWriteProperty(XamlPropertyNode xamlProperty) 
        {
            short attributeId = 
                    MapTable.AddAttributeInfoMap(BinaryWriter, 
                                                 xamlProperty.AssemblyName,
                                                 xamlProperty.TypeFullName, 
                                                 xamlProperty.PropDeclaringType,
                                                 xamlProperty.PropName,
                                                 xamlProperty.PropValidType,
                                                 xamlProperty.AttributeUsage); 

            BamlPropertyRecord bamlClrProperty = 
            (BamlPropertyRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.Property); 
            bamlClrProperty.AttributeId = attributeId;
            bamlClrProperty.Value = xamlProperty.Value; 
            WriteAndReleaseRecord(bamlClrProperty, xamlProperty);
        }

        internal void WriteClrEvent(XamlClrEventNode xamlClrEventNode) 
        {
            // This should have been overridden by AC to catch the CLR event case before 
            // this point is reached.  If not it means we have a designer which 
            // should have been given the pertinent information, so keep this as a placeholder,
            // but don't do anything now. 
        }

        // Write the start of an array property
        internal void WritePropertyArrayStart( 
            XamlPropertyArrayStartNode xamlPropertyArrayStartNode)
        { 
            // initialize the element and add to the stack 
            BamlPropertyArrayStartRecord bamlPropertyArrayStart =
                (BamlPropertyArrayStartRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyArrayStart); 

            bamlPropertyArrayStart.AttributeId =
                MapTable.AddAttributeInfoMap(BinaryWriter,
                                             xamlPropertyArrayStartNode.AssemblyName, 
                                             xamlPropertyArrayStartNode.TypeFullName,
                                             xamlPropertyArrayStartNode.PropDeclaringType, 
                                             xamlPropertyArrayStartNode.PropName, 
                                             null,
                                             BamlAttributeUsage.Default); 

            WriteAndReleaseRecord(bamlPropertyArrayStart, xamlPropertyArrayStartNode);
        }
 
        // Write the end of an array property
        internal virtual void WritePropertyArrayEnd( 
            XamlPropertyArrayEndNode xamlPropertyArrayEndNode) 
        {
            // initialize the element and add to the stack 
            BamlPropertyArrayEndRecord bamlPropertyArrayEndRecord =
                (BamlPropertyArrayEndRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyArrayEnd);

            WriteAndReleaseRecord(bamlPropertyArrayEndRecord, xamlPropertyArrayEndNode); 
        }
 
        // Write the start of a complex property that implements IList 
        internal void WritePropertyIListStart(
                XamlPropertyIListStartNode xamlPropertyIListStart) 
        {
            // initialize the element and add to the stack
            BamlPropertyIListStartRecord bamlPropertyIListStart =
                (BamlPropertyIListStartRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyIListStart); 

            bamlPropertyIListStart.AttributeId = 
                MapTable.AddAttributeInfoMap(BinaryWriter, 
                                             xamlPropertyIListStart.AssemblyName,
                                             xamlPropertyIListStart.TypeFullName, 
                                             xamlPropertyIListStart.PropDeclaringType,
                                             xamlPropertyIListStart.PropName,
                                             null,
                                             BamlAttributeUsage.Default); 

            WriteAndReleaseRecord(bamlPropertyIListStart, xamlPropertyIListStart); 
        } 

        // Write the end of a complex property that implements IList 
        internal virtual void WritePropertyIListEnd(
                XamlPropertyIListEndNode xamlPropertyIListEndNode)
        {
            // initialize the element and add to the stack 
            BamlPropertyIListEndRecord bamlPropertyIListEndRecord =
                (BamlPropertyIListEndRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyIListEnd); 
 
            WriteAndReleaseRecord(bamlPropertyIListEndRecord, xamlPropertyIListEndNode);
        } 

        // Write the start of a complex property that implements IDictionary
        internal void WritePropertyIDictionaryStart(
                XamlPropertyIDictionaryStartNode xamlPropertyIDictionaryStartNode) 
        {
            // initialize the element and add to the stack 
            BamlPropertyIDictionaryStartRecord bamlPropertyIDictionaryStart = 
                (BamlPropertyIDictionaryStartRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyIDictionaryStart);
 
            bamlPropertyIDictionaryStart.AttributeId =
                MapTable.AddAttributeInfoMap(BinaryWriter,
                                             xamlPropertyIDictionaryStartNode.AssemblyName,
                                             xamlPropertyIDictionaryStartNode.TypeFullName, 
                                             xamlPropertyIDictionaryStartNode.PropDeclaringType,
                                             xamlPropertyIDictionaryStartNode.PropName, 
                                             null, 
                                             BamlAttributeUsage.Default);
 
            WriteAndReleaseRecord(bamlPropertyIDictionaryStart, xamlPropertyIDictionaryStartNode);
       }

        // Write the end of a complex property that implements IDictionary 
        internal virtual void WritePropertyIDictionaryEnd(
                XamlPropertyIDictionaryEndNode xamlPropertyIDictionaryEndNode) 
        { 
            // initialize the element and add to the stack
            BamlPropertyIDictionaryEndRecord bamlPropertyIDictionaryEndRecord = 
                (BamlPropertyIDictionaryEndRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.PropertyIDictionaryEnd);

            WriteAndReleaseRecord(bamlPropertyIDictionaryEndRecord, xamlPropertyIDictionaryEndNode);
        } 

#if !PBTCOMPILER 
 
        // Write a routed event record
        internal void WriteRoutedEvent(XamlRoutedEventNode xamlRoutedEventNode) 
        {
            BamlRoutedEventRecord bamlEvent =
                (BamlRoutedEventRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.RoutedEvent);
 
            BamlAttributeInfoRecord bamlAttributeInfoRecord;
            MapTable.AddAttributeInfoMap(BinaryWriter, 
                                         xamlRoutedEventNode.AssemblyName, 
                                         xamlRoutedEventNode.TypeFullName,
                                         null, 
                                         xamlRoutedEventNode.EventName,
                                         null,
                                         BamlAttributeUsage.Default,
                                         out bamlAttributeInfoRecord); 

            bamlAttributeInfoRecord.Event = xamlRoutedEventNode.Event; // set the table value 
 
            bamlEvent.AttributeId = bamlAttributeInfoRecord.AttributeId;
            bamlEvent.Value = xamlRoutedEventNode.Value; 

            WriteAndReleaseRecord(bamlEvent, xamlRoutedEventNode);
        }
 
#endif
 
        // Write text content to baml 
        internal void WriteText(XamlTextNode xamlTextNode)
        { 
            BamlTextRecord bamlText;
            if (xamlTextNode.ConverterType == null)
            {
                if (!InStaticResourceSection && !InDynamicResourceSection) 
                {
                    bamlText = (BamlTextRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.Text); 
                } 
                else
                { 
                    bamlText = (BamlTextWithIdRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.TextWithId);

                    // Store the string value in the string table, since these records
                    // are often used as the key for a [Static/Dynamic]Resource. 
                    short valueId;
                    if (!MapTable.GetStringInfoId(xamlTextNode.Text, 
                                                  out valueId)) 
                    {
                        valueId = MapTable.AddStringInfoMap(BinaryWriter, 
                                                             xamlTextNode.Text);
                    }

                    ((BamlTextWithIdRecord)bamlText).ValueId = valueId; 
                }
            } 
            else 
            {
                bamlText = (BamlTextWithConverterRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.TextWithConverter); 

                short typeId;
                string converterAssemblyFullName = xamlTextNode.ConverterType.Assembly.FullName;
                string converterTypeFullName = xamlTextNode.ConverterType.FullName; 

                // If we do not already have a type record for the type of this converter, 
                // then add a new TypeInfo record to the map table. 
                if (!MapTable.GetTypeInfoId(BinaryWriter, converterAssemblyFullName,
                                            converterTypeFullName, 
                                            out typeId))
                {
                    typeId = MapTable.AddTypeInfoMap(BinaryWriter,
                                                     converterAssemblyFullName, 
                                                     converterTypeFullName,
                                                     xamlTextNode.ConverterType, 
                                                     string.Empty, 
                                                     string.Empty);
                } 
                ((BamlTextWithConverterRecord)bamlText).ConverterTypeId = typeId;
            }

             bamlText.Value = xamlTextNode.Text; 

             // up the parent node count, wait to update until endElement. 
 
             // add text to the Tree.
            WriteAndReleaseRecord(bamlText, xamlTextNode); 
        }

        // Helper to write out the baml record, with line numbers obtained from
        // the associated xaml node. 
        private void WriteAndReleaseRecord(
            BamlRecord    bamlRecord, 
            XamlNode      xamlNode) 
        {
            int lineNumber = xamlNode != null ? xamlNode.LineNumber : 0; 
            int linePosition = xamlNode != null ? xamlNode.LinePosition : 0;

            // If we are currently parsing a deferable content section, then queue
            // up the records for later writing 
            if (_deferLoadingSupport && _deferElementDepth > 0)
            { 
                if (InStaticResourceSection) 
                {
                    // Gather all the BamlRecords within the StaticResource section 
                    _staticResourceRecordList.Add(new ValueDeferRecord(bamlRecord, lineNumber, linePosition));
                }
                else
                { 
                    ValueDeferRecord deferRec = new ValueDeferRecord(bamlRecord,
                                                                     lineNumber, 
                                                                     linePosition); 
                    if (_deferEndOfStartReached)
                    { 
                        // If we are starting/ending a complex property, and we are at the same
                        // depth as the defered element, then track a mode so that we write to
                        // the _deferElement array instead of the key/value arrays.
                        if(_deferElementDepth == 1 && xamlNode is XamlPropertyComplexStartNode) 
                        {
                            _deferComplexPropertyDepth++; 
                        } 

                        if(_deferComplexPropertyDepth > 0) 
                        {
                            _deferElement.Add(deferRec);

                            if(_deferElementDepth == 1 && xamlNode is XamlPropertyComplexEndNode) 
                            {
                                _deferComplexPropertyDepth--; 
                            } 
                        }
                        else if (_deferKeyCollecting) 
                        {
                            ((KeyDeferRecord)_deferKeys[_deferKeys.Count-1]).RecordList.Add(deferRec);
                        }
                        else 
                        {
                            _deferValues.Add(deferRec); 
                        } 
                    }
                    else 
                    {
                        _deferElement.Add(deferRec);
                    }
                } 
            }
            else 
            { 
                WriteBamlRecord(bamlRecord,
                                lineNumber, 
                                linePosition);

                BamlRecordManager.ReleaseWriteRecord(bamlRecord);
            } 
        }
 
        // We've reached the end tag of a deferable content section.  Write out 
        // the following information, in order:
        //   1) Start record for deferable content element, and any properties 
        //      that are set on that element
        //   2) All keys for keyed content (if this is a dictionary)
        //   3) All value sections.  If this is a dictionary, then go back
        //      and update the positions in the key records to point to the value 
        //   4) End record for the deferable content element.
        private void WriteDeferableContent(XamlElementEndNode xamlNode) 
        { 
            // 1) Write Start record and all property information for the start tag
            for (int h = 0; h<_deferElement.Count; h++) 
            {
                ValueDeferRecord deferRecord = (ValueDeferRecord)_deferElement[h];
                WriteBamlRecord(deferRecord.Record,
                                deferRecord.LineNumber, 
                                deferRecord.LinePosition);
            } 
 
            // Find where the deferable content starts, which is after the end
            // of the start tag for the deferable element, and insert a deferable 
            // block start record here.
            BamlDeferableContentStartRecord bamlDeferableContentStart =
                (BamlDeferableContentStartRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.DeferableContentStart);
            WriteBamlRecord(bamlDeferableContentStart, 
                            xamlNode.LineNumber,
                            xamlNode.LinePosition); 
            Int64 endOfStart = BinaryWriter.Seek(0, SeekOrigin.Current); 

            // 2) Write key collection 
            for (int i = 0; i<_deferKeys.Count; i++)
            {
                KeyDeferRecord keyRecord = (KeyDeferRecord)_deferKeys[i];
                // If we don't have a Record stored here, then we didn't find a key 
                // for this dictionary entry.  In that case, throw an exception.
                // Otherwise loop through the records if there is a collection, or 
                // write out the single record if it is a simple key. 
                // NOTE:  Make sure to check the List before the individual record because
                //        the list of records takes precedence over a single record.  It is 
                //        possible for a single record to be stored first, and then later a
                //        Key Element in complex property is found which overrides the
                //        original key value.
                if (keyRecord.RecordList != null && 
                    keyRecord.RecordList.Count > 0)
                { 
                    for (int j = 0; j < keyRecord.RecordList.Count; j++) 
                    {
                        ValueDeferRecord keyValueRec = (ValueDeferRecord)keyRecord.RecordList[j]; 
                        WriteBamlRecord(keyValueRec.Record,
                                        keyValueRec.LineNumber,
                                        keyValueRec.LinePosition);
                    } 
                }
                else 
                { 
                    if (keyRecord.Record == null)
                    { 
                        XamlParser.ThrowException(SRID.ParserNoDictionaryKey,
                                              keyRecord.LineNumber,
                                              keyRecord.LinePosition);
                    } 
                    else
                    { 
                        WriteBamlRecord(keyRecord.Record, 
                                        keyRecord.LineNumber,
                                        keyRecord.LinePosition); 
                    }
                }

                // Write out the BamlRecords for all the StaticResources belonging to this key 
                List> staticResourceRecordList = keyRecord.StaticResourceRecordList;
                if (staticResourceRecordList.Count > 0) 
                { 
                    // Iterate through each one of the StaticResources in the list
                    for (int j=0; j srRecords = staticResourceRecordList[j];
                        for (int k=0; k 0)
                    {
                        ValueDeferRecord elementDeferRec = (ValueDeferRecord)(deferKeyRecord.RecordList[0]); 
                        keyRecord = (IBamlDictionaryKey)elementDeferRec.Record;
                    } 
                    else 
                    {
                        keyRecord = (IBamlDictionaryKey)deferKeyRecord.Record; 
                    }
                    Debug.Assert(keyRecord != null, "Unknown key record type in defer load dictionary");
                    if (keyRecord != null)
                    { 
                        keyRecord.UpdateValuePosition((Int32)(position-endOfKeys), BinaryWriter);
                    } 
                } 
                WriteBamlRecord(deferRecord.Record,
                                deferRecord.LineNumber, 
                                deferRecord.LinePosition);
            }

            Debug.Assert(keyIndex == _deferKeys.Count, 
                "Number of keys and values don't match");
 
            // 4) Write end record and update the content size in start record 
            Int64 startOfEnd = BinaryWriter.Seek(0, SeekOrigin.Current);
            bamlDeferableContentStart.UpdateContentSize((Int32)(startOfEnd - endOfStart), 
                                           BinaryWriter);

            BamlElementEndRecord bamlElementEnd =
                (BamlElementEndRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.ElementEnd); 
            WriteBamlRecord(bamlElementEnd,
                            xamlNode.LineNumber, 
                            xamlNode.LinePosition); 

            BamlRecordManager.ReleaseWriteRecord(bamlElementEnd); 

        }

        ///  
        /// This method is responsible for processing and writing out the StaticResource
        /// records that we have been gathering this far to DeferredContent 
        ///  
        private void WriteStaticResource()
        { 
            Debug.Assert(_deferElementDepth > 0 && CollectingValues,
                "Special processing of StaticResources happens only when collecting values within a deferred section");

            // Replace the first record in the list with the StaticResource start record 
            ValueDeferRecord valueDeferRecord = _staticResourceRecordList[0];
            int lineNumber = valueDeferRecord.LineNumber; 
            int linePosition = valueDeferRecord.LinePosition; 

            Debug.Assert(valueDeferRecord.Record != null && 
                         valueDeferRecord.Record.RecordType == BamlRecordType.ElementStart &&
                         ((BamlElementStartRecord)valueDeferRecord.Record).TypeId == BamlMapTable.GetKnownTypeIdFromType(KnownTypes.Types[(int)KnownElements.StaticResourceExtension]),
                "The first record in the list must be the ElementStart record for the StaticResourceExtension tag");
 
            BamlStaticResourceStartRecord bamlStaticResourceStart =
                (BamlStaticResourceStartRecord)BamlRecordManager.GetWriteRecord(BamlRecordType.StaticResourceStart); 
            bamlStaticResourceStart.TypeId = ((BamlElementStartRecord)valueDeferRecord.Record).TypeId; 
            valueDeferRecord.Record = bamlStaticResourceStart;
 
            // Replace last record in the list with the StaticResource end record
            valueDeferRecord = _staticResourceRecordList[_staticResourceRecordList.Count-1];
            Debug.Assert(valueDeferRecord.Record != null && valueDeferRecord.Record.RecordType == BamlRecordType.ElementEnd,
                "The last record in the list must be the ElementEnd record for the StaticResourceExtension tag"); 

            BamlStaticResourceEndRecord bamlStaticResourceEnd = 
                (BamlStaticResourceEndRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.StaticResourceEnd); 
            valueDeferRecord.Record = bamlStaticResourceEnd;
 
            // Add the current StaticResource to the list on the current key record
            KeyDeferRecord keyDeferRecord = ((KeyDeferRecord)_deferKeys[_deferKeys.Count-1]);
            keyDeferRecord.StaticResourceRecordList.Add(_staticResourceRecordList);
 
            // Write a StaticResourceId to the values collection
            BamlStaticResourceIdRecord bamlStaticResourceId = 
                (BamlStaticResourceIdRecord) BamlRecordManager.GetWriteRecord(BamlRecordType.StaticResourceId); 
            bamlStaticResourceId.StaticResourceId = (short)(keyDeferRecord.StaticResourceRecordList.Count-1);
 
            _deferValues.Add(new ValueDeferRecord(bamlStaticResourceId, lineNumber, linePosition));
        }

#endregion Record Writing 

#endregion Methods 
 
#region Private Classes
 
        // DeferRecord contains information about a BamlRecord or list of
        // BamlRecords that has not been written to the baml stream yet
        // because we are processing a deferable content element.
        private class DeferRecord 
        {
            internal DeferRecord ( 
                int        lineNumber, 
                int        linePosition)
            { 
                _lineNumber = lineNumber;
                _linePosition = linePosition;
            }
 
            internal int LineNumber
            { 
                get { return _lineNumber; } 
                set { _lineNumber = value; }
            } 

            internal int LinePosition
            {
                get { return _linePosition; } 
                set { _linePosition = value; }
            } 
 
            private int        _lineNumber;
            private int        _linePosition; 

        }

        private class ValueDeferRecord : DeferRecord 
        {
            internal ValueDeferRecord ( 
                BamlRecord record, 
                int        lineNumber,
                int        linePosition) : base(lineNumber, linePosition) 
            {
                _record = record;
                _updateOffset = false;
            } 

            internal BamlRecord Record 
            { 
                get { return _record; }
                set { _record = value; } 
            }

            internal bool UpdateOffset
            { 
                get { return _updateOffset; }
                set { _updateOffset = value; } 
            } 

            private bool       _updateOffset; 
            private BamlRecord _record;
        }

        private class KeyDeferRecord : DeferRecord 
        {
            internal KeyDeferRecord ( 
                int        lineNumber, 
                int        linePosition) : base(lineNumber, linePosition)
            { 
            }

            internal BamlRecord Record
            { 
                get { return _record; }
                set { _record = value; } 
            } 

            internal ArrayList RecordList 
            {
                get { return _recordList; }
                set { _recordList = value; }
            } 

            internal List> StaticResourceRecordList 
            { 
                get
                { 
                    if (_staticResourceRecordList == null)
                    {
                        _staticResourceRecordList = new List>(1);
                    } 

                    return _staticResourceRecordList; 
                } 
            }
 
            private BamlRecord _record;
            private ArrayList _recordList;
            private List> _staticResourceRecordList;
        } 

#endregion Private Classes 
 
#region Properties
 
#if PBTCOMPILER

        internal bool InDeferLoadedSection
        { 
            get { return _deferElementDepth > 0; }
        } 
 
#endif
 
        /// 
        /// returns stream that BamlRecordWriter is writing Baml records to
        /// 
        ///  
        public Stream BamlStream
        { 
            get { return _bamlStream; } 
        }
 
        internal BamlBinaryWriter BinaryWriter
        {
            get { return _bamlBinaryWriter; }
        } 

        internal BamlMapTable MapTable 
        { 
            get { return _bamlMapTable ; }
        } 

        internal ParserContext ParserContext
        {
            get { return _parserContext ; } 
        }
 
        internal virtual BamlRecordManager BamlRecordManager 
        {
            get { return _bamlRecordManager; } 
        }

        BamlDocumentStartRecord DocumentStartRecord
        { 
            get { return _startDocumentRecord; }
            set {  _startDocumentRecord = value; } 
        } 

        private bool CollectingValues 
        {
            get { return _deferEndOfStartReached && !_deferKeyCollecting && _deferComplexPropertyDepth <= 0; }
        }
 
        // ITypeDescriptorContext used when running type convertors on serializable
        // DP values. 
        ITypeDescriptorContext TypeConvertContext 
        {
            get 
            {
#if !PBTCOMPILER  // Don't run type converters for compilation
                if (null == _typeConvertContext)
                { 
                    _typeConvertContext = new TypeConvertContext(_parserContext);
                } 
 
                return _typeConvertContext;
#else 
                _typeConvertContext = null;
                return _typeConvertContext;
#endif
            } 
        }
 
        ///  
        /// Are we currently processing a StaticResource section?
        ///  
        private bool InStaticResourceSection
        {
            get { return _staticResourceElementDepth > 0; }
        } 

        ///  
        /// Are we currently processing a DynamicResource section? 
        /// 
        private bool InDynamicResourceSection 
        {
            get { return _dynamicResourceElementDepth > 0; }
        }
 
#endregion Properties
 
 
#region Data
        XamlTypeMapper          _xamlTypeMapper; 
        Stream                  _bamlStream;
        BamlBinaryWriter        _bamlBinaryWriter;

        BamlDocumentStartRecord _startDocumentRecord; 
        ParserContext           _parserContext;
        BamlMapTable            _bamlMapTable; 
        BamlRecordManager       _bamlRecordManager; 
        ITypeDescriptorContext  _typeConvertContext;
 
        bool                    _deferLoadingSupport;  // true if defer load of ResourceDictionary
                                                       // is enabled.
        int                     _deferElementDepth = 0;
 
        // True if we are processing a defered content element and we have reached the end
        // end of the start record for the element.  At this point all properties for that 
        // element have been collected. 
        bool                    _deferEndOfStartReached = false;
 
        // How deep are we in a complex property of a defered type?
        int                    _deferComplexPropertyDepth = 0;

        // True if we are processing a defered content block and we are collecting all the 
        // baml records that make up a single key for the keys section of defered content
        bool                    _deferKeyCollecting = false; 
 
        // List of keys for a defered content section.  Each item is a KeyDeferRecord
        ArrayList               _deferKeys; 

        // List of values for a defered content section.  Each item is a ValueDeferRecord
        ArrayList               _deferValues;       // Values in the dictionary
 
        // List of properties set on an element that is the root of a defered content
        // section.  Each item is a ValueDeferRecord. 
        ArrayList               _deferElement;      // Start tag and properties 
                                                    // of deferable content
 
        short                   _staticResourceElementDepth = 0; // Used to identify the StaticResource EndRecord

        short                   _dynamicResourceElementDepth = 0; // Used to identify the DynamicResource EndRecord
 
        List  _staticResourceRecordList;  // List of BamlRecords between the start and end of a StaticResource definition (both ends inclusive).
 
        bool                    _debugBamlStream; 
        int                     _lineNumber;
        int                     _linePosition; 
        BamlLineAndPositionRecord  _bamlLineAndPositionRecord;
        BamlLinePositionRecord     _bamlLinePositionRecord;

#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