NodeList.java revision 33115b3c857a87e398e9eaffd3d29c47804a0a53
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;
353b31ef89fd3f2963c2bf53655f42ed459376e879Danny 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<>();
99c3f372b0c7c8ca4bed1261e7f1d3f17ed01b4889Danny van Bruggen        nodeList.addAll(nodes);
100515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return nodeList;
101515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
102515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
103515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public static <X extends Node> NodeList<X> nodeList(NodeList<X> nodes) {
104515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        final NodeList<X> nodeList = new NodeList<>();
1059dfe6cb2a1115f749a6a9adca05297d6b24eb046Danny van Bruggen        nodeList.addAll(nodes);
106515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return nodeList;
107515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
108515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
109515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public boolean contains(N node) {
110515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return innerList.contains(node);
111515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
112515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
113f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
114515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public int size() {
115515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return innerList.size();
116515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
117515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
118f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
119515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public N get(int i) {
120515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return innerList.get(i);
121515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
122515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
123515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    @Override
124515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public Iterator<N> iterator() {
125515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        // TODO take care of "Iterator.remove"
126515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return innerList.iterator();
127515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
128515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
129f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
130f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public N set(int index, N element) {
1310d8f8e5cc0e48d0cc27cf070155ab318fe160a00Federico Tomassetti        notifyElementReplaced(index, element);
132515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        setAsParentNodeOf(element);
133f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.set(index, element);
134515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
135515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
136f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
137f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public N remove(int index) {
138263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti        notifyElementRemoved(index, innerList.get(index));
139f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        N remove = innerList.remove(index);
140f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        if (remove != null)
141f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien            remove.setParentNode(null);
142f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return remove;
143515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
144515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
145f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
146515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public boolean isEmpty() {
147515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        return innerList.isEmpty();
148515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
149515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
150f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
151515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public void sort(Comparator<? super N> comparator) {
152c3f372b0c7c8ca4bed1261e7f1d3f17ed01b4889Danny van Bruggen        innerList.sort(comparator);
153515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
154515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
155515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    public void addAll(NodeList<N> otherList) {
156515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        for (N node : otherList) {
157515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen            add(node);
158515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        }
159515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
160515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen
161f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
162f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public void add(int index, N node) {
1636d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti        notifyElementAdded(index, node);
164515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        own(node);
165515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen        innerList.add(index, node);
166515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen    }
167db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen
16833115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen    /**
16933115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen     * Inserts the node before all other nodes.
17033115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen     */
17133115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen    public NodeList<N> addToTop(N node) {
17233115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen        add(0, node);
17333115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen        return this;
17433115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen    }
17533115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen
17633115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen    /**
17733115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen     * Inserts the node after all other nodes. (This is simply an alias for add.)
17833115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen     */
17933115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen    public NodeList<N> addToBottom(N node) {
18033115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen        add(node);
18133115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen        return this;
18233115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen    }
18333115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen
18433115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen    /**
18533115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen     * Inserts the node after afterThisNode.
18633115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen     *
18733115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen     * @throws IllegalArgumentException when afterThisNode is not in this list.
18833115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen     */
18933115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen    public NodeList<N> addAfter(N node, N afterThisNode) {
19033115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen        int i = indexOf(afterThisNode);
19133115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen        if (i == -1) {
19233115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen            throw new IllegalArgumentException("Can't find node to insert after.");
19333115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen        }
19433115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen        add(i + 1, node);
19533115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen        return this;
19633115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen    }
19733115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen
19833115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen    /**
19933115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen     * Inserts the node before beforeThisNode.
20033115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen     *
20133115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen     * @throws IllegalArgumentException when beforeThisNode is not in this list.
20233115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen     */
20333115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen    public NodeList<N> addBefore(N node, N beforeThisNode) {
20433115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen        int i = indexOf(beforeThisNode);
20533115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen        if (i == -1) {
20633115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen            throw new IllegalArgumentException("Can't find node to insert before.");
20733115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen        }
20833115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen        add(i, node);
20933115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen        return this;
21033115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen    }
21133115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen
21233115b3c857a87e398e9eaffd3d29c47804a0a53Danny van Bruggen
213db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    @Override
214008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien    public Optional<Node> getParentNode() {
215008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien        return Optional.ofNullable(parentNode);
216db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    }
217db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen
218008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien    /**
219008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien     * Sets the parentNode
2204296abb695b767f7471dd255d0679516183b062aDanny van Bruggen     *
221008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien     * @param parentNode the parentNode
222008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien     * @return this, the NodeList
223008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien     */
224db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    @Override
225db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    public NodeList<N> setParentNode(Node parentNode) {
226db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen        this.parentNode = parentNode;
227db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen        setAsParentNodeOf(innerList);
228db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen        return this;
229db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    }
230db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen
231db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    @Override
232db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    public Node getParentNodeForChildren() {
233db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen        return parentNode;
234db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    }
235db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen
236008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien    @Override
237db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    public <R, A> R accept(final GenericVisitor<R, A> v, final A arg) {
238db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen        return v.visit(this, arg);
239db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    }
240db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen
241008b82d149685d6702a060fbecafc8fc2e10b459Cruz Maximilien    @Override
242db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    public <A> void accept(final VoidVisitor<A> v, final A arg) {
243db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen        v.visit(this, arg);
244db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen    }
245db52836b6a33c9ff130d8ea554f78b21ebe9b586Danny van Bruggen
246f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
247f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.lang.Iterable#forEach(java.util.function.Consumer)
248f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
249f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
250f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public void forEach(Consumer<? super N> action) {
251f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        innerList.forEach(action);
252f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
253f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
254f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
255f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#contains(java.lang.Object)
256f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
257f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
258f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean contains(Object o) {
259f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.contains(o);
260f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
261f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
262f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
263f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#toArray()
264f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
265f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
266f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public Object[] toArray() {
267f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.toArray();
268f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
269f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
270f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
271f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#toArray(java.lang.Object[])
272f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
273f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
274f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public <T> T[] toArray(T[] a) {
275f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.toArray(a);
276f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
277f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
278f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
279f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#remove(java.lang.Object)
280f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
281f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
282f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean remove(Object o) {
283ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti        if (o instanceof Node) {
2844296abb695b767f7471dd255d0679516183b062aDanny van Bruggen            return remove((Node) o);
285ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti        } else {
286ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti            return false;
287ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti        }
288f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
289f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
290f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
291f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#containsAll(java.util.Collection)
292f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
293f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
294f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean containsAll(Collection<?> c) {
295f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.containsAll(c);
296f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
297f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
298f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
299f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#addAll(java.util.Collection)
300f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
301f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
302f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean addAll(Collection<? extends N> c) {
3039dfe6cb2a1115f749a6a9adca05297d6b24eb046Danny van Bruggen        c.forEach(this::add);
3043e8757e510df2bbdb1ef8bedf92538b17a5e36c6Federico Tomassetti        return !c.isEmpty();
305f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
306f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
307f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
308f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#addAll(int, java.util.Collection)
309f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
310f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
311f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean addAll(int index, Collection<? extends N> c) {
312150ecb8efecf1bbe22f23e6e2869ef4f59fe3523Federico Tomassetti        for (N e : c) {
313150ecb8efecf1bbe22f23e6e2869ef4f59fe3523Federico Tomassetti            add(index++, e);
3143e8757e510df2bbdb1ef8bedf92538b17a5e36c6Federico Tomassetti        }
315150ecb8efecf1bbe22f23e6e2869ef4f59fe3523Federico Tomassetti        return !c.isEmpty();
316f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
317f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
318f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
319f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#removeAll(java.util.Collection)
320f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
321f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
322f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean removeAll(Collection<?> c) {
323ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti        boolean changed = false;
324ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti        for (Object e : c) {
325ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti            changed = remove(e) || changed;
326f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        }
327ab4f6a5743de6a9fbb09da9d6a00678bbc2cd3d1Federico Tomassetti        return changed;
328f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
329f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
330f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
331f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#retainAll(java.util.Collection)
332f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
333f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
334f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean retainAll(Collection<?> c) {
335cbaf4495c17eb3383e8d2b40db9a4fe92221d118Federico Tomassetti        boolean changed = false;
336cbaf4495c17eb3383e8d2b40db9a4fe92221d118Federico Tomassetti        for (Object e : this.stream().filter(it -> !c.contains(it)).toArray()) {
337cbaf4495c17eb3383e8d2b40db9a4fe92221d118Federico Tomassetti            if (!c.contains(e)) {
338cbaf4495c17eb3383e8d2b40db9a4fe92221d118Federico Tomassetti                changed = remove(e) || changed;
339cbaf4495c17eb3383e8d2b40db9a4fe92221d118Federico Tomassetti            }
340cbaf4495c17eb3383e8d2b40db9a4fe92221d118Federico Tomassetti        }
341cbaf4495c17eb3383e8d2b40db9a4fe92221d118Federico Tomassetti        return changed;
342f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
343f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
344f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
345f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#replaceAll(java.util.function.UnaryOperator)
346f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
347f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
348f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public void replaceAll(UnaryOperator<N> operator) {
3494296abb695b767f7471dd255d0679516183b062aDanny van Bruggen        for (int i = 0; i < this.size(); i++) {
35034ee4b944cf1534361d6d9ca7ba3f9876df5ddb4Federico Tomassetti            set(i, operator.apply(this.get(i)));
35134ee4b944cf1534361d6d9ca7ba3f9876df5ddb4Federico Tomassetti        }
352f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
353f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
354f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
355f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.Collection#removeIf(java.util.function.Predicate)
356f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
357f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
358f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean removeIf(Predicate<? super N> filter) {
35955d475bac6deff387e608ac7f200227a23488ea7Federico Tomassetti        boolean changed = false;
3604296abb695b767f7471dd255d0679516183b062aDanny van Bruggen        for (Object e : this.stream().filter(filter).toArray()) {
36155d475bac6deff387e608ac7f200227a23488ea7Federico Tomassetti            changed = remove(e) || changed;
36255d475bac6deff387e608ac7f200227a23488ea7Federico Tomassetti        }
36355d475bac6deff387e608ac7f200227a23488ea7Federico Tomassetti        return changed;
364f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
365f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
366f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
367f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#clear()
368f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
369f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
370f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public void clear() {
3714a25ff22c5db52fe1f21f8939e4a47a73ff2f61bFederico Tomassetti        while (!isEmpty()) {
3724a25ff22c5db52fe1f21f8939e4a47a73ff2f61bFederico Tomassetti            remove(0);
3734a25ff22c5db52fe1f21f8939e4a47a73ff2f61bFederico Tomassetti        }
374f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
375f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
376f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
377f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#equals(java.lang.Object)
378f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
379f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
380f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public boolean equals(Object o) {
381f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.equals(o);
382f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
383f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
384f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
385f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#hashCode()
386f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
387f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
388f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public int hashCode() {
389f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.hashCode();
390f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
391f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
392f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
393f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#indexOf(java.lang.Object)
394f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
395f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
396f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public int indexOf(Object o) {
397f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.indexOf(o);
398f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
399f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
400f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
401f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#lastIndexOf(java.lang.Object)
402f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
403f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
404f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public int lastIndexOf(Object o) {
405f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.lastIndexOf(o);
406f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
407f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
408f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
409f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#listIterator()
410f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
411f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
412f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public ListIterator<N> listIterator() {
413f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.listIterator();
414f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
415f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
416f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
417f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#listIterator(int)
418f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
419f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
420f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public ListIterator<N> listIterator(int index) {
421f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.listIterator(index);
422f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
423f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
424f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
425f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.Collection#parallelStream()
426f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
427f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
428f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public Stream<N> parallelStream() {
429f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.parallelStream();
430f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
431f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
432f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
433f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#subList(int, int)
434f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
435f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
436f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public List<N> subList(int fromIndex, int toIndex) {
437f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.subList(fromIndex, toIndex);
438f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
439f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
440f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    /**
441f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     * @see java.util.List#spliterator()
442f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien     */
443f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    @Override
444f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    public Spliterator<N> spliterator() {
445f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien        return innerList.spliterator();
446c77e046d2a645bf42f9450bd293e0ba69300a309Federico Tomassetti    }
447263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti
4486d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti    private void notifyElementAdded(int index, Node nodeAddedOrRemoved) {
44917c60f99a730acb68276303e7c6fcdf0a376258cFederico Tomassetti        this.observers.forEach(o -> o.listChange(this, AstObserver.ListChangeType.ADDITION, index, nodeAddedOrRemoved));
4506d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti    }
4516d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti
4526d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti    private void notifyElementRemoved(int index, Node nodeAddedOrRemoved) {
45317c60f99a730acb68276303e7c6fcdf0a376258cFederico Tomassetti        this.observers.forEach(o -> o.listChange(this, AstObserver.ListChangeType.REMOVAL, index, nodeAddedOrRemoved));
4546d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti    }
4556d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti
4560d8f8e5cc0e48d0cc27cf070155ab318fe160a00Federico Tomassetti    private void notifyElementReplaced(int index, Node nodeAddedOrRemoved) {
4570d8f8e5cc0e48d0cc27cf070155ab318fe160a00Federico Tomassetti        this.observers.forEach(o -> o.listReplacement(this, index, this.get(index), nodeAddedOrRemoved));
4580d8f8e5cc0e48d0cc27cf070155ab318fe160a00Federico Tomassetti    }
4590d8f8e5cc0e48d0cc27cf070155ab318fe160a00Federico Tomassetti
4606d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti    @Override
461263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti    public void unregister(AstObserver observer) {
4626d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti        this.observers.remove(observer);
4636d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti    }
4646d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti
4656d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti    @Override
466263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti    public void register(AstObserver observer) {
4676d41743d2b5dcd565b401a27f62526ec7a7b54d4Federico Tomassetti        this.observers.add(observer);
468263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti    }
469263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti
470263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti    @Override
471263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti    public boolean isRegistered(AstObserver observer) {
472263cf50ac27714b8e120565f45a1fac661df18b5Federico Tomassetti        return this.observers.contains(observer);
473f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien    }
474f1cce0ac20c5af34085d891bee6d9ff9012d36c7Cruz Maximilien
475f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen    /**
476f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen     * Replaces the first node that is equal to "old" with "replacement".
477f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen     *
478f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen     * @return true if a replacement has happened.
479f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen     */
480f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen    public boolean replace(N old, N replacement) {
481f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen        int i = indexOf(old);
482f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen        if (i == -1) {
483f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen            return false;
484f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen        }
485f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen        set(i, replacement);
486f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen        return true;
487f64e8f570cb375692d112e03d095040e88d109abDanny van Bruggen    }
48826ddbc38a65a4a8350afcb569923d7d66b7e6ee2Danny van Bruggen
48926ddbc38a65a4a8350afcb569923d7d66b7e6ee2Danny van Bruggen    /**
49026ddbc38a65a4a8350afcb569923d7d66b7e6ee2Danny van Bruggen     * @return the opposite of isEmpty()
49126ddbc38a65a4a8350afcb569923d7d66b7e6ee2Danny van Bruggen     */
49226ddbc38a65a4a8350afcb569923d7d66b7e6ee2Danny van Bruggen    public boolean isNonEmpty() {
49326ddbc38a65a4a8350afcb569923d7d66b7e6ee2Danny van Bruggen        return !isEmpty();
49426ddbc38a65a4a8350afcb569923d7d66b7e6ee2Danny van Bruggen    }
4957cd83c2e73deb47d79e71cc6afc3eb4b613302d1Danny van Bruggen
4967cd83c2e73deb47d79e71cc6afc3eb4b613302d1Danny van Bruggen    public void ifNonEmpty(Consumer<? super NodeList<N>> consumer) {
4977cd83c2e73deb47d79e71cc6afc3eb4b613302d1Danny van Bruggen        if (isNonEmpty())
4987cd83c2e73deb47d79e71cc6afc3eb4b613302d1Danny van Bruggen            consumer.accept(this);
4997cd83c2e73deb47d79e71cc6afc3eb4b613302d1Danny van Bruggen    }
500c9f2a4fe27453e09a268730cd0ab76a42016475fDanny van Bruggen
501c9f2a4fe27453e09a268730cd0ab76a42016475fDanny van Bruggen    public static <T extends Node> Collector<T, NodeList<T>, NodeList<T>> toNodeList() {
502c9f2a4fe27453e09a268730cd0ab76a42016475fDanny van Bruggen        return Collector.of(NodeList::new, NodeList::add, (left, right) -> {
503c9f2a4fe27453e09a268730cd0ab76a42016475fDanny van Bruggen            left.addAll(right);
504c9f2a4fe27453e09a268730cd0ab76a42016475fDanny van Bruggen            return left;
505c9f2a4fe27453e09a268730cd0ab76a42016475fDanny van Bruggen        });
506c9f2a4fe27453e09a268730cd0ab76a42016475fDanny van Bruggen    }
5074ea99f582d159e166eef3c6cc48a33bc85f2b22fDanny van Bruggen
5084ea99f582d159e166eef3c6cc48a33bc85f2b22fDanny van Bruggen    private void setAsParentNodeOf(List<? extends Node> childNodes) {
5094ea99f582d159e166eef3c6cc48a33bc85f2b22fDanny van Bruggen        if (childNodes != null) {
5104ea99f582d159e166eef3c6cc48a33bc85f2b22fDanny van Bruggen            for (HasParentNode current : childNodes) {
5114ea99f582d159e166eef3c6cc48a33bc85f2b22fDanny van Bruggen                current.setParentNode(getParentNodeForChildren());
5124ea99f582d159e166eef3c6cc48a33bc85f2b22fDanny van Bruggen            }
5134ea99f582d159e166eef3c6cc48a33bc85f2b22fDanny van Bruggen        }
5144ea99f582d159e166eef3c6cc48a33bc85f2b22fDanny van Bruggen    }
5154ea99f582d159e166eef3c6cc48a33bc85f2b22fDanny van Bruggen
5164ea99f582d159e166eef3c6cc48a33bc85f2b22fDanny van Bruggen    private void setAsParentNodeOf(Node childNode) {
5174ea99f582d159e166eef3c6cc48a33bc85f2b22fDanny van Bruggen        if (childNode != null) {
5184ea99f582d159e166eef3c6cc48a33bc85f2b22fDanny van Bruggen            childNode.setParentNode(getParentNodeForChildren());
5194ea99f582d159e166eef3c6cc48a33bc85f2b22fDanny van Bruggen        }
5204ea99f582d159e166eef3c6cc48a33bc85f2b22fDanny van Bruggen    }
5213b31ef89fd3f2963c2bf53655f42ed459376e879Danny van Bruggen
5223b31ef89fd3f2963c2bf53655f42ed459376e879Danny van Bruggen    @Override
5233b31ef89fd3f2963c2bf53655f42ed459376e879Danny van Bruggen    public String toString() {
524716c3b490fe90c09b9ca66d66569eb58f52e8b48Danny van Bruggen        return innerList.stream().map(Node::toString).collect(Collectors.joining(", ", "[", "]"));
5253b31ef89fd3f2963c2bf53655f42ed459376e879Danny van Bruggen    }
526515a9392928c14a60dc9dfa42a98198a4d877534Danny van Bruggen}
527