// 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<ValueDeferRecord>(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);
            }
          }
        // 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);
            }
        }