NodeList.java revision cbaf4495c17eb3383e8d2b40db9a4fe92221d118
1515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggenpackage com.github.javaparser.ast;
2515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
3db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggenimport com.github.javaparser.HasParentNode;
4263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassettiimport com.github.javaparser.ast.observing.AstObserver;
5c77e046d2a645bf42f9450bd293e0ba69300a309Federico Tomassettiimport com.github.javaparser.ast.observing.Observable;
6515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggenimport com.github.javaparser.ast.visitor.GenericVisitor;
7008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilienimport com.github.javaparser.ast.visitor.Visitable;
8515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggenimport com.github.javaparser.ast.visitor.VoidVisitor;
9515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
106d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassettiimport java.util.*;
11c77e046d2a645bf42f9450bd293e0ba69300a309Federico Tomassettiimport java.util.function.Consumer;
12c77e046d2a645bf42f9450bd293e0ba69300a309Federico Tomassettiimport java.util.function.Predicate;
13c77e046d2a645bf42f9450bd293e0ba69300a309Federico Tomassettiimport java.util.function.UnaryOperator;
146d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassettiimport java.util.stream.Stream;
156d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti
16515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen/**
17db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen * A list of nodes.
18515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen *
19515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen * @param <N> the type of nodes contained.
20515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen */
21c77e046d2a645bf42f9450bd293e0ba69300a309Federico Tomassettipublic class NodeList<N extends Node> implements List<N>, Iterable<N>, HasParentNode<NodeList<N>>, Visitable, Observable {
22515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    private List<N> innerList = new ArrayList<>(0);
23515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
24db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    private Node parentNode;
25db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen
26263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti    private List<AstObserver> observers = new ArrayList<>();
276d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti
28515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public NodeList() {
29db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen        this(null);
30515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
31515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
32515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public NodeList(Node parent) {
33515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        setParentNode(parent);
34515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
35515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
36f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
37f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean add(N node) {
386d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti        notifyElementAdded(innerList.size(), node);
39515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        own(node);
40f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.add(node);
41515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
42515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
43515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    private void own(N node) {
44515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        if (node == null) {
45515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen            return;
46515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        }
47515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        setAsParentNodeOf(node);
48515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
49515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
50515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public boolean remove(Node node) {
51c0e1f8e102a33dc34c41318ba55469516fff0993Federico Tomassetti        int index = innerList.indexOf(node);
52c0e1f8e102a33dc34c41318ba55469516fff0993Federico Tomassetti        if (index != -1) {
53c0e1f8e102a33dc34c41318ba55469516fff0993Federico Tomassetti            notifyElementRemoved(index, node);
54c0e1f8e102a33dc34c41318ba55469516fff0993Federico Tomassetti            node.setParentNode(null);
55c0e1f8e102a33dc34c41318ba55469516fff0993Federico Tomassetti        }
56515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        boolean remove = innerList.remove(node);
57515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return remove;
58515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
59515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
60515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public static <X extends Node> NodeList<X> nodeList(X... nodes) {
61515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        final NodeList<X> nodeList = new NodeList<>();
62515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        for (X node : nodes) {
63515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen            nodeList.add(node);
64515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        }
65515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return nodeList;
66515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
67515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
68515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public static <X extends Node> NodeList<X> nodeList(Collection<X> nodes) {
69515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        final NodeList<X> nodeList = new NodeList<>();
70515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        for (X node : nodes) {
71515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen            nodeList.add(node);
72515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        }
73515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return nodeList;
74515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
75515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
76515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public static <X extends Node> NodeList<X> nodeList(NodeList<X> nodes) {
77515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        final NodeList<X> nodeList = new NodeList<>();
78515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        for (X node : nodes) {
79515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen            nodeList.add(node);
80515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        }
81515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return nodeList;
82515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
83515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
84515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public boolean contains(N node) {
85515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return innerList.contains(node);
86515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
87515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
88f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
89515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public Stream<N> stream() {
90515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return innerList.stream();
91515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
92515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
93f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
94515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public int size() {
95515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return innerList.size();
96515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
97515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
98f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
99515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public N get(int i) {
100515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return innerList.get(i);
101515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
102515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
103515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    @Override
104515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public Iterator<N> iterator() {
105515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        // TODO take care of "Iterator.remove"
106515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return innerList.iterator();
107515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
108515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
109f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
110f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public N set(int index, N element) {
111c7d2927625db7201d35d891e1751c91edfebd285Federico Tomassetti        notifyElementRemoved(index, innerList.get(index));
112c7d2927625db7201d35d891e1751c91edfebd285Federico Tomassetti        notifyElementAdded(index, element);
113515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        setAsParentNodeOf(element);
114f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.set(index, element);
115515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
116515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
117f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
118f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public N remove(int index) {
119263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti        notifyElementRemoved(index, innerList.get(index));
120f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        N remove = innerList.remove(index);
121f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        if (remove != null)
122f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien            remove.setParentNode(null);
123f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return remove;
124515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
125515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
126f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
127515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public boolean isEmpty() {
128515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return innerList.isEmpty();
129515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
130515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
131f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
132515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public void sort(Comparator<? super N> comparator) {
133515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        Collections.sort(innerList, comparator);
134515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
135515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
136515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public void addAll(NodeList<N> otherList) {
137515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        for (N node : otherList) {
138515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen            add(node);
139515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        }
140515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
141515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
142f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
143f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public void add(int index, N node) {
1446d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti        notifyElementAdded(index, node);
145515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        own(node);
146515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        innerList.add(index, node);
147515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
148db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen
149db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    @Override
150008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien    public Optional<Node> getParentNode() {
151008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien        return Optional.ofNullable(parentNode);
152db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    }
153db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen
154008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien    /**
155008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien     * Sets the parentNode
156008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien     *
157008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien     * @param parentNode the parentNode
158008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien     * @return this, the NodeList
159008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien     */
160db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    @Override
161db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    public NodeList<N> setParentNode(Node parentNode) {
162db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen        this.parentNode = parentNode;
163db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen        setAsParentNodeOf(innerList);
164db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen        return this;
165db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    }
166db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen
167db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    @Override
168db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    public Node getParentNodeForChildren() {
169db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen        return parentNode;
170db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    }
171db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen
172008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien    @Override
173db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
174db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen        return v.visit(this, arg);
175db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    }
176db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen
177008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien    @Override
178db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    public <A> void accept(final VoidVisitor<A> v, final A arg) {
179db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen        v.visit(this, arg);
180db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    }
181db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen
182f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
183f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @param action
184f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.lang.Iterable#forEach(java.util.function.Consumer)
185f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
186f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
187f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public void forEach(Consumer<? super N> action) {
188f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        innerList.forEach(action);
189f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
190f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
191f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
192f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @param o
193f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @return
194f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#contains(java.lang.Object)
195f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
196f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
197f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean contains(Object o) {
198f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.contains(o);
199f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
200f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
201f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
202f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @return
203f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#toArray()
204f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
205f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
206f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public Object[] toArray() {
207f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.toArray();
208f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
209f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
210f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
211f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @param a
212f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @return
213f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#toArray(java.lang.Object[])
214f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
215f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
216f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public <T> T[] toArray(T[] a) {
217f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.toArray(a);
218f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
219f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
220f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
221f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @param o
222f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @return
223f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#remove(java.lang.Object)
224f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
225f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
226f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean remove(Object o) {
227ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti        if (o instanceof Node) {
228ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti            return remove((Node)o);
229ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti        } else {
230ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti            return false;
231ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti        }
232f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
233f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
234f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
235f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @param c
236f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @return
237f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#containsAll(java.util.Collection)
238f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
239f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
240f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean containsAll(Collection<?> c) {
241f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.containsAll(c);
242f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
243f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
244f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
245f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @param c
246f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @return
247f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#addAll(java.util.Collection)
248f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
249f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
250f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean addAll(Collection<? extends N> c) {
2513e8757e510df2bbdb1ef8bedf92538b17a5e36c6Federico Tomassetti        c.forEach(e -> add(e));
2523e8757e510df2bbdb1ef8bedf92538b17a5e36c6Federico Tomassetti        return !c.isEmpty();
253f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
254f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
255f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
256f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @param index
257f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @param c
258f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @return
259f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#addAll(int, java.util.Collection)
260f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
261f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
262f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean addAll(int index, Collection<? extends N> c) {
263150ecb8efecf1bbe22f23e6e2869ef4f59fe3523Federico Tomassetti        for (N e : c) {
264150ecb8efecf1bbe22f23e6e2869ef4f59fe3523Federico Tomassetti            add(index++, e);
2653e8757e510df2bbdb1ef8bedf92538b17a5e36c6Federico Tomassetti        }
266150ecb8efecf1bbe22f23e6e2869ef4f59fe3523Federico Tomassetti        return !c.isEmpty();
267f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
268f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
269f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
270f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @param c
271f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @return
272f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#removeAll(java.util.Collection)
273f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
274f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
275f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean removeAll(Collection<?> c) {
276ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti        boolean changed = false;
277ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti        for (Object e : c) {
278ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti            changed = remove(e) || changed;
279f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        }
280ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti        return changed;
281f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
282f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
283f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
284f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @param c
285f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @return
286f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#retainAll(java.util.Collection)
287f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
288f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
289f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean retainAll(Collection<?> c) {
290cbaf4495c17eb3383e8d2b40db9a4fe92221d118Federico Tomassetti        boolean changed = false;
291cbaf4495c17eb3383e8d2b40db9a4fe92221d118Federico Tomassetti        for (Object e : this.stream().filter(it -> !c.contains(it)).toArray()) {
292cbaf4495c17eb3383e8d2b40db9a4fe92221d118Federico Tomassetti            if (!c.contains(e)) {
293cbaf4495c17eb3383e8d2b40db9a4fe92221d118Federico Tomassetti                changed = remove(e) || changed;
294cbaf4495c17eb3383e8d2b40db9a4fe92221d118Federico Tomassetti            }
295cbaf4495c17eb3383e8d2b40db9a4fe92221d118Federico Tomassetti        }
296cbaf4495c17eb3383e8d2b40db9a4fe92221d118Federico Tomassetti        return changed;
297f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
298f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
299f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
300f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @param operator
301f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#replaceAll(java.util.function.UnaryOperator)
302f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
303f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
304f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public void replaceAll(UnaryOperator<N> operator) {
305f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        innerList.replaceAll(operator);
306f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
307f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
308f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
309f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @param filter
310f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @return
311f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.Collection#removeIf(java.util.function.Predicate)
312f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
313f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
314f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean removeIf(Predicate<? super N> filter) {
315f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        innerList.stream().filter(filter).forEach(n -> {
316f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien            if (n != null)
317f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien                n.setParentNode(null);
318f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        });
319f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.removeIf(filter);
320f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
321f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
322f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
323f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     *
324f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#clear()
325f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
326f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
327f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public void clear() {
3284a25ff22c5db52fe1f21f8939e4a47a73ff2f61bFederico Tomassetti        while (!isEmpty()) {
3294a25ff22c5db52fe1f21f8939e4a47a73ff2f61bFederico Tomassetti            remove(0);
3304a25ff22c5db52fe1f21f8939e4a47a73ff2f61bFederico Tomassetti        }
331f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
332f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
333f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
334f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @param o
335f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @return
336f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#equals(java.lang.Object)
337f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
338f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
339f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean equals(Object o) {
340f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.equals(o);
341f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
342f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
343f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
344f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @return
345f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#hashCode()
346f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
347f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
348f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public int hashCode() {
349f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.hashCode();
350f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
351f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
352f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
353f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @param o
354f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @return
355f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#indexOf(java.lang.Object)
356f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
357f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
358f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public int indexOf(Object o) {
359f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.indexOf(o);
360f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
361f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
362f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
363f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @param o
364f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @return
365f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#lastIndexOf(java.lang.Object)
366f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
367f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
368f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public int lastIndexOf(Object o) {
369f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.lastIndexOf(o);
370f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
371f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
372f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
373f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @return
374f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#listIterator()
375f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
376f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
377f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public ListIterator<N> listIterator() {
378f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.listIterator();
379f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
380f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
381f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
382f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @param index
383f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @return
384f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#listIterator(int)
385f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
386f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
387f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public ListIterator<N> listIterator(int index) {
388f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.listIterator(index);
389f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
390f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
391f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
392f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @return
393f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.Collection#parallelStream()
394f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
395f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
396f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public Stream<N> parallelStream() {
397f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.parallelStream();
398f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
399f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
400f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
401f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @param fromIndex
402f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @param toIndex
403f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @return
404f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#subList(int, int)
405f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
406f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
407f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public List<N> subList(int fromIndex, int toIndex) {
408f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.subList(fromIndex, toIndex);
409f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
410f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
411f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
412f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @return
413f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#spliterator()
414f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
415f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
416f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public Spliterator<N> spliterator() {
417f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.spliterator();
418c77e046d2a645bf42f9450bd293e0ba69300a309Federico Tomassetti    }
419263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti
4206d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti    private void notifyElementAdded(int index, Node nodeAddedOrRemoved) {
42117c60f99a730acb68276303e7c6fcdf0a376258cFederico Tomassetti        this.observers.forEach(o -> o.listChange(this, AstObserver.ListChangeType.ADDITION, index, nodeAddedOrRemoved));
4226d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti    }
4236d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti
4246d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti    private void notifyElementRemoved(int index, Node nodeAddedOrRemoved) {
42517c60f99a730acb68276303e7c6fcdf0a376258cFederico Tomassetti        this.observers.forEach(o -> o.listChange(this, AstObserver.ListChangeType.REMOVAL, index, nodeAddedOrRemoved));
4266d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti    }
4276d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti
4286d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti    @Override
429263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti    public void unregister(AstObserver observer) {
4306d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti        this.observers.remove(observer);
4316d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti    }
4326d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti
4336d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti    @Override
434263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti    public void register(AstObserver observer) {
4356d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti        this.observers.add(observer);
436263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti    }
437263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti
438263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti    @Override
439263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti    public boolean isRegistered(AstObserver observer) {
440263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti        return this.observers.contains(observer);
441f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
442f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
443515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen}
444