private void WalkTreeOnChangeNode( DiffgramParentOperation diffParent, XmlDiffNode sourceNode, XmlDiffNode targetNode, XmlDiffOperation op )
        {
            Debug.Assert( sourceNode.NodeType != XmlDiffNodeType.Element && targetNode.NodeType != XmlDiffNodeType.Element );

            DiffgramChangeNode changeOp = new DiffgramChangeNode( sourceNode, targetNode, op, 0 );
            if ( sourceNode.HasChildNodes || targetNode.HasChildNodes ) {
            WalkTreeGenerateDiffgramMatch( changeOp, (XmlDiffParentNode) sourceNode, (XmlDiffParentNode) targetNode );
            }
            diffParent.InsertAtEnd( changeOp );
        }
        // produces <change> element in diffgram
        private void OnChange( DiffgramParentOperation parent )
        {
            EditScriptChange chOp = _editScript as EditScriptChange;

            Debug.Assert( chOp._targetIndex == _curTargetIndex );
            Debug.Assert( chOp._sourceIndex == _curSourceIndex );

            XmlDiffNode sourceRoot = _sourceNodes[ chOp._sourceIndex ];
            XmlDiffNode targetRoot = _targetNodes[ chOp._targetIndex ];

            Debug.Assert( !( sourceRoot is XmlDiffShrankNode) );
            Debug.Assert( !( targetRoot is XmlDiffShrankNode) );

            // adjust current position
            _curSourceIndex--;
            _curTargetIndex--;

            // move to next edit script operation
            _editScript = _editScript._nextEditScript;

            DiffgramOperation diffgramNode = null;

            if ( _bBuildingAddTree )
            {
            // <add> changed node to the new location
            if ( targetRoot.NodeType == XmlDiffNodeType.Element )
                diffgramNode = new DiffgramAddNode( targetRoot, 0 );
            else
                diffgramNode = new DiffgramAddSubtrees( targetRoot, 0, !_xmlDiff.IgnoreChildOrder );

            // <remove> old node from old location -> add to postponed operations
            bool bSubtree = sourceRoot.NodeType != XmlDiffNodeType.Element;
            PostponedRemoveNode( sourceRoot, bSubtree, 0,
            //AddToPosponedOperations( new DiffgramRemoveNode( sourceRoot, bSubtree, 0 ),
                chOp._sourceIndex, chOp._sourceIndex );

            // recursively process children
            if ( sourceRoot.Left < chOp._sourceIndex ||
                targetRoot.Left < chOp._targetIndex )
            {
                Debug.Assert( targetRoot.NodeType == XmlDiffNodeType.Element );
                GenerateDiffgramAdd( (DiffgramParentOperation)diffgramNode, sourceRoot.Left, targetRoot.Left );
            }

            // add attributes, if element
            if ( targetRoot.NodeType == XmlDiffNodeType.Element )
                GenerateAddDiffgramForAttributes( (DiffgramParentOperation)diffgramNode, (XmlDiffElement)targetRoot );
            }
            else
            {
            ulong opid = 0;

            // change of namespace or prefix -> get the appropriate operation id
            if ( !_xmlDiff.IgnoreNamespaces &&
                 sourceRoot.NodeType == XmlDiffNodeType.Element )
            {
                XmlDiffElement sourceEl = (XmlDiffElement)sourceRoot;
                XmlDiffElement targetEl = (XmlDiffElement)targetRoot;

                if ( sourceEl.LocalName == targetEl.LocalName )
                {
                    opid = GetNamespaceChangeOpid( sourceEl.NamespaceURI, sourceEl.Prefix,
                                                   targetEl.NamespaceURI, targetEl.Prefix );
                }
            }

            if ( sourceRoot.NodeType == XmlDiffNodeType.Element )
            {
                if ( XmlDiff.IsChangeOperationOnAttributesOnly( chOp._changeOp ) )
                    diffgramNode = new DiffgramPosition( sourceRoot );
                else
                {
                    Debug.Assert( (int)chOp._changeOp == (int)XmlDiffOperation.ChangeElementName ||
                                  ( (int)chOp._changeOp >= (int)XmlDiffOperation.ChangeElementNameAndAttr1 &&
                                    (int)chOp._changeOp <= (int)XmlDiffOperation.ChangeElementNameAndAttr2 ) );

                    diffgramNode = new DiffgramChangeNode( sourceRoot, targetRoot, XmlDiffOperation.ChangeElementName, opid );
                }

                // recursively process children
                if ( sourceRoot.Left < chOp._sourceIndex ||
                    targetRoot.Left < chOp._targetIndex )
                {
                    GenerateDiffgramMatch( (DiffgramParentOperation) diffgramNode, sourceRoot.Left, targetRoot.Left );
                }

                GenerateChangeDiffgramForAttributes( (DiffgramParentOperation)diffgramNode, (XmlDiffElement)sourceRoot, (XmlDiffElement)targetRoot );
            }
            else
            {
                // '<change>'
                diffgramNode = new DiffgramChangeNode( sourceRoot, targetRoot, chOp._changeOp, opid );
                Debug.Assert( !sourceRoot.HasChildNodes );
            }
            }

            parent.InsertAtBeginning( diffgramNode );
        }
        private void WalkTreeOnChangeElement( DiffgramParentOperation diffParent, XmlDiffElement sourceElement, XmlDiffElement targetElement, XmlDiffOperation op )
        {
            DiffgramParentOperation diffOp;

            if ( XmlDiff.IsChangeOperationOnAttributesOnly( op ) ) {
            diffOp = new DiffgramPosition( sourceElement );
            }
            else
            {
            ulong opid = 0;
            if ( !_xmlDiff.IgnoreNamespaces && sourceElement.LocalName == targetElement.LocalName)
            {
                opid = GetNamespaceChangeOpid( sourceElement.NamespaceURI, sourceElement.Prefix,
                                               targetElement.NamespaceURI, targetElement.Prefix );
            }

            Debug.Assert( (int)op >= (int)XmlDiffOperation.ChangeElementName &&
                          (int)op <= (int)XmlDiffOperation.ChangeElementNameAndAttr3 );

            diffOp = new DiffgramChangeNode( sourceElement, targetElement, XmlDiffOperation.ChangeElementName, opid );
            }

            GenerateChangeDiffgramForAttributes( diffOp, sourceElement, targetElement );

            if ( sourceElement.HasChildNodes || targetElement.HasChildNodes ) {
            WalkTreeGenerateDiffgramMatch( diffOp, sourceElement, targetElement );
            }

            diffParent.InsertAtEnd( diffOp );
        }