// when Read hits EndObject or EndMember
        void ExitObject()
        {
            if (this.depth <= this.inXClassDepth)
            {
                this.inXClassDepth = 0;
            }

            this.depth--;
            this.frontLoadedDirectives = false;

            if (this.depth == 1)
            {
                this.builderStack = null;
            }
            else if (this.depth == 0)
            {
                // we're about to write out the last tag. Dump our accrued properties 
                // as no more property values are forthcoming. 
                if (this.bufferedProperties != null)
                {
                    this.bufferedProperties.FlushTo(this.nodeQueue, this);
                }
            }
        }
        // pull on our inner reader, map the results as necessary, and pump
        // mapped results into the streaming node reader that we're offering up.
        // return true if we need to keep pumping (because we've buffered some nodes on the side)
        bool ProcessCurrentNode()
        {
            bool processedNode = false;
            this.namespaceTable.ManageNamespace(this.innerReader);

            switch (this.innerReader.NodeType)
            {
                case XamlNodeType.StartMember:
                    XamlMember currentMember = this.innerReader.Member;
                    // find out if the member is a default value for one of
                    // our declared properties. If it is, then we have a complex case
                    // where we need to:
                    // 1) read the nodes into a side list 
                    // 2) interleave these nodes with the DynamicActivityProperty nodes
                    //    since they need to appear as DynamicActivityProperty.Value
                    // 3) right before we hit the last node, we'll dump the side node-lists
                    //    reflecting a zipped up representation of the Properties
                    if (IsXClassName(currentMember.DeclaringType))
                    {
                        if (this.bufferedProperties == null)
                        {
                            this.bufferedProperties = new BufferedPropertyList(this);
                        }
                        this.bufferedProperties.BufferDefaultValue(currentMember.Name, this.activityPropertyValue, this.innerReader, this.innerReaderLineInfo);
                        return true; // output cursor didn't move forward
                    }
                    else if (this.frontLoadedDirectives && currentMember == XamlLanguage.FactoryMethod)
                    {
                        DisableRewrite();
                        return false;
                    }
                    else
                    {
                        this.depth++;
                        if (this.depth == 2)
                        {
                            if (currentMember.DeclaringType == this.activityXamlType || currentMember.DeclaringType == this.baseActivityXamlType)
                            {
                                // Rewrite "<Activity.XXX>" to "<DynamicActivity.XXX>"
                                XamlMember member = this.activityReplacementXamlType.GetMember(currentMember.Name);
                                if (member == null)
                                {
                                    throw FxTrace.Exception.AsError(CreateXamlException(SR.MemberNotSupportedByActivityXamlServices(currentMember.Name), this.innerReaderLineInfo));
                                }

                                this.nodeQueue.Writer.WriteStartMember(member, this.innerReaderLineInfo);

                                if (member.Name == "Constraints")
                                {
                                    WriteWrappedMember(true);
                                    processedNode = true;
                                    return true;
                                }

                                processedNode = true;

                                // if we're in ActivityBuilder.Implementation, start buffering nodes
                                if (this.isBuilder && member.Name == "Implementation")
                                {
                                    this.builderStack = new BuilderStack(this);
                                }
                            }
                            else if (currentMember == XamlLanguage.Class)
                            {
                                this.inXClassDepth = this.depth;

                                // Rewrite x:Class to DynamicActivity.Name
                                this.nodeQueue.Writer.WriteStartMember(this.activityReplacementXamlType.GetMember("Name"), this.innerReaderLineInfo);
                                processedNode = true;
                            }
                            else if (currentMember == XamlLanguage.Members)
                            {
                                // Rewrite "<x:Members>" to "<DynamicActivity.Properties>"
                                if (this.bufferedProperties == null)
                                {
                                    this.bufferedProperties = new BufferedPropertyList(this);
                                }
                                this.bufferedProperties.BufferDefinitions(this);
                                this.depth--;
                                return true; // output cursor didn't move forward
                            }
                            else if (currentMember == XamlLanguage.ClassAttributes)
                            {
                                // Rewrite x:ClassAttributes to DynamicActivity.Attributes
                                this.nodeQueue.Writer.WriteStartMember(this.activityReplacementXamlType.GetMember("Attributes"), this.innerReaderLineInfo);
                                // x:ClassAttributes directive has no following GetObject, but Attributes does since it's not a directive
                                WriteWrappedMember(false);
                                processedNode = true;
                                return true;
                            }
                        }
                    }
                    break;

                case XamlNodeType.StartObject:
                    {
                        EnterObject();
                        if (this.depth == 1)
                        {
                            // see if we're deserializing an Activity
                            if (this.innerReader.Type.UnderlyingType == typeof(Activity))
                            {
                                // Rewrite "<Activity>" to "<DynamicActivity>"
                                this.activityXamlType = this.innerReader.Type;
                                if (this.isBuilder)
                                {
                                    this.activityReplacementXamlType = SchemaContext.GetXamlType(typeof(ActivityBuilder));
                                }
                                else
                                {
                                    this.activityReplacementXamlType = SchemaContext.GetXamlType(typeof(DynamicActivity));
                                }
                            }
                            // or an Activity<TResult>
                            else if (this.innerReader.Type.IsGeneric && this.innerReader.Type.UnderlyingType != null
                                && this.innerReader.Type.UnderlyingType.GetGenericTypeDefinition() == typeof(Activity<>))
                            {
                                // Rewrite "<Activity typeArgument=T>" to "<DynamicActivity typeArgument=T>" 
                                this.activityXamlType = this.innerReader.Type;

                                Type activityType = this.innerReader.Type.TypeArguments[0].UnderlyingType;
                                Type activityReplacementGenericType;
                                if (this.isBuilder)
                                {
                                    activityReplacementGenericType = typeof(ActivityBuilder<>).MakeGenericType(activityType);
                                }
                                else
                                {
                                    activityReplacementGenericType = typeof(DynamicActivity<>).MakeGenericType(activityType);
                                }

                                this.activityReplacementXamlType = SchemaContext.GetXamlType(activityReplacementGenericType);
                            }
                            // otherwise disable rewriting so that we're a pass through
                            else
                            {
                                DisableRewrite();
                                return false;
                            }

                            this.nodeQueue.Writer.WriteStartObject(this.activityReplacementXamlType, this.innerReaderLineInfo);
                            processedNode = true;
                        }

                    }
                    break;

                case XamlNodeType.GetObject:
                    EnterObject();
                    break;

                case XamlNodeType.EndObject:
                case XamlNodeType.EndMember:
                    ExitObject();
                    break;

                case XamlNodeType.Value:
                    if (this.inXClassDepth >= this.depth && this.xClassName == null)
                    {
                        string fullName = (string)this.innerReader.Value;
                        string xClassNamespace = "";
                        string xClassName = fullName;

                        int nameStartIndex = fullName.LastIndexOf('.');
                        if (nameStartIndex > 0)
                        {
                            xClassNamespace = fullName.Substring(0, nameStartIndex);
                            xClassName = fullName.Substring(nameStartIndex + 1);
                        }

                        this.xClassName = new XamlTypeName(xClassNamespace, xClassName);
                    }
                    break;
            }

            if (!processedNode)
            {
                if (this.builderStack != null)
                {
                    bool writeNode = true;
                    this.builderStack.ProcessNode(this.innerReader, this.innerReaderLineInfo, this.nodeQueue.Writer, out writeNode);
                    if (!writeNode)
                    {
                        this.innerReader.Read();
                        return true;
                    }
                }
                this.nodeQueue.Writer.WriteNode(this.innerReader, this.innerReaderLineInfo);
            }
            return false;
        }