/*
 * 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.planner.iterative;

import com.facebook.presto.sql.planner.plan.PlanNode;

import java.util.function.Function;
import java.util.stream.Stream;

import static com.google.common.base.Verify.verify;
import static com.google.common.collect.MoreCollectors.toOptional;

public interface Lookup
{
    /**
     * Resolves a node by materializing GroupReference nodes
     * representing symbolic references to other nodes. This method
     * is deprecated since is assumes group contains only one node.
     * <p>
     * If the node is not a GroupReference, it returns the
     * argument as is.
     */
    @Deprecated
    default PlanNode resolve(PlanNode node)
    {
        return resolveGroup(node).collect(toOptional()).get();
    }

    /**
     * Resolves nodes by materializing GroupReference nodes
     * representing symbolic references to other nodes.
     * <p>
     * If the node is not a GroupReference, it returns the
     * singleton of the argument node.
     */
    Stream<PlanNode> resolveGroup(PlanNode node);

    /**
     * A Lookup implementation that does not perform lookup. It satisfies contract
     * by rejecting {@link GroupReference}-s.
     */
    static Lookup noLookup()
    {
        return node -> {
            verify(!(node instanceof GroupReference), "Unexpected GroupReference");
            return Stream.of(node);
        };
    }

    static Lookup from(Function<GroupReference, Stream<PlanNode>> resolver)
    {
        return node -> {
            if (node instanceof GroupReference) {
                return resolver.apply((GroupReference) node);
            }

            return Stream.of(node);
        };
    }
}

@@ -772,21 +772,35 @@
 ase.
-Verify.verify
+Preconditions.checkArgument
 ;%0Aim
@@ -1255,32 +1255,82 @@
 ode node)%0A    %7B%0A
+        if (node instanceof GroupReference) %7B%0A    
         return r
@@ -1376,16 +1376,47 @@
 .get();%0A
+        %7D%0A        return node;%0A
     %7D%0A%0A 
@@ -1560,98 +1560,76 @@
   * 
-If the node is not a GroupReference, it returns the%0A     * singleton of the argument node.
+@throws IllegalArgumentException if the node is not a GroupReference
 %0A   
@@ -1905,113 +1905,48 @@
     
-verify(!(node instanceof GroupReference), %22Unexpected GroupReference%22);%0A            return Stream.of(node
+throw new UnsupportedOperationException(
 );%0A 
@@ -2073,35 +2073,45 @@
 %3E %7B%0A            
-if 
+checkArgument
 (node instanceof
@@ -2129,118 +2129,132 @@
 ence
-) %7B%0A                return resolver.apply((GroupReference) node);%0A            %7D%0A%0A            return Stream.of(
+, %22Node '%25s' is not a GroupReference%22, node.getClass().getSimpleName());%0A            return resolver.apply((GroupReference) 
 node

Make resolveGroup accept only GroupReference