ReadSubtree() private method

private ReadSubtree ( ) : XamlReader
return XamlReader
        // We get here when we are inside x:ClassAttributes or x:Property.Attributes. We expect the first element to be the Attribute SO.
        internal static AttributeData LoadAttributeData(XamlReader reader, NamespaceTable namespaceTable, string rootNamespace)
        {
            AttributeData attributeData = null;
            reader.Read();
            if (reader.NodeType == XamlNodeType.StartObject)
            {
                attributeData = new AttributeData { Type = reader.Type };

                bool readNext = false;
                while (readNext || reader.Read())
                {
                    namespaceTable.ManageNamespace(reader);
                    readNext = false;
                    if (reader.NodeType == XamlNodeType.StartMember)
                    {
                        if (reader.Member == XamlLanguage.Arguments)
                        {
                            foreach (AttributeParameterData parameterData in ReadParameters(reader.ReadSubtree(), namespaceTable, rootNamespace))
                            {
                                attributeData.Parameters.Add(parameterData);
                            }
                            readNext = true;
                        }
                        else if (!reader.Member.IsDirective)
                        {
                            KeyValuePair<string, AttributeParameterData> propertyInfo = ReadAttributeProperty(reader.ReadSubtree(), namespaceTable, rootNamespace);
                            attributeData.Properties.Add(propertyInfo.Key, propertyInfo.Value);
                            readNext = true;
                        }
                    }
                }
            }
            return attributeData;
        }
        // This method reads a ViewStateData node from the xaml nodestream. It outputs the Id property into viewStateId
        // and the attached viewstate related properties in viewStateNodes. The input reader is positioned on a 
        // ViewStateData node within ViewStateManager.
        static void ReadViewState(XamlType viewStateType, XamlReader xamlReader, out string viewStateId, out XamlNodeList viewStateNodes, out SourceLocation sourceLocation)
        {
            int globalMemberLevel = 0;
            bool skippingUnexpectedAttachedProperty = false;
            int skippingUnexpectedAttachedPropertyLevel = 0;
            viewStateId = null;
            viewStateNodes = new XamlNodeList(viewStateType.SchemaContext);
            sourceLocation = null;

            Stack<Frame> objectNodes = new Stack<Frame>();
            XamlMember idMember = new XamlMember(typeof(ViewStateData).GetProperty("Id"), xamlReader.SchemaContext);
            int[] viewStateDataSourceLocation = new int[4];
            int sourceLocationIndex = -1;

            IXamlLineInfo lineInfo = xamlReader as IXamlLineInfo;
            IXamlLineInfoConsumer lineInfoComsumer = viewStateNodes.Writer as IXamlLineInfoConsumer;
            bool shouldPassLineInfo = lineInfo != null && lineInfo.HasLineInfo && lineInfoComsumer != null && lineInfoComsumer.ShouldProvideLineInfo;

            while (xamlReader.Read())
            {
                bool skipWritingToNodeList = false;
                switch (xamlReader.NodeType)
                {
                    case XamlNodeType.StartObject:
                        if (xamlReader.Type.Equals(viewStateType))
                        {
                            skipWritingToNodeList = true;
                        }
                        objectNodes.Push(new Frame { Type = xamlReader.Type });
                        break;

                    case XamlNodeType.GetObject:
                        objectNodes.Push(new Frame { Type = null });
                        break;

                    case XamlNodeType.StartMember:
                        globalMemberLevel++;
                        if (xamlReader.Member.Equals(idMember))
                        {
                            XamlReader idNode = xamlReader.ReadSubtree();
                            while (idNode.Read())
                            {
                                if (idNode.NodeType == XamlNodeType.Value)
                                {
                                    viewStateId = idNode.Value as string;
                                }
                            }
                        } 
                        else if (globalMemberLevel == 1 && !IsAttachablePropertyForConvert(xamlReader)) 
                        {
                            skippingUnexpectedAttachedProperty = true;
                        }
                        if (skippingUnexpectedAttachedProperty)
                        {
                            skippingUnexpectedAttachedPropertyLevel++;
                        }

                        sourceLocationIndex = GetViewStateDataSourceLocationIndexFromCurrentReader(xamlReader);
                        break;

                    case XamlNodeType.EndMember:
                        globalMemberLevel--;
                        if (skippingUnexpectedAttachedProperty)
                        {
                            skippingUnexpectedAttachedPropertyLevel--;
                        }
                        break;
                    case XamlNodeType.Value:
                        if (xamlReader.Value is int
                            && sourceLocationIndex >= 0 
                            && sourceLocationIndex < viewStateDataSourceLocation.Length)
                        {
                            viewStateDataSourceLocation[sourceLocationIndex] = (int)xamlReader.Value;
                        }

                        break;
                    case XamlNodeType.EndObject:
                        Frame objectNode = objectNodes.Pop();
                        if (objectNode.Type != null && objectNode.Type.Equals(viewStateType))
                        {
                            skipWritingToNodeList = true;
                            // The ViewStateData's source location should be valid, because
                            // before each EndObject, its SourceLocation is injected.
                            // If not, an exception will be thrown from constructor 
                            // of SourceLocation.
                            sourceLocation = new SourceLocation(null,
                                viewStateDataSourceLocation[0],
                                viewStateDataSourceLocation[1],
                                viewStateDataSourceLocation[2],
                                viewStateDataSourceLocation[3]
                                );
                        }

                        Array.Clear(viewStateDataSourceLocation, 0, viewStateDataSourceLocation.Length);
                        break;
                };

                if (!skipWritingToNodeList && !skippingUnexpectedAttachedProperty)
                {
                    if (shouldPassLineInfo)
                    {
                        lineInfoComsumer.SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition);
                    }

                    viewStateNodes.Writer.WriteNode(xamlReader);
                }

                if (skippingUnexpectedAttachedPropertyLevel == 0)
                {
                    skippingUnexpectedAttachedProperty = false;
                }
            }
            viewStateNodes.Writer.Close();
        }
        // This method reads ViewStateManager nodes from the xaml nodestream and outputs that in the 
        // viewStateInfo dictionary. The input reader is positioned on the ViewStateManagerNode in the nodestream.
        static void ReadViewStateInfo(XamlReader inputReader, out Dictionary<string, XamlNodeList> viewStateInfo, out Dictionary<string, SourceLocation> viewStateSourceLocationMap)
        {
            XamlType viewStateType = new XamlType(typeof(ViewStateData), inputReader.SchemaContext);

            viewStateInfo = new Dictionary<string, XamlNodeList>();
            viewStateSourceLocationMap = new Dictionary<string, SourceLocation>();
            bool skipReading = false;
            while (skipReading || inputReader.Read())
            {
                skipReading = false;
                if (inputReader.NodeType == XamlNodeType.StartObject && inputReader.Type.Equals(viewStateType))
                {
                    string id;
                    XamlNodeList viewStateNodeList;
                    SourceLocation viewStateSourceLocation = null;
                    ReadViewState(viewStateType, inputReader.ReadSubtree(), out id, out viewStateNodeList, out viewStateSourceLocation);
                    if (id != null)
                    {
                        viewStateInfo[id] = viewStateNodeList;
                        viewStateSourceLocationMap[id] = viewStateSourceLocation;
                    }

                    //inputReader will be positioned on the next node so no need to advance it.
                    skipReading = true;
                }
            }
        }
        // This method reads ViewStateManager nodes from the xaml nodestream and outputs that in the
        // viewStateInfo dictionary. The input reader is positioned at the begining of the workflow definition.
        // The method returns a reader positioned at the begining of the workflow definition with the ViewStateManager 
        // nodes removed.
        static XamlReader StripViewStateElement(XamlReader inputReader, out Dictionary<string, XamlNodeList> viewStateInfo, out Dictionary<string, SourceLocation> viewStateSourceLocationMap)
        {
            viewStateSourceLocationMap = null;
            XamlNodeList strippedNodeList = new XamlNodeList(inputReader.SchemaContext);
            XamlMember viewStateManager = new XamlMember(ViewStateManager, GetViewStateManager, SetViewStateManager, inputReader.SchemaContext);
            using (XamlWriter strippedWriter = strippedNodeList.Writer)
            {
                IXamlLineInfo lineInfo = inputReader as IXamlLineInfo;
                IXamlLineInfoConsumer lineInfoComsumer = strippedWriter as IXamlLineInfoConsumer;
                bool shouldPassLineInfo = lineInfo != null && lineInfo.HasLineInfo && lineInfoComsumer != null && lineInfoComsumer.ShouldProvideLineInfo;

                viewStateInfo = null;
                while (inputReader.Read())
                {
                    if (inputReader.NodeType == XamlNodeType.StartMember && inputReader.Member.Equals(viewStateManager))
                    {
                        ReadViewStateInfo(inputReader.ReadSubtree(), out viewStateInfo, out viewStateSourceLocationMap);
                        
                    }

                    if (shouldPassLineInfo)
                    {
                        lineInfoComsumer.SetLineInfo(lineInfo.LineNumber, lineInfo.LinePosition);
                    }

                    strippedWriter.WriteNode(inputReader);
                }
            }

            return strippedNodeList.GetReader();
        }
 // Read the parameters on the Attribute. We expect the parameters to be in the order in which they are supposed to appear in the output code.
 // Here we are inside x:Arguments and we expect a list of parameters.
 private static IList<AttributeParameterData> ReadParameters(XamlReader reader, NamespaceTable namespaceTable, string rootNamespace)
 {
     IList<AttributeParameterData> parameters = new List<AttributeParameterData>();
     bool readNext = false;
     while (readNext || reader.Read())
     {
         readNext = false;
         if (reader.NodeType == XamlNodeType.StartObject)
         {
             AttributeParameterData paramInfo = new AttributeParameterData();
             ReadParamInfo(reader.ReadSubtree(), null, namespaceTable, rootNamespace, paramInfo);
             parameters.Add(paramInfo);
             readNext = true;
         }
     }
     return parameters;
 }
 // Read the actual parameter info, i.e. the type of the paramter and its value.
 // The first element could be a V or an SO.
 private static void ReadParamInfo(XamlReader reader, XamlType type, NamespaceTable namespaceTable, string rootNamespace, AttributeParameterData paramInfo)
 {
     reader.Read();
     
     bool readNext = false;
     do
     {
         readNext = false;
         if (reader.NodeType == XamlNodeType.StartObject && reader.Type == XamlLanguage.Array)
         {
             paramInfo.IsArray = true;
             XamlReader xamlArrayReader = reader.ReadSubtree();
             xamlArrayReader.Read();
             while (readNext || xamlArrayReader.Read())
             {
                 readNext = false;
                 if (xamlArrayReader.NodeType == XamlNodeType.StartMember && xamlArrayReader.Member.Name == "Type")
                 {
                     xamlArrayReader.Read();
                     if (xamlArrayReader.NodeType == XamlNodeType.Value)
                     {
                         XamlType arrayType = XamlBuildTaskServices.GetXamlTypeFromString(xamlArrayReader.Value as string, namespaceTable, xamlArrayReader.SchemaContext);
                         if (arrayType.UnderlyingType != null)
                         {
                             paramInfo.Type = xamlArrayReader.SchemaContext.GetXamlType(arrayType.UnderlyingType.MakeArrayType());
                         }
                         else
                         {
                             throw FxTrace.Exception.AsError(new InvalidOperationException(SR.AttributeParameterTypeUnknown(arrayType)));
                         }
                     }
                 }
                 else if (xamlArrayReader.NodeType == XamlNodeType.StartObject)
                 {
                     AttributeParameterData arrayEntry = new AttributeParameterData();
                     ReadParamInfo(xamlArrayReader.ReadSubtree(), null, namespaceTable, rootNamespace, arrayEntry);
                     paramInfo.AddArrayContentsEntry(arrayEntry);
                     readNext = true;
                 }
             }
         }                    
         else if (reader.NodeType == XamlNodeType.StartObject || reader.NodeType == XamlNodeType.Value)
         {
             paramInfo.IsArray = false;
             string paramVal;
             object paramObj = null;
             XamlType paramType;
             GetParamValueType(reader.ReadSubtree(), type, namespaceTable, rootNamespace, out paramVal, out paramType, out paramObj);
             paramInfo.TextValue = paramVal;
             paramInfo.Type = paramType;
             paramInfo.Value = paramObj;
         }
     } while (readNext || reader.Read());
 }
        IEnumerable<PropertyData> ReadProperties(XamlReader reader)
        {
            IDictionary<string, PropertyData> members = new Dictionary<string, PropertyData>();

            bool nextNodeRead = false;
            while (nextNodeRead || reader.Read())
            {
                namespaceTable.ManageNamespace(reader);
                nextNodeRead = false;
                if (reader.NodeType == XamlNodeType.StartObject)
                {
                    if (reader.Type == XamlLanguage.Property)
                    {
                        PropertyData xProperty = LoadProperty(reader.ReadSubtree());
                        nextNodeRead = true;
                        if (members.ContainsKey(xProperty.Name))
                        {
                            throw FxTrace.Exception.AsError(LogInvalidOperationException(reader, SR.DuplicatePropertyDefinition(xProperty.Name)));
                        }
                        members.Add(xProperty.Name, xProperty);
                    }
                }
            }

            return members.Values;
        }
        PropertyData LoadProperty(XamlReader xamlReader)
        {
            if (xamlReader == null)
            {
                throw FxTrace.Exception.ArgumentNull("xamlReader");
            }

            PropertyData property = new PropertyData();
            while (xamlReader.Read())
            {
                if (xamlReader.NodeType == XamlNodeType.StartMember)
                {
                    XamlMember member = xamlReader.Member;
                    switch (member.Name)
                    {
                        case "Name":
                            property.Name = ReadValueAsString(xamlReader.ReadSubtree());
                            break;
                        case "Type":
                            property.Type = ReadPropertyType(xamlReader.ReadSubtree());
                            break;
                        case "Attributes":
                            foreach (AttributeData attribute in ReadAttributesCollection(xamlReader.ReadSubtree()))
                            {
                                property.Attributes.Add(attribute);
                            }
                            break;
                        case "Modifier":
                            string propertyModifier = ReadValueAsString(xamlReader.ReadSubtree());
                            property.Visibility = XamlBuildTaskServices.GetMemberVisibility(propertyModifier);
                            break;
                        default:
                            // Ignore AttachedProperties on property
                            if (!member.IsAttachable)
                            {
                                throw FxTrace.Exception.AsError(LogInvalidOperationException(xamlReader, SR.UnknownPropertyMember(member.Name)));
                            }                            
                            break;
                    }
                }
            }
            if (string.IsNullOrEmpty(property.Name))
            {
                throw FxTrace.Exception.AsError(LogInvalidOperationException(xamlReader, SR.PropertyNameRequired));
            }
            if (property.Type == null)
            {
                throw FxTrace.Exception.AsError(LogInvalidOperationException(xamlReader, SR.PropertyTypeRequired(property.Name)));
            }
            return property;
        }
        bool ProcessDirective(XamlReader reader, ClassData classData,
            NamedObject currentObject, bool isRootElement, XamlNodeList strippedXamlNodes, out bool readNextNode)
        {
            Fx.Assert(reader.NodeType == XamlNodeType.StartMember, "Current node should be a Start Member Node");

            XamlMember member = reader.Member;
            bool directiveRecognized = false;
            readNextNode = false;

            switch (member.Name)
            {
                case "Name":
                    // Unlike all the other directives that we process, x:Name should be written
                    // to the stripped output.
                    strippedXamlNodes.Writer.WriteStartMember(member);

                    string objectName = ReadAtom(reader, XamlLanguage.Name.Name);
                    if (!objectName.StartsWith(XamlBuildTaskServices.SerializerReferenceNamePrefix,
                        StringComparison.Ordinal))
                    {
                        currentObject.Name = objectName;
                        classData.NamedObjects.Add(currentObject);
                    }

                    strippedXamlNodes.Writer.WriteValue(objectName);
                    strippedXamlNodes.Writer.WriteEndMember();
                    directiveRecognized = true;
                    break;

                case "Class":
                    if (isRootElement)
                    {
                        string fullClassName = ReadAtom(reader, XamlLanguage.Class.Name);
                        SetClassName(fullClassName, classData);
                        directiveRecognized = true;
                    }
                    break;

                case "ClassModifier":
                    if (isRootElement)
                    {
                        string classModifier = ReadAtom(reader, XamlLanguage.ClassModifier.Name);
                        classData.IsPublic = XamlBuildTaskServices.IsPublic(classModifier);
                        directiveRecognized = true;
                    }
                    break;

                case "FieldModifier":
                    string fieldModifier = ReadAtom(reader, XamlLanguage.FieldModifier.Name);
                    currentObject.Visibility = XamlBuildTaskServices.GetMemberVisibility(fieldModifier);
                    directiveRecognized = true;
                    break;

                case "Code":
                    string codeSnippet = ReadAtom(reader, XamlLanguage.Code.Name);
                    classData.CodeSnippets.Add(codeSnippet);
                    directiveRecognized = true;
                    break;

                case "Members":
                    foreach (PropertyData property in ReadProperties(reader.ReadSubtree()))
                    {
                        classData.Properties.Add(property);
                    }
                    if (!classData.RequiresCompilationPass2)
                    {
                        foreach (PropertyData property in classData.Properties)
                        {
                            if (property.Type.IsUnknown)
                            {
                                classData.RequiresCompilationPass2 = true;
                                break;
                            }
                        }
                    }
                    directiveRecognized = true;
                    readNextNode = true;
                    break;

                case "ClassAttributes":
                    foreach (AttributeData attribute in ReadAttributesCollection(reader.ReadSubtree()))
                    {
                        classData.Attributes.Add(attribute);
                    }
                    directiveRecognized = true;
                    readNextNode = true;
                    break;

            }

            if (directiveRecognized == true && readNextNode == false)
            {
                reader.Read();
                Fx.Assert(reader.NodeType == XamlNodeType.EndMember, "Current node should be a XamlEndmember");
            }

            return directiveRecognized;
        }
        private IList<AttributeData> ReadAttributesCollection(XamlReader reader)
        {
            IList<AttributeData> attributes = new List<AttributeData>();
            bool nextNodeRead = false;
            while (nextNodeRead || reader.Read())
            {
                this.namespaceTable.ManageNamespace(reader);
                nextNodeRead = false;
                if (reader.NodeType == XamlNodeType.StartObject && reader.Type != null)
                {
                    AttributeData attribute = null;
                    try
                    {
                        attribute = AttributeData.LoadAttributeData(reader.ReadSubtree(), this.namespaceTable, this.rootNamespace);
                    }
                    catch (InvalidOperationException e)
                    {
                        throw FxTrace.Exception.AsError(LogInvalidOperationException(reader, e.Message));
                    }
                    nextNodeRead = true;
                    attributes.Add(attribute);
                }
            }

            return attributes;
        }
 public bool ProcessNode(XamlReader reader, XamlWriter targetWriter, int currentDepth, IXamlLineInfo readerLineInfo)
 {
     if ((currentDepth == this.Depth) && ((reader.NodeType == XamlNodeType.NamespaceDeclaration) || (reader.NodeType == XamlNodeType.None)))
     {
         this.bufferedNodes.Writer.WriteNode(reader, readerLineInfo);
         reader.Read();
         return true;
     }
     if ((((reader.NodeType == XamlNodeType.StartObject) && reader.Type.IsGeneric) && ((reader.Type.UnderlyingType != null) && (reader.Type.Name == "PropertyReferenceExtension"))) && (reader.Type.UnderlyingType.GetGenericTypeDefinition() == typeof(PropertyReferenceExtension<>)))
     {
         if (this.bufferedNodes.Count > 0)
         {
             XamlServices.Transform(this.bufferedNodes.Reader, targetWriter, false);
             this.bufferedNodes = null;
         }
         XamlType type = reader.Type;
         XamlReader reader2 = reader.ReadSubtree();
         XamlType xamlType = reader.SchemaContext.GetXamlType(typeof(ActivityBuilder));
         XamlType type3 = reader.SchemaContext.GetXamlType(typeof(ActivityPropertyReference));
         targetWriter.WriteStartMember(xamlType.GetAttachableMember("PropertyReference"), readerLineInfo);
         reader2.Read();
         targetWriter.WriteStartObject(type3, readerLineInfo);
         targetWriter.WriteStartMember(type3.GetMember("TargetProperty"), readerLineInfo);
         targetWriter.WriteValue(this.currentMember.Name, readerLineInfo);
         targetWriter.WriteEndMember(readerLineInfo);
         bool flag = reader2.Read();
         bool flag2 = false;
         while (flag)
         {
             if (((reader2.NodeType == XamlNodeType.StartMember) && (reader2.Member.DeclaringType == type)) && (reader2.Member.Name == "PropertyName"))
             {
                 flag2 = true;
             }
             else if (flag2)
             {
                 if (reader2.NodeType == XamlNodeType.EndMember)
                 {
                     flag2 = false;
                 }
                 else if (reader2.NodeType == XamlNodeType.Value)
                 {
                     targetWriter.WriteStartMember(type3.GetMember("SourceProperty"), readerLineInfo);
                     targetWriter.WriteValue((string) reader2.Value, readerLineInfo);
                     targetWriter.WriteEndMember(readerLineInfo);
                 }
             }
             flag = reader2.Read();
         }
         targetWriter.WriteEndObject(readerLineInfo);
         targetWriter.WriteEndMember(readerLineInfo);
         this.ExitObject = true;
         reader2.Close();
     }
     else
     {
         this.FlushBuffer(targetWriter);
         targetWriter.WriteNode(reader, readerLineInfo);
     }
     return false;
 }
 public ValueHolder(XamlSchemaContext schemaContext, XamlMember propertyValue, XamlReader reader, IXamlLineInfo lineInfo)
 {
     this.nodes = new XamlNodeQueue(schemaContext);
     this.PropertyValue = propertyValue;
     XamlWriterExtensions.Transform(reader.ReadSubtree(), this.nodes.Writer, lineInfo, true);
 }
 public void ProcessDefaultValue(XamlMember propertyValue, XamlReader subReader, IXamlLineInfo lineInfo)
 {
     XamlReader reader;
     bool flag = false;
     subReader.Read();
     if (!subReader.Member.IsNameValid)
     {
         throw FxTrace.Exception.AsError(DynamicActivityXamlReader.CreateXamlException(System.Activities.SR.InvalidXamlMember(subReader.Member.Name), lineInfo));
     }
     this.nodes.Writer.WriteStartMember(propertyValue, lineInfo);
     subReader.Read();
     if (subReader.NodeType == XamlNodeType.GetObject)
     {
         subReader.Read();
         subReader.Read();
         reader = subReader.ReadSubtree();
         reader.Read();
     }
     else
     {
         reader = subReader;
     }
     if ((reader.NodeType != XamlNodeType.EndMember) && (reader.NodeType != XamlNodeType.StartObject))
     {
         flag = true;
         this.nodes.Writer.WriteStartObject(this.Type, lineInfo);
         this.nodes.Writer.WriteStartMember(XamlLanguage.Initialization, lineInfo);
     }
     while (!reader.IsEof)
     {
         this.nodes.Writer.WriteNode(reader, lineInfo);
         reader.Read();
     }
     reader.Close();
     if (!object.ReferenceEquals(reader, subReader))
     {
         subReader.Read();
         while (subReader.Read())
         {
             this.nodes.Writer.WriteNode(subReader, lineInfo);
         }
     }
     if (flag)
     {
         this.nodes.Writer.WriteEndObject(lineInfo);
         this.nodes.Writer.WriteEndMember(lineInfo);
     }
     subReader.Close();
 }
 public void BufferDefaultValue(string propertyName, XamlMember propertyValue, XamlReader reader, IXamlLineInfo lineInfo)
 {
     if (this.alreadyBufferedDefinitions)
     {
         this.ProcessDefaultValue(propertyName, propertyValue, reader.ReadSubtree(), lineInfo);
     }
     else
     {
         if (this.valueHolders == null)
         {
             this.valueHolders = new Dictionary<string, ValueHolder>();
         }
         ValueHolder holder = new ValueHolder(this.parent.SchemaContext, propertyValue, reader, lineInfo);
         this.valueHolders[propertyName] = holder;
     }
 }
                public void ProcessDefaultValue(XamlMember propertyValue, XamlReader subReader, IXamlLineInfo lineInfo)
                {
                    bool addedStartObject = false;

                    // 1) swap out the start member with <ActivityProperty.Value>
                    subReader.Read();
                    if (!subReader.Member.IsNameValid)
                    {
                        throw FxTrace.Exception.AsError(CreateXamlException(SR.InvalidXamlMember(subReader.Member.Name), lineInfo));
                    }

                    this.nodes.Writer.WriteStartMember(propertyValue, lineInfo);

                    // temporary hack: read past GetObject/StartMember nodes that are added by 
                    // the XAML stack. This has been fixed in the WPF branch, but we haven't FI'ed that yet
                    XamlReader valueReader;
                    subReader.Read();
                    if (subReader.NodeType == XamlNodeType.GetObject)
                    {
                        subReader.Read();
                        subReader.Read();
                        valueReader = subReader.ReadSubtree();
                        valueReader.Read();
                    }
                    else
                    {
                        valueReader = subReader;
                    }

                    // Add SO tag if necessary UNLESS there's no value to wrap (which means we're already at EO)
                    if (valueReader.NodeType != XamlNodeType.EndMember && valueReader.NodeType != XamlNodeType.StartObject)
                    {
                        addedStartObject = true;
                        // Add <TypeOfProperty> nodes so that type converters work correctly
                        this.nodes.Writer.WriteStartObject(this.Type, lineInfo);
                        this.nodes.Writer.WriteStartMember(XamlLanguage.Initialization, lineInfo);
                    }

                    // 3) copy over the value 
                    while (!valueReader.IsEof)
                    {
                        this.nodes.Writer.WriteNode(valueReader, lineInfo);
                        valueReader.Read();
                    }

                    valueReader.Close();

                    // 4) close up the extra nodes 
                    if (!object.ReferenceEquals(valueReader, subReader))
                    {
                        subReader.Read();
                        while (subReader.Read())
                        {
                            this.nodes.Writer.WriteNode(subReader, lineInfo);
                        }

                    }

                    if (addedStartObject)
                    {
                        this.nodes.Writer.WriteEndObject(lineInfo);
                        this.nodes.Writer.WriteEndMember(lineInfo);
                    }
                    subReader.Close();
                }