NodeList.java revision c9f2a4fe27453e09a268730cd0ab76a42016475f
176f5dc9d043237e8ada0e6597d6c8d48b67f6d8fFederico Tomassetti/*
276f5dc9d043237e8ada0e6597d6c8d48b67f6d8fFederico Tomassetti * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
376f5dc9d043237e8ada0e6597d6c8d48b67f6d8fFederico Tomassetti * Copyright (C) 2011, 2013-2016 The JavaParser Team.
476f5dc9d043237e8ada0e6597d6c8d48b67f6d8fFederico Tomassetti *
576f5dc9d043237e8ada0e6597d6c8d48b67f6d8fFederico Tomassetti * This file is part of JavaParser.
676f5dc9d043237e8ada0e6597d6c8d48b67f6d8fFederico Tomassetti *
776f5dc9d043237e8ada0e6597d6c8d48b67f6d8fFederico Tomassetti * JavaParser can be used either under the terms of
876f5dc9d043237e8ada0e6597d6c8d48b67f6d8fFederico Tomassetti * a) the GNU Lesser General Public License as published by
976f5dc9d043237e8ada0e6597d6c8d48b67f6d8fFederico Tomassetti *     the Free Software Foundation, either version 3 of the License, or
1076f5dc9d043237e8ada0e6597d6c8d48b67f6d8fFederico Tomassetti *     (at your option) any later version.
1176f5dc9d043237e8ada0e6597d6c8d48b67f6d8fFederico Tomassetti * b) the terms of the Apache License
1276f5dc9d043237e8ada0e6597d6c8d48b67f6d8fFederico Tomassetti *
1376f5dc9d043237e8ada0e6597d6c8d48b67f6d8fFederico Tomassetti * You should have received a copy of both licenses in LICENCE.LGPL and
1476f5dc9d043237e8ada0e6597d6c8d48b67f6d8fFederico Tomassetti * LICENCE.APACHE. Please refer to those files for details.
1576f5dc9d043237e8ada0e6597d6c8d48b67f6d8fFederico Tomassetti *
1676f5dc9d043237e8ada0e6597d6c8d48b67f6d8fFederico Tomassetti * JavaParser is distributed in the hope that it will be useful,
1776f5dc9d043237e8ada0e6597d6c8d48b67f6d8fFederico Tomassetti * but WITHOUT ANY WARRANTY; without even the implied warranty of
1876f5dc9d043237e8ada0e6597d6c8d48b67f6d8fFederico Tomassetti * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1976f5dc9d043237e8ada0e6597d6c8d48b67f6d8fFederico Tomassetti * GNU Lesser General Public License for more details.
2076f5dc9d043237e8ada0e6597d6c8d48b67f6d8fFederico Tomassetti */
2176f5dc9d043237e8ada0e6597d6c8d48b67f6d8fFederico Tomassetti
22515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggenpackage com.github.javaparser.ast;
23515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
24db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggenimport com.github.javaparser.HasParentNode;
250f8bbe61c2d7132846b8ad13804ae70d62c5c8bcDanny van Bruggenimport com.github.javaparser.ast.observer.AstObserver;
260f8bbe61c2d7132846b8ad13804ae70d62c5c8bcDanny van Bruggenimport com.github.javaparser.ast.observer.Observable;
27515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggenimport com.github.javaparser.ast.visitor.GenericVisitor;
28008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilienimport com.github.javaparser.ast.visitor.Visitable;
29515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggenimport com.github.javaparser.ast.visitor.VoidVisitor;
302adf38a7f2ee394f648d2fe7fc3e9b25810cde9dDanny van Bruggenimport com.github.javaparser.metamodel.InternalProperty;
31515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
326d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassettiimport java.util.*;
33c9f2a4fe27453e09a268730cd0ab76a42016475fDanny van Bruggenimport java.util.function.*;
34c9f2a4fe27453e09a268730cd0ab76a42016475fDanny van Bruggenimport java.util.stream.Collector;
35c9f2a4fe27453e09a268730cd0ab76a42016475fDanny van Bruggenimport java.util.stream.Collectors;
366d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassettiimport java.util.stream.Stream;
376d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti
38515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen/**
39db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen * A list of nodes.
409dfe6cb2a1115f749a6a9adca05297d6b24eb046Danny van Bruggen * It usually has a parent node.
4115c2aa05f936720e8f7efdedbbc68450a6f27fb3Danny van Bruggen * Unlike normal Nodes, this does not mean that it is a child of that parent.
429dfe6cb2a1115f749a6a9adca05297d6b24eb046Danny van Bruggen * Instead, this list will make every node it contains a child of its parent.
439dfe6cb2a1115f749a6a9adca05297d6b24eb046Danny van Bruggen * This way, a NodeList does not create an extra level inside the AST.
44515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen *
45515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen * @param <N> the type of nodes contained.
46515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen */
47c77e046d2a645bf42f9450bd293e0ba69300a309Federico Tomassettipublic class NodeList<N extends Node> implements List<N>, Iterable<N>, HasParentNode<NodeList<N>>, Visitable, Observable {
482adf38a7f2ee394f648d2fe7fc3e9b25810cde9dDanny van Bruggen    @InternalProperty
49515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    private List<N> innerList = new ArrayList<>(0);
50515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
51db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    private Node parentNode;
52db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen
53263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti    private List<AstObserver> observers = new ArrayList<>();
546d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti
55515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public NodeList() {
56f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen        this((Node) null);
57515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
58515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
59515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public NodeList(Node parent) {
60515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        setParentNode(parent);
61515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
62515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
63796e7f15567eeeef96e224d8d00c27fdf1248413Danny van Bruggen    public NodeList(NodeList<N> n) {
64796e7f15567eeeef96e224d8d00c27fdf1248413Danny van Bruggen        this.addAll(n);
65796e7f15567eeeef96e224d8d00c27fdf1248413Danny van Bruggen    }
66796e7f15567eeeef96e224d8d00c27fdf1248413Danny van Bruggen
67f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
68f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean add(N node) {
696d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti        notifyElementAdded(innerList.size(), node);
70515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        own(node);
71f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.add(node);
72515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
73515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
74515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    private void own(N node) {
75515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        if (node == null) {
76515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen            return;
77515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        }
78515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        setAsParentNodeOf(node);
79515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
80515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
81515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public boolean remove(Node node) {
82c0e1f8e102a33dc34c41318ba55469516fff0993Federico Tomassetti        int index = innerList.indexOf(node);
83c0e1f8e102a33dc34c41318ba55469516fff0993Federico Tomassetti        if (index != -1) {
84c0e1f8e102a33dc34c41318ba55469516fff0993Federico Tomassetti            notifyElementRemoved(index, node);
85c0e1f8e102a33dc34c41318ba55469516fff0993Federico Tomassetti            node.setParentNode(null);
86c0e1f8e102a33dc34c41318ba55469516fff0993Federico Tomassetti        }
879dfe6cb2a1115f749a6a9adca05297d6b24eb046Danny van Bruggen        return innerList.remove(node);
88515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
89515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
909dfe6cb2a1115f749a6a9adca05297d6b24eb046Danny van Bruggen    @SafeVarargs
91515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public static <X extends Node> NodeList<X> nodeList(X... nodes) {
92515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        final NodeList<X> nodeList = new NodeList<>();
939dfe6cb2a1115f749a6a9adca05297d6b24eb046Danny van Bruggen        Collections.addAll(nodeList, nodes);
94515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return nodeList;
95515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
96515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
97515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public static <X extends Node> NodeList<X> nodeList(Collection<X> nodes) {
98515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        final NodeList<X> nodeList = new NodeList<>();
99515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        for (X node : nodes) {
100515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen            nodeList.add(node);
101515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        }
102515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return nodeList;
103515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
104515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
105515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public static <X extends Node> NodeList<X> nodeList(NodeList<X> nodes) {
106515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        final NodeList<X> nodeList = new NodeList<>();
1079dfe6cb2a1115f749a6a9adca05297d6b24eb046Danny van Bruggen        nodeList.addAll(nodes);
108515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return nodeList;
109515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
110515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
111515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public boolean contains(N node) {
112515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return innerList.contains(node);
113515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
114515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
115f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
116515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public int size() {
117515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return innerList.size();
118515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
119515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
120f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
121515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public N get(int i) {
122515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return innerList.get(i);
123515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
124515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
125515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    @Override
126515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public Iterator<N> iterator() {
127515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        // TODO take care of "Iterator.remove"
128515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return innerList.iterator();
129515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
130515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
131f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
132f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public N set(int index, N element) {
1330d8f8e5cc0e48d0cc27cf070155ab318fe160a00Federico Tomassetti        notifyElementReplaced(index, element);
134515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        setAsParentNodeOf(element);
135f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.set(index, element);
136515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
137515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
138f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
139f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public N remove(int index) {
140263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti        notifyElementRemoved(index, innerList.get(index));
141f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        N remove = innerList.remove(index);
142f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        if (remove != null)
143f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien            remove.setParentNode(null);
144f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return remove;
145515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
146515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
147f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
148515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public boolean isEmpty() {
149515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return innerList.isEmpty();
150515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
151515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
152f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
153515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public void sort(Comparator<? super N> comparator) {
154515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        Collections.sort(innerList, comparator);
155515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
156515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
157515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public void addAll(NodeList<N> otherList) {
158515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        for (N node : otherList) {
159515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen            add(node);
160515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        }
161515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
162515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
163f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
164f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public void add(int index, N node) {
1656d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti        notifyElementAdded(index, node);
166515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        own(node);
167515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        innerList.add(index, node);
168515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
169db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen
170db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    @Override
171008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien    public Optional<Node> getParentNode() {
172008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien        return Optional.ofNullable(parentNode);
173db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    }
174db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen
175008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien    /**
176008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien     * Sets the parentNode
1774296abb695b767f7471dd255d0679516183b062aDanny van Bruggen     *
178008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien     * @param parentNode the parentNode
179008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien     * @return this, the NodeList
180008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien     */
181db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    @Override
182db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    public NodeList<N> setParentNode(Node parentNode) {
183db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen        this.parentNode = parentNode;
184db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen        setAsParentNodeOf(innerList);
185db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen        return this;
186db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    }
187db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen
188db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    @Override
189db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    public Node getParentNodeForChildren() {
190db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen        return parentNode;
191db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    }
192db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen
193008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien    @Override
194db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
195db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen        return v.visit(this, arg);
196db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    }
197db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen
198008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien    @Override
199db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    public <A> void accept(final VoidVisitor<A> v, final A arg) {
200db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen        v.visit(this, arg);
201db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    }
202db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen
203f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
204f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.lang.Iterable#forEach(java.util.function.Consumer)
205f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
206f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
207f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public void forEach(Consumer<? super N> action) {
208f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        innerList.forEach(action);
209f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
210f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
211f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
212f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#contains(java.lang.Object)
213f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
214f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
215f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean contains(Object o) {
216f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.contains(o);
217f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
218f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
219f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
220f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#toArray()
221f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
222f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
223f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public Object[] toArray() {
224f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.toArray();
225f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
226f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
227f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
228f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#toArray(java.lang.Object[])
229f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
230f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
231f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public <T> T[] toArray(T[] a) {
232f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.toArray(a);
233f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
234f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
235f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
236f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#remove(java.lang.Object)
237f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
238f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
239f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean remove(Object o) {
240ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti        if (o instanceof Node) {
2414296abb695b767f7471dd255d0679516183b062aDanny van Bruggen            return remove((Node) o);
242ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti        } else {
243ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti            return false;
244ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti        }
245f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
246f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
247f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
248f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#containsAll(java.util.Collection)
249f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
250f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
251f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean containsAll(Collection<?> c) {
252f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.containsAll(c);
253f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
254f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
255f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
256f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#addAll(java.util.Collection)
257f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
258f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
259f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean addAll(Collection<? extends N> c) {
2609dfe6cb2a1115f749a6a9adca05297d6b24eb046Danny van Bruggen        c.forEach(this::add);
2613e8757e510df2bbdb1ef8bedf92538b17a5e36c6Federico Tomassetti        return !c.isEmpty();
262f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
263f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
264f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
265f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#addAll(int, java.util.Collection)
266f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
267f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
268f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean addAll(int index, Collection<? extends N> c) {
269150ecb8efecf1bbe22f23e6e2869ef4f59fe3523Federico Tomassetti        for (N e : c) {
270150ecb8efecf1bbe22f23e6e2869ef4f59fe3523Federico Tomassetti            add(index++, e);
2713e8757e510df2bbdb1ef8bedf92538b17a5e36c6Federico Tomassetti        }
272150ecb8efecf1bbe22f23e6e2869ef4f59fe3523Federico Tomassetti        return !c.isEmpty();
273f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
274f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
275f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
276f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#removeAll(java.util.Collection)
277f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
278f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
279f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean removeAll(Collection<?> c) {
280ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti        boolean changed = false;
281ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti        for (Object e : c) {
282ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti            changed = remove(e) || changed;
283f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        }
284ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti        return changed;
285f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
286f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
287f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
288f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#retainAll(java.util.Collection)
289f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
290f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
291f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean retainAll(Collection<?> c) {
292cbaf4495c17eb3383e8d2b40db9a4fe92221d118Federico Tomassetti        boolean changed = false;
293cbaf4495c17eb3383e8d2b40db9a4fe92221d118Federico Tomassetti        for (Object e : this.stream().filter(it -> !c.contains(it)).toArray()) {
294cbaf4495c17eb3383e8d2b40db9a4fe92221d118Federico Tomassetti            if (!c.contains(e)) {
295cbaf4495c17eb3383e8d2b40db9a4fe92221d118Federico Tomassetti                changed = remove(e) || changed;
296cbaf4495c17eb3383e8d2b40db9a4fe92221d118Federico Tomassetti            }
297cbaf4495c17eb3383e8d2b40db9a4fe92221d118Federico Tomassetti        }
298cbaf4495c17eb3383e8d2b40db9a4fe92221d118Federico Tomassetti        return changed;
299f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
300f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
301f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
302f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#replaceAll(java.util.function.UnaryOperator)
303f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
304f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
305f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public void replaceAll(UnaryOperator<N> operator) {
3064296abb695b767f7471dd255d0679516183b062aDanny van Bruggen        for (int i = 0; i < this.size(); i++) {
30734ee4b944cf1534361d6d9ca7ba3f9876df5ddb4Federico Tomassetti            set(i, operator.apply(this.get(i)));
30834ee4b944cf1534361d6d9ca7ba3f9876df5ddb4Federico Tomassetti        }
309f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
310f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
311f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
312f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.Collection#removeIf(java.util.function.Predicate)
313f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
314f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
315f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean removeIf(Predicate<? super N> filter) {
31655d475bac6deff387e608ac7f200227a23488ea7Federico Tomassetti        boolean changed = false;
3174296abb695b767f7471dd255d0679516183b062aDanny van Bruggen        for (Object e : this.stream().filter(filter).toArray()) {
31855d475bac6deff387e608ac7f200227a23488ea7Federico Tomassetti            changed = remove(e) || changed;
31955d475bac6deff387e608ac7f200227a23488ea7Federico Tomassetti        }
32055d475bac6deff387e608ac7f200227a23488ea7Federico Tomassetti        return changed;
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     * @see java.util.List#equals(java.lang.Object)
335f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
336f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
337f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean equals(Object o) {
338f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.equals(o);
339f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
340f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
341f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
342f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#hashCode()
343f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
344f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
345f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public int hashCode() {
346f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.hashCode();
347f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
348f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
349f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
350f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#indexOf(java.lang.Object)
351f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
352f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
353f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public int indexOf(Object o) {
354f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.indexOf(o);
355f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
356f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
357f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
358f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#lastIndexOf(java.lang.Object)
359f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
360f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
361f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public int lastIndexOf(Object o) {
362f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.lastIndexOf(o);
363f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
364f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
365f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
366f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#listIterator()
367f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
368f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
369f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public ListIterator<N> listIterator() {
370f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.listIterator();
371f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
372f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
373f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
374f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#listIterator(int)
375f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
376f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
377f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public ListIterator<N> listIterator(int index) {
378f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.listIterator(index);
379f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
380f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
381f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
382f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.Collection#parallelStream()
383f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
384f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
385f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public Stream<N> parallelStream() {
386f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.parallelStream();
387f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
388f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
389f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
390f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#subList(int, int)
391f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
392f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
393f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public List<N> subList(int fromIndex, int toIndex) {
394f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.subList(fromIndex, toIndex);
395f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
396f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
397f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
398f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#spliterator()
399f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
400f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
401f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public Spliterator<N> spliterator() {
402f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.spliterator();
403c77e046d2a645bf42f9450bd293e0ba69300a309Federico Tomassetti    }
404263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti
4056d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti    private void notifyElementAdded(int index, Node nodeAddedOrRemoved) {
40617c60f99a730acb68276303e7c6fcdf0a376258cFederico Tomassetti        this.observers.forEach(o -> o.listChange(this, AstObserver.ListChangeType.ADDITION, index, nodeAddedOrRemoved));
4076d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti    }
4086d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti
4096d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti    private void notifyElementRemoved(int index, Node nodeAddedOrRemoved) {
41017c60f99a730acb68276303e7c6fcdf0a376258cFederico Tomassetti        this.observers.forEach(o -> o.listChange(this, AstObserver.ListChangeType.REMOVAL, index, nodeAddedOrRemoved));
4116d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti    }
4126d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti
4130d8f8e5cc0e48d0cc27cf070155ab318fe160a00Federico Tomassetti    private void notifyElementReplaced(int index, Node nodeAddedOrRemoved) {
4140d8f8e5cc0e48d0cc27cf070155ab318fe160a00Federico Tomassetti        this.observers.forEach(o -> o.listReplacement(this, index, this.get(index), nodeAddedOrRemoved));
4150d8f8e5cc0e48d0cc27cf070155ab318fe160a00Federico Tomassetti    }
4160d8f8e5cc0e48d0cc27cf070155ab318fe160a00Federico Tomassetti
4176d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti    @Override
418263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti    public void unregister(AstObserver observer) {
4196d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti        this.observers.remove(observer);
4206d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti    }
4216d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti
4226d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti    @Override
423263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti    public void register(AstObserver observer) {
4246d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti        this.observers.add(observer);
425263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti    }
426263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti
427263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti    @Override
428263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti    public boolean isRegistered(AstObserver observer) {
429263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti        return this.observers.contains(observer);
430f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
431f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
432f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen    /**
433f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen     * Replaces the first node that is equal to "old" with "replacement".
434f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen     *
435f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen     * @return true if a replacement has happened.
436f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen     */
437f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen    public boolean replace(N old, N replacement) {
438f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen        int i = indexOf(old);
439f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen        if (i == -1) {
440f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen            return false;
441f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen        }
442f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen        set(i, replacement);
443f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen        return true;
444f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen    }
44526ddbc38a65a4a8350afcb569923d7d66b7e6ee2Danny van Bruggen
44626ddbc38a65a4a8350afcb569923d7d66b7e6ee2Danny van Bruggen    /**
44726ddbc38a65a4a8350afcb569923d7d66b7e6ee2Danny van Bruggen     * @return the opposite of isEmpty()
44826ddbc38a65a4a8350afcb569923d7d66b7e6ee2Danny van Bruggen     */
44926ddbc38a65a4a8350afcb569923d7d66b7e6ee2Danny van Bruggen    public boolean isNonEmpty() {
45026ddbc38a65a4a8350afcb569923d7d66b7e6ee2Danny van Bruggen        return !isEmpty();
45126ddbc38a65a4a8350afcb569923d7d66b7e6ee2Danny van Bruggen    }
4527cd83c2e73deb47d79e71cc6afc3eb4b613302d1Danny van Bruggen
4537cd83c2e73deb47d79e71cc6afc3eb4b613302d1Danny van Bruggen    public void ifNonEmpty(Consumer<? super NodeList<N>> consumer) {
4547cd83c2e73deb47d79e71cc6afc3eb4b613302d1Danny van Bruggen        if (isNonEmpty())
4557cd83c2e73deb47d79e71cc6afc3eb4b613302d1Danny van Bruggen            consumer.accept(this);
4567cd83c2e73deb47d79e71cc6afc3eb4b613302d1Danny van Bruggen    }
457c9f2a4fe27453e09a268730cd0ab76a42016475fDanny van Bruggen
458c9f2a4fe27453e09a268730cd0ab76a42016475fDanny van Bruggen    public static <T extends Node> Collector<T, NodeList<T>, NodeList<T>> toNodeList() {
459c9f2a4fe27453e09a268730cd0ab76a42016475fDanny van Bruggen        return Collector.of(NodeList::new, NodeList::add, (left, right) -> {
460c9f2a4fe27453e09a268730cd0ab76a42016475fDanny van Bruggen            left.addAll(right);
461c9f2a4fe27453e09a268730cd0ab76a42016475fDanny van Bruggen            return left;
462c9f2a4fe27453e09a268730cd0ab76a42016475fDanny van Bruggen        });
463c9f2a4fe27453e09a268730cd0ab76a42016475fDanny van Bruggen    }
464515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen}
465