/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.facebook.presto.sql.util;

import com.facebook.presto.sql.tree.Node;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Iterator;
import java.util.Spliterators;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import static java.util.Objects.requireNonNull;

public class AstUtils
{
    public static boolean nodeContains(Node node, Node subNode)
    {
        requireNonNull(node, "node is null");
        requireNonNull(subNode, "subNode is null");

        return preOrder(node)
                .anyMatch(childNode -> childNode == subNode);
    }

    public static Stream<Node> preOrder(Node node)
    {
        return StreamSupport.stream(Spliterators.spliteratorUnknownSize(new PreOrderIterator(node), 0), false);
    }

    private static final class PreOrderIterator
            implements Iterator<Node>
    {
        private final Deque<Node> remaining = new ArrayDeque<>();

        public PreOrderIterator(Node node)
        {
            remaining.push(node);
        }

        @Override
        public boolean hasNext()
        {
            return remaining.size() > 0;
        }

        @Override
        public Node next()
        {
            Node node = remaining.pop();
            node.getChildren().forEach(remaining::push);
            return node;
        }
    }

    private AstUtils() {}
}

@@ -640,119 +640,56 @@
 de;%0A
-%0A
 import 
-java.util.ArrayDeque;%0Aimport java.util.Deque;%0Aimport java.util.Iterator;%0Aimport java.util.Spliterators;
+com.google.common.collect.TreeTraverser;%0A
 %0Aimp
@@ -721,47 +721,80 @@
 am;%0A
+%0A
 import 
-java.util.stream.StreamSupport;%0A
+static com.google.common.collect.Iterables.unmodifiableIterable;
 %0Aimp
@@ -1207,669 +1207,178 @@
 urn 
-StreamSupport.stream(Spliterators.spliteratorUnknownSize(new PreOrderIterator(node), 0), false);%0A    %7D%0A%0A    private static final class PreOrderIterator%0A            implements Iterator%3CNode%3E%0A    %7B%0A        private final Deque%3CNode%3E remaining = new ArrayDeque%3C%3E();%0A%0A        public PreOrderIterator(Node node)%0A        %7B%0A            remaining.push(node);%0A        %7D%0A%0A        @Override%0A        public boolean hasNext()%0A        %7B%0A            return remaining.size() %3E 0;%0A        %7D%0A%0A        @Override%0A        public Node next()%0A        %7B%0A            Node node = remaining.pop();%0A            node.getChildren().forEach(remaining::push);%0A            return node;%0A        %7D
+TreeTraverser.using((Node n) -%3E unmodifiableIterable(n.getChildren()))%0A                .preOrderTraversal(requireNonNull(node, %22node is null%22))%0A                .stream();
 %0A   

Simplify AstUtils.preOrder