/*-
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.sling.query;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import org.apache.sling.query.api.SearchStrategy;
import org.apache.sling.query.api.internal.IteratorToIteratorFunction;
import org.apache.sling.query.api.internal.Option;
import org.apache.sling.query.api.internal.TreeProvider;
import org.apache.sling.query.function.AddFunction;
import org.apache.sling.query.function.ChildrenFunction;
import org.apache.sling.query.function.ClosestFunction;
import org.apache.sling.query.function.CompositeFunction;
import org.apache.sling.query.function.DescendantFunction;
import org.apache.sling.query.function.FilterFunction;
import org.apache.sling.query.function.FindFunction;
import org.apache.sling.query.function.HasFunction;
import org.apache.sling.query.function.IdentityFunction;
import org.apache.sling.query.function.LastFunction;
import org.apache.sling.query.function.NextFunction;
import org.apache.sling.query.function.NotFunction;
import org.apache.sling.query.function.ParentFunction;
import org.apache.sling.query.function.ParentsFunction;
import org.apache.sling.query.function.PrevFunction;
import org.apache.sling.query.function.SiblingsFunction;
import org.apache.sling.query.function.SliceFunction;
import org.apache.sling.query.function.UniqueFunction;
import org.apache.sling.query.iterator.EmptyElementFilter;
import org.apache.sling.query.iterator.OptionDecoratingIterator;
import org.apache.sling.query.iterator.OptionStrippingIterator;
import org.apache.sling.query.predicate.IterableContainsPredicate;
import org.apache.sling.query.predicate.RejectingPredicate;
import org.apache.sling.query.selector.SelectorFunction;
import org.apache.sling.query.util.LazyList;
import org.osgi.annotation.versioning.ProviderType;

@ProviderType
public abstract class AbstractQuery<T, Q extends AbstractQuery<T, Q>> implements Iterable<T> {

	protected final List<Function<?, ?>> functions = new ArrayList<>();

	private final List<T> initialCollection;

	private final SearchStrategy searchStrategy;

	private final TreeProvider<T> provider;

	AbstractQuery(TreeProvider<T> provider, T[] initialCollection, SearchStrategy strategy) {
		this.provider = provider;
		this.initialCollection = new ArrayList<>(Arrays.asList(initialCollection));
		this.searchStrategy = strategy;
	}

	protected AbstractQuery(AbstractQuery<T, Q> original, SearchStrategy searchStrategy) {
		this.functions.addAll(original.functions);
		this.initialCollection = new ArrayList<>(original.initialCollection);
		this.searchStrategy = searchStrategy;
		this.provider = original.provider;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Iterator<T> iterator() {
		IteratorToIteratorFunction<T> f = new CompositeFunction<>(functions);
		Iterator<Option<T>> iterator = f.apply(new OptionDecoratingIterator<>(initialCollection.iterator()));
		iterator = new EmptyElementFilter<>(iterator);
		return new OptionStrippingIterator<>(iterator);
	}

	public Stream<T> stream() {
		return StreamSupport.stream(this.spliterator(), false);
	}

	/**
	 * Include resources to the collection.
	 * 
	 * @param resources Resources to include
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q add(T... resources) {
		return function(new AddFunction<>(Arrays.asList(resources)));
	}

	/**
	 * Include resources to the collection.
	 * 
	 * @param iterable Resources to include
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q add(Iterable<T> iterable) {
		return function(new AddFunction<>(iterable));
	}

	/**
	 * Transform SlingQuery collection into a lazy list.
	 * 
	 * @return List containing all elements from the collection.
	 */
	public List<T> asList() {
		return new LazyList<>(iterator());
	}

	/**
	 * Get list of the children for each Resource in the collection.
	 * 
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q children() {
		return function(new ChildrenFunction<>(provider));
	}

	/**
	 * Get list of the children for each Resource in the collection.
	 * 
	 * @param filter Children filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q children(String filter) {
		return function(new ChildrenFunction<>(provider), filter);
	}

	/**
	 * Get list of the children for each Resource in the collection.
	 * 
	 * @param filter Children filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q children(Predicate<T> filter) {
		return function(new ChildrenFunction<>(provider), filter);
	}

	/**
	 * Get list of the children for each Resource in the collection.
	 * 
	 * @param filter Children filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q children(Iterable<T> filter) {
		return function(new ChildrenFunction<>(provider), filter);
	}

	/**
	 * For each Resource in the collection, return the first element matching the selector testing the
	 * Resource itself and traversing up its ancestors.
	 * 
	 * @param selector Ancestor filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q closest(String selector) {
		return closest(parse(selector));
	}

	/**
	 * For each Resource in the collection, return the first element matching the selector testing the
	 * Resource itself and traversing up its ancestors.
	 * 
	 * @param iterable Ancestor filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q closest(Iterable<T> iterable) {
		return closest(new IterableContainsPredicate<>(iterable, provider));
	}

	/**
	 * For each Resource in the collection, return the first element matching the selector testing the
	 * Resource itself and traversing up its ancestors.
	 * 
	 * @param predicate Ancestor filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q closest(Predicate<T> predicate) {
		return function(new ClosestFunction<>(predicate, provider));
	}

	/**
	 * Reduce Resource collection to the one Resource at the given 0-based index.
	 * 
	 * @param index 0-based index
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q eq(int index) {
		return slice(index, index);
	}

	/**
	 * Filter Resource collection using given selector.
	 * 
	 * @param selector Selector
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q filter(String selector) {
		return function(new IdentityFunction<T>(), selector);
	}

	/**
	 * Filter Resource collection using given predicate object.
	 * 
	 * @param predicate Collection filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q filter(Predicate<T> predicate) {
		return function(new FilterFunction<>(predicate));
	}

	/**
	 * Filter Resource collection using given iterable.
	 * 
	 * @param iterable Collection filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q filter(Iterable<T> iterable) {
		return function(new FilterFunction<>(new IterableContainsPredicate<>(iterable, provider)));
	}

	/**
	 * For each Resource in collection use depth-first search to return all its descendants. Please notice
	 * that invoking this method on a Resource being a root of a large subtree may and will cause performance
	 * problems.
	 * 
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q find() {
		return function(new FindFunction<>(searchStrategy, provider, ""));
	}

	/**
	 * For each Resource in collection use breadth-first search to return all its descendants. Please notice
	 * that invoking this method on a Resource being a root of a large subtree may and will cause performance
	 * problems.
	 * 
	 * @param selector descendants filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q find(String selector) {
		return function(new FindFunction<>(searchStrategy, provider, selector), selector);
	}

	/**
	 * For each Resource in collection use breadth-first search to return all its descendants. Please notice
	 * that invoking this method on a Resource being a root of a large subtree may and will cause performance
	 * problems.
	 * 
	 * @param predicate descendants filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q find(Predicate<T> predicate) {
		return function(new FindFunction<>(searchStrategy, provider, ""), predicate);
	}

	/**
	 * For each Resource in collection use breadth-first search to return all its descendants. Please notice
	 * that invoking this method on a Resource being a root of a large subtree may and will cause performance
	 * problems.
	 * 
	 * @param iterable descendants filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q find(Iterable<T> iterable) {
		return function(new DescendantFunction<>(new LazyList<>(iterable.iterator()), provider));
	}

	/**
	 * Filter Resource collection to the first element. Equivalent to {@code eq(0)} or {@code slice(0, 0)}.
	 * 
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q first() {
		return eq(0);
	}

	/**
	 * Pick such Resources from the collection that have descendant matching the selector.
	 * 
	 * @param selector Descendant selector
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q has(String selector) {
		return function(new HasFunction<>(selector, searchStrategy, provider));
	}

	/**
	 * Pick such Resources from the collection that have descendant matching the selector.
	 * 
	 * @param predicate Descendant selector
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q has(Predicate<T> predicate) {
		return function(new HasFunction<>(predicate, searchStrategy, provider));
	}

	/**
	 * Pick such Resources from the collection that have descendant matching the selector.
	 * 
	 * @param iterable Descendant selector
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q has(Iterable<T> iterable) {
		return function(new HasFunction<>(iterable, provider));
	}

	/**
	 * Filter Resource collection to the last element.
	 * 
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q last() {
		return function(new LastFunction<T>());
	}

	/**
	 * Return the next sibling for each Resource in the collection.
	 * 
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q next() {
		return function(new NextFunction<>(provider));
	}

	/**
	 * Return the next sibling for each Resource in the collection and filter it by a selector. If the next
	 * sibling doesn't match it, empty collection will be returned.
	 * 
	 * @param selector Next sibling filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q next(String selector) {
		return function(new NextFunction<>(provider), selector);
	}

	/**
	 * Return the next sibling for each Resource in the collection and filter it by a selector. If the next
	 * sibling doesn't match it, empty collection will be returned.
	 * 
	 * @param predicate Next sibling filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q next(Predicate<T> predicate) {
		return function(new NextFunction<>(provider), predicate);
	}

	/**
	 * Return the next sibling for each Resource in the collection and filter it by a selector. If the next
	 * sibling doesn't match it, empty collection will be returned.
	 * 
	 * @param iterable Next sibling filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q next(Iterable<T> iterable) {
		return function(new NextFunction<>(provider), iterable);
	}

	/**
	 * Return all following siblings for each Resource in the collection.
	 * 
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q nextAll() {
		return function(new NextFunction<>(new RejectingPredicate<>(), provider));
	}

	/**
	 * Return all following siblings for each Resource in the collection, filtering them by a selector.
	 * 
	 * @param selector Following siblings filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q nextAll(String selector) {
		return function(new NextFunction<>(new RejectingPredicate<>(), provider), selector);
	}

	/**
	 * Return all following siblings for each Resource in the collection, filtering them by a selector.
	 * 
	 * @param predicate Following siblings filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q nextAll(Predicate<T> predicate) {
		return function(new NextFunction<>(new RejectingPredicate<>(), provider), predicate);
	}

	/**
	 * Return all following siblings for each Resource in the collection, filtering them by a selector.
	 * 
	 * @param iterable Following siblings filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q nextAll(Iterable<T> iterable) {
		return function(new NextFunction<>(new RejectingPredicate<>(), provider), iterable);
	}

	/**
	 * Return all following siblings for each Resource in the collection up to, but not including, Resource
	 * matched by a selector.
	 * 
	 * @param until Selector marking when the operation should stop
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q nextUntil(String until) {
		return function(new NextFunction<>(parse(until), provider));
	}

	/**
	 * Return all following siblings for each Resource in the collection up to, but not including, Resource
	 * matched by a selector.
	 * 
	 * @param predicate Selector marking when the operation should stop
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q nextUntil(Predicate<T> predicate) {
		return function(new NextFunction<>(predicate, provider));
	}

	/**
	 * Return all following siblings for each Resource in the collection up to, but not including, Resource
	 * matched by a selector.
	 * 
	 * @param iterable Selector marking when the operation should stop
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q nextUntil(Iterable<T> iterable) {
		return nextUntil(new IterableContainsPredicate<>(iterable, provider));
	}

	/**
	 * Remove elements from the collection.
	 * 
	 * @param selector Selector used to remove Resources
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q not(String selector) {
		return function(new NotFunction<>(parse(selector)));
	}

	/**
	 * Remove elements from the collection.
	 * 
	 * @param predicate Selector used to remove Resources
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q not(Predicate<T> predicate) {
		return function(new FilterFunction<>(new RejectingPredicate<>(predicate)));
	}

	/**
	 * Remove elements from the collection.
	 * 
	 * @param iterable Selector used to remove Resources
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q not(Iterable<T> iterable) {
		return not(new IterableContainsPredicate<>(iterable, provider));
	}

	/**
	 * Replace each element in the collection with its parent.
	 * 
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q parent() {
		return function(new ParentFunction<>(provider));
	}

	/**
	 * For each element in the collection find its all ancestor.
	 * 
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q parents() {
		return function(new ParentsFunction<>(new RejectingPredicate<>(), provider));
	}

	/**
	 * For each element in the collection find its all ancestor, filtered by a selector.
	 * 
	 * @param selector Parents filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q parents(String selector) {
		return function(new ParentsFunction<>(new RejectingPredicate<>(), provider), selector);
	}

	/**
	 * For each element in the collection find its all ancestor, filtered by a selector.
	 * 
	 * @param predicate Parents filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q parents(Predicate<T> predicate) {
		return function(new ParentsFunction<>(new RejectingPredicate<>(), provider), predicate);
	}

	/**
	 * For each element in the collection find its all ancestor, filtered by a selector.
	 * 
	 * @param iterable Parents filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q parents(Iterable<T> iterable) {
		return function(new ParentsFunction<>(new RejectingPredicate<>(), provider), iterable);
	}

	/**
	 * For each element in the collection find all of its ancestors until the predicate is met.
	 * 
	 * @param until Selector marking when the operation should stop
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q parentsUntil(String until) {
		return function(new ParentsFunction<>(parse(until), provider));
	}

	/**
	 * For each element in the collection find all of its ancestors until the predicate is met.
	 * 
	 * @param predicate Selector marking when the operation should stop
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q parentsUntil(Predicate<T> predicate) {
		return function(new ParentsFunction<>(predicate, provider));
	}

	/**
	 * For each element in the collection find all of its ancestors until the predicate is met.
	 * 
	 * @param iterable Selector marking when the operation should stop
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q parentsUntil(Iterable<T> iterable) {
		return parentsUntil(new IterableContainsPredicate<>(iterable, provider));
	}

	/**
	 * Return the previous sibling for each Resource in the collection.
	 * 
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q prev() {
		return function(new PrevFunction<>(provider));
	}

	/**
	 * Return the previous sibling for each Resource in the collection and filter it by a selector. If the
	 * previous sibling doesn't match it, empty collection will be returned.
	 * 
	 * @param selector Previous sibling filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q prev(String selector) {
		return function(new PrevFunction<>(null, provider), selector);
	}

	/**
	 * Return the previous sibling for each Resource in the collection and filter it by a selector. If the
	 * previous sibling doesn't match it, empty collection will be returned.
	 * 
	 * @param predicate Previous sibling filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q prev(Predicate<T> predicate) {
		return function(new PrevFunction<>(null, provider), predicate);
	}

	/**
	 * Return the previous sibling for each Resource in the collection and filter it by a selector. If the
	 * previous sibling doesn't match it, empty collection will be returned.
	 * 
	 * @param iterable Previous sibling filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q prev(Iterable<T> iterable) {
		return function(new PrevFunction<>(null, provider), iterable);
	}

	/**
	 * Return all previous siblings for each Resource in the collection.
	 * 
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q prevAll() {
		return function(new PrevFunction<>(new RejectingPredicate<>(), provider));
	}

	/**
	 * Return all previous siblings for each Resource in the collection, filtering them by a selector.
	 * 
	 * @param selector Previous siblings filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q prevAll(String selector) {
		return function(new PrevFunction<>(new RejectingPredicate<>(), provider), selector);
	}

	/**
	 * Return all previous siblings for each Resource in the collection, filtering them by a selector.
	 * 
	 * @param predicate Previous siblings filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q prevAll(Predicate<T> predicate) {
		return function(new PrevFunction<>(new RejectingPredicate<>(), provider), predicate);
	}

	/**
	 * Return all previous siblings for each Resource in the collection, filtering them by a selector.
	 * 
	 * @param iterable Previous siblings filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q prevAll(Iterable<T> iterable) {
		return function(new PrevFunction<>(new RejectingPredicate<>(), provider), iterable);
	}

	/**
	 * Return all previous siblings for each Resource in the collection up to, but not including, Resource
	 * matched by a selector.
	 * 
	 * @param until Selector marking when the operation should stop
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q prevUntil(String until) {
		return function(new PrevFunction<>(parse(until), provider));
	}

	/**
	 * Return all previous siblings for each Resource in the collection up to, but not including, Resource
	 * matched by a selector.
	 * 
	 * @param predicate Selector marking when the operation should stop
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q prevUntil(Predicate<T> predicate) {
		return function(new PrevFunction<>(predicate, provider));
	}

	/**
	 * Return all previous siblings for each Resource in the collection up to, but not including, Resource
	 * matched by a selector.
	 * 
	 * @param iterable Selector marking when the operation should stop
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q prevUntil(Iterable<T> iterable) {
		return prevUntil(new IterableContainsPredicate<>(iterable, provider));
	}

	/**
	 * Set new search strategy, which will be used in {@link AbstractQuery#find()} and
	 * {@link AbstractQuery#has(String)} functions.
	 * 
	 * @param strategy Search strategy type
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q searchStrategy(SearchStrategy strategy) {
		return clone(this, strategy);
	}

	/**
	 * Return siblings for the given Ts.
	 * 
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q siblings() {
		return siblings("");
	}

	/**
	 * Return siblings for the given Resources filtered by a selector.
	 * 
	 * @param selector Siblings filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q siblings(String selector) {
		return function(new SiblingsFunction<>(provider), selector);
	}

	/**
	 * Return siblings for the given Resources filtered by a selector.
	 * 
	 * @param predicate Siblings filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q siblings(Predicate<T> predicate) {
		return function(new SiblingsFunction<>(provider), predicate);
	}

	/**
	 * Return siblings for the given Resources filtered by a selector.
	 * 
	 * @param iterable Siblings filter
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q siblings(Iterable<T> iterable) {
		return function(new SiblingsFunction<>(provider), iterable);
	}

	/**
	 * Filter out first {@code from} Resources from the collection.
	 * 
	 * @param from How many Resources to cut out
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q slice(int from) {
		if (from < 0) {
			throw new IndexOutOfBoundsException();
		}
		return function(new SliceFunction<T>(from));
	}

	/**
	 * Reduce the collection to a subcollection specified by a given range. Both from and to are inclusive,
	 * 0-based indices.
	 * 
	 * @param from Low endpoint (inclusive) of the subcollection
	 * @param to High endpoint (inclusive) of the subcollection
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q slice(int from, int to) {
		if (from < 0) {
			throw new IndexOutOfBoundsException();
		}
		if (from > to) {
			throw new IllegalArgumentException();
		}
		return function(new SliceFunction<T>(from, to));
	}

	/**
	 * Filter out duplicated resources in a stream, this iterator is stateful during 
	 * the iteration process.
	 * 
	 * @return new SlingQuery object transformed by this operation
	 */
	public Q unique() {
		return function(new UniqueFunction<>());
	}

	private Q function(Function<?, ?> function, Iterable<T> iterable) {
		Q newQuery = clone(this, this.searchStrategy);
		newQuery.functions.add(function);
		newQuery.functions.add(new FilterFunction<>(new IterableContainsPredicate<>(iterable, provider)));
		return newQuery;
	}

	private Q function(Function<?, ?> function, Predicate<T> predicate) {
		Q newQuery = clone(this, this.searchStrategy);
		newQuery.functions.add(function);
		newQuery.functions.add(new FilterFunction<>(predicate));
		return newQuery;
	}

	private Q function(Function<?, ?> function, String selector) {
		Q newQuery = clone(this, this.searchStrategy);
		newQuery.functions.add(function);
		newQuery.functions.add(new SelectorFunction<>(selector, provider, searchStrategy));
		return newQuery;
	}

	private Q function(Function<?, ?> function) {
		Q newQuery = clone(this, this.searchStrategy);
		newQuery.functions.add(function);
		return newQuery;
	}

	private SelectorFunction<T> parse(String selector) {
		return new SelectorFunction<>(selector, provider, searchStrategy);
	}

	protected abstract Q clone(AbstractQuery<T, Q> original, SearchStrategy strategy);

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("$(");
		Iterator<T> iterator = this.iterator();
		while (iterator.hasNext()) {
			builder.append('[');
			builder.append(iterator.next());
			builder.append(']');
			if (iterator.hasNext()) {
				builder.append(", ");
			}
		}
		builder.append(")");
		return builder.toString();
	}
}