<s> package org . eclipse . jdt . internal . core . dom . rewrite ; import java . util . * ; import org . eclipse . jdt . core . Signature ; import org . eclipse . jdt . core . dom . ASTNode ; import org . eclipse . jdt . core . dom . Block ; import org . eclipse . jdt . core . dom . StructuralPropertyDescriptor ; import org . eclipse . jdt . core . dom . rewrite . TargetSourceRangeComputer ; import org . eclipse . text . edits . TextEditGroup ; public final class RewriteEventStore { public static final class PropertyLocation { private final ASTNode parent ; private final StructuralPropertyDescriptor property ; public PropertyLocation ( ASTNode parent , StructuralPropertyDescriptor property ) { this . parent = parent ; this . property = property ; } public ASTNode getParent ( ) { return this . parent ; } public StructuralPropertyDescriptor getProperty ( ) { return this . property ; } public boolean equals ( Object obj ) { if ( obj != null && obj . getClass ( ) . equals ( getClass ( ) ) ) { PropertyLocation other = ( PropertyLocation ) obj ; return other . getParent ( ) . equals ( getParent ( ) ) && other . getProperty ( ) . equals ( getProperty ( ) ) ; } return false ; } public int hashCode ( ) { return getParent ( ) . hashCode ( ) + getProperty ( ) . hashCode ( ) ; } } public static interface INodePropertyMapper { Object getOriginalValue ( ASTNode parent , StructuralPropertyDescriptor childProperty ) ; } private static class EventHolder { public final ASTNode parent ; public final StructuralPropertyDescriptor childProperty ; public final RewriteEvent event ; public EventHolder ( ASTNode parent , StructuralPropertyDescriptor childProperty , RewriteEvent change ) { this . parent = parent ; this . childProperty = childProperty ; this . event = change ; } public String toString ( ) { StringBuffer buf = new StringBuffer ( ) ; buf . append ( this . parent ) . append ( " - " ) ; buf . append ( this . childProperty . getId ( ) ) . append ( ": " ) ; buf . append ( this . event ) . append ( '\n' ) ; return buf . toString ( ) ; } } public static class CopySourceInfo implements Comparable { public final PropertyLocation location ; private final ASTNode node ; public final boolean isMove ; public CopySourceInfo ( PropertyLocation location , ASTNode node , boolean isMove ) { this . location = location ; this . node = node ; this . isMove = isMove ; } public ASTNode getNode ( ) { return this . node ; } public int compareTo ( Object o2 ) { CopySourceInfo r2 = ( CopySourceInfo ) o2 ; int startDiff = getNode ( ) . getStartPosition ( ) - r2 . getNode ( ) . getStartPosition ( ) ; if ( startDiff != 0 ) { return startDiff ; } if ( r2 . isMove != this . isMove ) { return this . isMove ? - 1 : 1 ; } return 0 ; } public String toString ( ) { StringBuffer buf = new StringBuffer ( ) ; if ( this . isMove ) { buf . append ( "" ) ; } else { buf . append ( "" ) ; } buf . append ( this . node ) ; return buf . toString ( ) ; } } private static class NodeRangeInfo implements Comparable { private final ASTNode first ; private final ASTNode last ; public final CopySourceInfo copyInfo ; public final ASTNode replacingNode ; public final TextEditGroup editGroup ; public NodeRangeInfo ( ASTNode parent , StructuralPropertyDescriptor childProperty , ASTNode first , ASTNode last , CopySourceInfo copyInfo , ASTNode replacingNode , TextEditGroup editGroup ) { this . first = first ; this . last = last ; this . copyInfo = copyInfo ; this . replacingNode = replacingNode ; this . editGroup = editGroup ; } public ASTNode getStartNode ( ) { return this . first ; } public ASTNode getEndNode ( ) { return this . last ; } public boolean isMove ( ) { return this . copyInfo . isMove ; } public Block getInternalPlaceholder ( ) { return ( Block ) this . copyInfo . getNode ( ) ; } public int compareTo ( Object o2 ) { NodeRangeInfo r2 = ( NodeRangeInfo ) o2 ; int startDiff = getStartNode ( ) . getStartPosition ( ) - r2 . getStartNode ( ) . getStartPosition ( ) ; if ( startDiff != 0 ) { return startDiff ; } int endDiff = getEndNode ( ) . getStartPosition ( ) - r2 . getEndNode ( ) . getStartPosition ( ) ; if ( endDiff != 0 ) { return - endDiff ; } if ( r2 . isMove ( ) != isMove ( ) ) { return isMove ( ) ? - 1 : 1 ; } return 0 ; } public void updatePlaceholderSourceRanges ( TargetSourceRangeComputer sourceRangeComputer ) { TargetSourceRangeComputer . SourceRange startRange = sourceRangeComputer . computeSourceRange ( getStartNode ( ) ) ; TargetSourceRangeComputer . SourceRange endRange = sourceRangeComputer . computeSourceRange ( getEndNode ( ) ) ; int startPos = startRange . getStartPosition ( ) ; int endPos = endRange . getStartPosition ( ) + endRange . getLength ( ) ; Block internalPlaceholder = getInternalPlaceholder ( ) ; internalPlaceholder . setSourceRange ( startPos , endPos - startPos ) ; } public String toString ( ) { StringBuffer buf = new StringBuffer ( ) ; if ( this . first != this . last ) { buf . append ( "range " ) ; } if ( isMove ( ) ) { buf . append ( "" ) ; } else { buf . append ( "" ) ; } buf . append ( this . first ) ; buf . append ( " - " ) ; buf . append ( this . last ) ; return buf . toString ( ) ; } } private class ParentIterator implements Iterator { private Iterator eventIter ; private Iterator sourceNodeIter ; private Iterator rangeNodeIter ; private Iterator trackedNodeIter ; public ParentIterator ( ) { this . eventIter = RewriteEventStore . this . eventLookup . keySet ( ) . iterator ( ) ; if ( RewriteEventStore . this . nodeCopySources != null ) { this . sourceNodeIter = RewriteEventStore . this . nodeCopySources . iterator ( ) ; } else { this . sourceNodeIter = Collections . EMPTY_LIST . iterator ( ) ; } if ( RewriteEventStore . this . nodeRangeInfos != null ) { this . rangeNodeIter = RewriteEventStore . this . nodeRangeInfos . keySet ( ) . iterator ( ) ; } else { this . rangeNodeIter = Collections . EMPTY_LIST . iterator ( ) ; } if ( RewriteEventStore . this . trackedNodes != null ) { this . trackedNodeIter = RewriteEventStore . this . trackedNodes . keySet ( ) . iterator ( ) ; } else { this . trackedNodeIter = Collections . EMPTY_LIST . iterator ( ) ; } } public boolean hasNext ( ) { return this . eventIter . hasNext ( ) || this . sourceNodeIter . hasNext ( ) || this . rangeNodeIter . hasNext ( ) || this . trackedNodeIter . hasNext ( ) ; } public Object next ( ) { if ( this . eventIter . hasNext ( ) ) { return this . eventIter . next ( ) ; } if ( this . sourceNodeIter . hasNext ( ) ) { return ( ( CopySourceInfo ) this . sourceNodeIter . next ( ) ) . getNode ( ) ; } if ( this . rangeNodeIter . hasNext ( ) ) { return ( ( PropertyLocation ) this . rangeNodeIter . next ( ) ) . getParent ( ) ; } return this . trackedNodeIter . next ( ) ; } public void remove ( ) { throw new UnsupportedOperationException ( ) ; } } public final static int NEW = 1 ; public final static int ORIGINAL = 2 ; public final static int BOTH = NEW | ORIGINAL ; final Map eventLookup ; private EventHolder lastEvent ; private Map editGroups ; List nodeCopySources ; Map nodeRangeInfos ; Map trackedNodes ; private Set insertBoundToPrevious ; private INodePropertyMapper nodePropertyMapper ; private static final String INTERNAL_PLACEHOLDER_PROPERTY = "" ; public RewriteEventStore ( ) { this . eventLookup = new HashMap ( ) ; this . lastEvent = null ; this . editGroups = null ; this . trackedNodes = null ; this . insertBoundToPrevious = null ; this . nodePropertyMapper = null ; this . nodeCopySources = null ; this . nodeRangeInfos = null ; } public void setNodePropertyMapper ( INodePropertyMapper nodePropertyMapper ) { this . nodePropertyMapper = nodePropertyMapper ; } public void clear ( ) { this . eventLookup . clear ( ) ; this . lastEvent = null ; this . trackedNodes = null ; this . editGroups = null ; this . insertBoundToPrevious = null ; this . nodeCopySources = null ; } public void addEvent ( ASTNode parent , StructuralPropertyDescriptor childProperty , RewriteEvent event ) { validateHasChildProperty ( parent , childProperty ) ; if ( event . isListRewrite ( ) ) { validateIsListProperty ( childProperty ) ; } EventHolder holder = new EventHolder ( parent , childProperty , event ) ; List entriesList = ( List ) this . eventLookup . get ( parent ) ; if ( entriesList != null ) { for ( int i = 0 ; i < entriesList . size ( ) ; i ++ ) { EventHolder curr = ( EventHolder ) entriesList . get ( i ) ; if ( curr . childProperty == childProperty ) { entriesList . set ( i , holder ) ; this . lastEvent = null ; return ; } } } else { entriesList = new ArrayList ( 3 ) ; this . eventLookup . put ( parent , entriesList ) ; } entriesList . add ( holder ) ; } public RewriteEvent getEvent ( ASTNode parent , StructuralPropertyDescriptor property ) { validateHasChildProperty ( parent , property ) ; if ( this . lastEvent != null && this . lastEvent . parent == parent && this . lastEvent . childProperty == property ) { return this . lastEvent . event ; } List entriesList = ( List ) this . eventLookup . get ( parent ) ; if ( entriesList != null ) { for ( int i = 0 ; i < entriesList . size ( ) ; i ++ ) { EventHolder holder = ( EventHolder ) entriesList . get ( i ) ; if ( holder . childProperty == property ) { this . lastEvent = holder ; return holder . event ; } } } return null ; } public NodeRewriteEvent getNodeEvent ( ASTNode parent , StructuralPropertyDescriptor childProperty , boolean forceCreation ) { validateIsNodeProperty ( childProperty ) ; NodeRewriteEvent event = ( NodeRewriteEvent ) getEvent ( parent , childProperty ) ; if ( event == null && forceCreation ) { Object originalValue = accessOriginalValue ( parent , childProperty ) ; event = new NodeRewriteEvent ( originalValue , originalValue ) ; addEvent ( parent , childProperty , event ) ; } return event ; } public ListRewriteEvent getListEvent ( ASTNode parent , StructuralPropertyDescriptor childProperty , boolean forceCreation ) { validateIsListProperty ( childProperty ) ; ListRewriteEvent event = ( ListRewriteEvent ) getEvent ( parent , childProperty ) ; if ( event == null && forceCreation ) { List originalValue = ( List ) accessOriginalValue ( parent , childProperty ) ; event = new ListRewriteEvent ( originalValue ) ; addEvent ( parent , childProperty , event ) ; } return event ; } public Iterator getChangeRootIterator ( ) { return new ParentIterator ( ) ; } public boolean hasChangedProperties ( ASTNode parent ) { List entriesList = ( List ) this . eventLookup . get ( parent ) ; if ( entriesList != null ) { for ( int i = 0 ; i < entriesList . size ( ) ; i ++ ) { EventHolder holder = ( EventHolder ) entriesList . get ( i ) ; if ( holder . event . getChangeKind ( ) != RewriteEvent . UNCHANGED ) { return true ; } } } return false ; } public PropertyLocation getPropertyLocation ( Object value , int kind ) { for ( Iterator iter = this . eventLookup . values ( ) . iterator ( ) ; iter . hasNext ( ) ; ) { List events = ( List ) iter . next ( ) ; for ( int i = 0 ; i < events . size ( ) ; i ++ ) { EventHolder holder = ( EventHolder ) events . get ( i ) ; RewriteEvent event = holder . event ; if ( isNodeInEvent ( event , value , kind ) ) { return new PropertyLocation ( holder . parent , holder . childProperty ) ; } if ( event . isListRewrite ( ) ) { RewriteEvent [ ] children = event . getChildren ( ) ; for ( int k = 0 ; k < children . length ; k ++ ) { if ( isNodeInEvent ( children [ k ] , value , kind ) ) { return new PropertyLocation ( holder . parent , holder . childProperty ) ; } } } } } if ( value instanceof ASTNode ) { ASTNode node = ( ASTNode ) value ; return new PropertyLocation ( node . getParent ( ) , node . getLocationInParent ( ) ) ; } return null ; } public RewriteEvent findEvent ( Object value , int kind ) { for ( Iterator iter = this . eventLookup . values ( ) . iterator ( ) ; iter . hasNext ( ) ; ) { List events = ( List ) iter . next ( ) ; for ( int i = 0 ; i < events . size ( ) ; i ++ ) { RewriteEvent event = ( ( EventHolder ) events . get ( i ) ) . event ; if ( isNodeInEvent ( event , value , kind ) ) { return event ; } if ( event . isListRewrite ( ) ) { RewriteEvent [ ] children = event . getChildren ( ) ; for ( int k = 0 ; k < children . length ; k ++ ) { if ( isNodeInEvent ( children [ k ] , value , kind ) ) { return children [ k ] ; } } } } } return null ; } private boolean isNodeInEvent ( RewriteEvent event , Object value , int kind ) { if ( ( ( kind & NEW ) != 0 ) && event . getNewValue ( ) == value ) { return true ; } if ( ( ( kind & ORIGINAL ) != 0 ) && event . getOriginalValue ( ) == value ) { return true ; } return false ; } public Object getOriginalValue ( ASTNode parent , StructuralPropertyDescriptor property ) { RewriteEvent event = getEvent ( parent , property ) ; if ( event != null ) { return event . getOriginalValue ( ) ; } return accessOriginalValue ( parent , property ) ; } public Object getNewValue ( ASTNode parent , StructuralPropertyDescriptor property ) { RewriteEvent event = getEvent ( parent , property ) ; if ( event != null ) { return event . getNewValue ( ) ; } return accessOriginalValue ( parent , property ) ; } public List getChangedPropertieEvents ( ASTNode parent ) { List changedPropertiesEvent = new ArrayList ( ) ; List entriesList = ( List ) this . eventLookup . get ( parent ) ; if ( entriesList != null ) { for ( int i = 0 ; i < entriesList . size ( ) ; i ++ ) { EventHolder holder = ( EventHolder ) entriesList . get ( i ) ; if ( holder . event . getChangeKind ( ) != RewriteEvent . UNCHANGED ) { changedPropertiesEvent . add ( holder . event ) ; } } } return changedPropertiesEvent ; } public int getChangeKind ( ASTNode node ) { RewriteEvent event = findEvent ( node , ORIGINAL ) ; if ( event != null ) { return event . getChangeKind ( ) ; } return RewriteEvent . UNCHANGED ; } private Object accessOriginalValue ( ASTNode parent , StructuralPropertyDescriptor childProperty ) { if ( this . nodePropertyMapper != null ) { return this . nodePropertyMapper . getOriginalValue ( parent , childProperty ) ; } return parent . getStructuralProperty ( childProperty ) ; } public TextEditGroup getEventEditGroup ( RewriteEvent event ) { if ( this . editGroups == null ) { return null ; } return ( TextEditGroup ) this . editGroups . get ( event ) ; } public void setEventEditGroup ( RewriteEvent event , TextEditGroup editGroup ) { if ( this . editGroups == null ) { this . editGroups = new IdentityHashMap ( 5 ) ; } this . editGroups . put ( event , editGroup ) ; } public final TextEditGroup getTrackedNodeData ( ASTNode node ) { if ( this . trackedNodes != null ) { return ( TextEditGroup ) this . trackedNodes . get ( node ) ; } return null ; } public void setTrackedNodeData ( ASTNode node , TextEditGroup editGroup ) { if ( this . trackedNodes == null ) { this . trackedNodes = new IdentityHashMap ( ) ; } this . trackedNodes . put ( node , editGroup ) ; } public final void markAsTracked ( ASTNode node , TextEditGroup editGroup ) { if ( getTrackedNodeData ( node ) != null ) { throw new IllegalArgumentException ( "" ) ; } setTrackedNodeData ( node , editGroup ) ; } private final CopySourceInfo createCopySourceInfo ( PropertyLocation location , ASTNode node , boolean isMove ) { CopySourceInfo copySource = new CopySourceInfo ( location , node , isMove ) ; if ( this . nodeCopySources == null ) { this . nodeCopySources = new ArrayList ( ) ; } this . nodeCopySources . add ( copySource ) ; return copySource ; } public final CopySourceInfo markAsCopySource ( ASTNode parent , StructuralPropertyDescriptor property , ASTNode node , boolean isMove ) { return createCopySourceInfo ( new PropertyLocation ( parent , property ) , node , isMove ) ; } public final boolean isRangeCopyPlaceholder ( ASTNode node ) { return node . getProperty ( INTERNAL_PLACEHOLDER_PROPERTY ) != null ; } public final CopySourceInfo createRangeCopy ( ASTNode parent , StructuralPropertyDescriptor childProperty , ASTNode first , ASTNode last , boolean isMove , ASTNode internalPlaceholder , ASTNode replacingNode , TextEditGroup editGroup ) { CopySourceInfo copyInfo = createCopySourceInfo ( null , internalPlaceholder , isMove ) ; internalPlaceholder . setProperty ( INTERNAL_PLACEHOLDER_PROPERTY , internalPlaceholder ) ; NodeRangeInfo copyRangeInfo = new NodeRangeInfo ( parent , childProperty , first , last , copyInfo , replacingNode , editGroup ) ; ListRewriteEvent listEvent = getListEvent ( parent , childProperty , true ) ; int indexFirst = listEvent . getIndex ( first , ListRewriteEvent . OLD ) ; if ( indexFirst == - 1 ) { throw new IllegalArgumentException ( "" ) ; } int indexLast = listEvent . getIndex ( last , ListRewriteEvent . OLD ) ; if ( indexLast == - 1 ) { throw new IllegalArgumentException ( "" ) ; } if ( indexFirst > indexLast ) { throw new IllegalArgumentException ( "" ) ; } if ( this . nodeRangeInfos == null ) { this . nodeRangeInfos = new HashMap ( ) ; } PropertyLocation loc = new PropertyLocation ( parent , childProperty ) ; List innerList = ( List ) this . nodeRangeInfos . get ( loc ) ; if ( innerList == null ) { innerList = new ArrayList ( 2 ) ; this . nodeRangeInfos . put ( loc , innerList ) ; } else { assertNoOverlap ( listEvent , indexFirst , indexLast , innerList ) ; } innerList . add ( copyRangeInfo ) ; return copyInfo ; } public CopySourceInfo [ ] getNodeCopySources ( ASTNode node ) { if ( this . nodeCopySources == null ) { return null ; } return internalGetCopySources ( this . nodeCopySources , node ) ; } public CopySourceInfo [ ] internalGetCopySources ( List copySources , ASTNode node ) { ArrayList res = new ArrayList ( 3 ) ; for ( int i = 0 ; i < copySources . size ( ) ; i ++ ) { CopySourceInfo curr = ( CopySourceInfo ) copySources . get ( i ) ; if ( curr . getNode ( ) == node ) { res . add ( curr ) ; } } if ( res . isEmpty ( ) ) { return null ; } CopySourceInfo [ ] arr = ( CopySourceInfo [ ] ) res . toArray ( new CopySourceInfo [ res . size ( ) ] ) ; Arrays . sort ( arr ) ; return arr ; } private void assertNoOverlap ( ListRewriteEvent listEvent , int indexFirst , int indexLast , List innerList ) { for ( Iterator iter = innerList . iterator ( ) ; iter . hasNext ( ) ; ) { NodeRangeInfo curr = ( NodeRangeInfo ) iter . next ( ) ; int currStart = listEvent . getIndex ( curr . getStartNode ( ) , ListRewriteEvent . BOTH ) ; int currEnd = listEvent . getIndex ( curr . getEndNode ( ) , ListRewriteEvent . BOTH ) ; if ( currStart < indexFirst && currEnd < indexLast && currEnd >= indexFirst || currStart > indexFirst && currStart <= currEnd && currEnd > indexLast ) { throw new IllegalArgumentException ( "" ) ; } } } public void prepareMovedNodes ( TargetSourceRangeComputer sourceRangeComputer ) { if ( this . nodeCopySources != null ) { prepareSingleNodeCopies ( ) ; } if ( this . nodeRangeInfos != null ) { prepareNodeRangeCopies ( sourceRangeComputer ) ; } } public void revertMovedNodes ( ) { if ( this . nodeRangeInfos != null ) { removeMoveRangePlaceholders ( ) ; } } private void removeMoveRangePlaceholders ( ) { for ( Iterator iter = this . nodeRangeInfos . entrySet ( ) . iterator ( ) ; iter . hasNext ( ) ; ) { Map . Entry entry = ( Map . Entry ) iter . next ( ) ; Set placeholders = new HashSet ( ) ; List rangeInfos = ( List ) entry . getValue ( ) ; for ( int i = 0 ; i < rangeInfos . size ( ) ; i ++ ) { placeholders . add ( ( ( NodeRangeInfo ) rangeInfos . get ( i ) ) . getInternalPlaceholder ( ) ) ; } PropertyLocation loc = ( PropertyLocation ) entry . getKey ( ) ; RewriteEvent [ ] children = getListEvent ( loc . getParent ( ) , loc . getProperty ( ) , true ) . getChildren ( ) ; List revertedChildren = new ArrayList ( ) ; revertListWithRanges ( children , placeholders , revertedChildren ) ; RewriteEvent [ ] revertedChildrenArr = ( RewriteEvent [ ] ) revertedChildren . toArray ( new RewriteEvent [ revertedChildren . size ( ) ] ) ; addEvent ( loc . getParent ( ) , loc . getProperty ( ) , new ListRewriteEvent ( revertedChildrenArr ) ) ; } } private void revertListWithRanges ( RewriteEvent [ ] childEvents , Set placeholders , List revertedChildren ) { for ( int i = 0 ; i < childEvents . length ; i ++ ) { RewriteEvent event = childEvents [ i ] ; ASTNode node = ( ASTNode ) event . getOriginalValue ( ) ; if ( placeholders . contains ( node ) ) { RewriteEvent [ ] placeholderChildren = getListEvent ( node , Block . STATEMENTS_PROPERTY , false ) . getChildren ( ) ; revertListWithRanges ( placeholderChildren , placeholders , revertedChildren ) ; } else { revertedChildren . add ( event ) ; } } } private void prepareNodeRangeCopies ( TargetSourceRangeComputer sourceRangeComputer ) { for ( Iterator iter = this . nodeRangeInfos . entrySet ( ) . iterator ( ) ; iter . hasNext ( ) ; ) { Map . Entry entry = ( Map . Entry ) iter . next ( ) ; List rangeInfos = ( List ) entry . getValue ( ) ; Collections . sort ( rangeInfos ) ; PropertyLocation loc = ( PropertyLocation ) entry . getKey ( ) ; RewriteEvent [ ] children = getListEvent ( loc . getParent ( ) , loc . getProperty ( ) , true ) . getChildren ( ) ; RewriteEvent [ ] newChildren = processListWithRanges ( rangeInfos , children , sourceRangeComputer ) ; addEvent ( loc . getParent ( ) , loc . getProperty ( ) , new ListRewriteEvent ( newChildren ) ) ; } } private RewriteEvent [ ] processListWithRanges ( List rangeInfos , RewriteEvent [ ] childEvents , TargetSourceRangeComputer sourceRangeComputer ) { List newChildEvents = new ArrayList ( childEvents . length ) ; NodeRangeInfo topInfo = null ; Stack newChildrenStack = new Stack ( ) ; Stack topInfoStack = new Stack ( ) ; Iterator rangeInfoIterator = rangeInfos . iterator ( ) ; NodeRangeInfo nextInfo = ( NodeRangeInfo ) rangeInfoIterator . next ( ) ; for ( int k = 0 ; k < childEvents . length ; k ++ ) { RewriteEvent event = childEvents [ k ] ; ASTNode node = ( ASTNode ) event . getOriginalValue ( ) ; while ( nextInfo != null && node == nextInfo . getStartNode ( ) ) { nextInfo . updatePlaceholderSourceRanges ( sourceRangeComputer ) ; Block internalPlaceholder = nextInfo . getInternalPlaceholder ( ) ; RewriteEvent newEvent ; if ( nextInfo . isMove ( ) ) { newEvent = new NodeRewriteEvent ( internalPlaceholder , nextInfo . replacingNode ) ; } else { newEvent = new NodeRewriteEvent ( internalPlaceholder , internalPlaceholder ) ; } newChildEvents . add ( newEvent ) ; if ( nextInfo . editGroup != null ) { setEventEditGroup ( newEvent , nextInfo . editGroup ) ; } newChildrenStack . push ( newChildEvents ) ; topInfoStack . push ( topInfo ) ; newChildEvents = new ArrayList ( childEvents . length ) ; topInfo = nextInfo ; nextInfo = rangeInfoIterator . hasNext ( ) ? ( NodeRangeInfo ) rangeInfoIterator . next ( ) : null ; } newChildEvents . add ( event ) ; while ( topInfo != null && node == topInfo . getEndNode ( ) ) { RewriteEvent [ ] placeholderChildEvents = ( RewriteEvent [ ] ) newChildEvents . toArray ( new RewriteEvent [ newChildEvents . size ( ) ] ) ; Block internalPlaceholder = topInfo . getInternalPlaceholder ( ) ; addEvent ( internalPlaceholder , Block . STATEMENTS_PROPERTY , new ListRewriteEvent ( placeholderChildEvents ) ) ; newChildEvents = ( List ) newChildrenStack . pop ( ) ; topInfo = ( NodeRangeInfo ) topInfoStack . pop ( ) ; } } return ( RewriteEvent [ ] ) newChildEvents . toArray ( new RewriteEvent [ newChildEvents . size ( ) ] ) ; } private void prepareSingleNodeCopies ( ) { for ( int i = 0 ; i < this . nodeCopySources . size ( ) ; i ++ ) { CopySourceInfo curr = ( CopySourceInfo ) this . nodeCopySources . get ( i ) ; if ( curr . isMove && curr . location != null ) { doMarkMovedAsRemoved ( curr , curr . location . getParent ( ) , curr . location . getProperty ( ) ) ; } } } private void doMarkMovedAsRemoved ( CopySourceInfo curr , ASTNode parent , StructuralPropertyDescriptor childProperty ) { if ( childProperty . isChildListProperty ( ) ) { ListRewriteEvent event = getListEvent ( parent , childProperty , true ) ; int index = event . getIndex ( curr . getNode ( ) , ListRewriteEvent . OLD ) ; if ( index != - 1 && event . getChangeKind ( index ) == RewriteEvent . UNCHANGED ) { event . setNewValue ( null , index ) ; } } else { NodeRewriteEvent event = getNodeEvent ( parent , childProperty , true ) ; if ( event . getChangeKind ( ) == RewriteEvent . UNCHANGED ) { event . setNewValue ( null ) ; } } } public boolean isInsertBoundToPrevious ( ASTNode node ) { if ( this . insertBoundToPrevious != null ) { return this . insertBoundToPrevious . contains ( node ) ; } return false ; } public void setInsertBoundToPrevious ( ASTNode node ) { if ( this . insertBoundToPrevious == null ) { this . insertBoundToPrevious = new HashSet ( ) ; } this . insertBoundToPrevious . add ( node ) ; } private void validateIsListProperty ( StructuralPropertyDescriptor property ) { if ( ! property . isChildListProperty ( ) ) { String message = property . getId ( ) + "" ; throw new IllegalArgumentException ( message ) ; } } private void validateHasChildProperty ( ASTNode parent , StructuralPropertyDescriptor property ) { if ( ! parent . structuralPropertiesForType ( ) . contains ( property ) ) { String message = Signature . getSimpleName ( parent . getClass ( ) . getName ( ) ) + "" + property . getId ( ) ; throw new IllegalArgumentException ( message ) ; } } private void validateIsNodeProperty ( StructuralPropertyDescriptor property ) { if ( property . isChildListProperty ( ) ) { String message = property . getId ( ) + "" ; throw new IllegalArgumentException ( message ) ; } } public String toString ( ) { StringBuffer buf = new StringBuffer ( ) ; for ( Iterator iter = this . eventLookup . values ( ) . iterator ( ) ; iter . hasNext ( ) ; ) { List events = ( List ) iter . next ( ) ; for ( int i = 0 ; i < events . size ( ) ; i ++ ) { buf . append ( events . get ( i ) . toString ( ) ) . append ( '\n' ) ; } } return buf . toString ( ) ; } public static boolean isNewNode ( ASTNode node ) { return ( node . getFlags ( ) & ASTNode . ORIGINAL ) == 0 ; } } </s>