/*
 * JBoss, Home of Professional Open Source.
 * See the COPYRIGHT.txt file distributed with this work for information
 * regarding copyright ownership.  Some portions may be licensed
 * to Red Hat, Inc. under one or more contributor license agreements.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301 USA.
 */

package org.teiid.translator;

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import org.teiid.language.Argument;
import org.teiid.language.Call;
import org.teiid.language.Command;
import org.teiid.language.LanguageFactory;
import org.teiid.language.QueryExpression;
import org.teiid.metadata.FunctionMethod;
import org.teiid.metadata.MetadataFactory;
import org.teiid.metadata.RuntimeMetadata;

/**
 * Base delegating translator. Will proxy all calls to another {@link ExecutionFactory}. 
 * You will create a custom translator as a subclass of this class containing overrides for
 * any method you wish to intercept.
 * Given that subclass is given a {@link Translator} name of 'custom-delegator', your 'vdb.xml' file will
 * contain an XML fragment like the following to assign the delegate:
 * <pre>
 * {@code
 <translator type="custom-delegator" name="my-translator" description="custom translator">
    <property value="delegateName" name="name of the delegate instance"/>
    <!-- any custom properties will also appear here -->
 </translator>}
 * </pre>
 *  
 */
@Translator(name="delegator", description="Translator that delegates to another translator "
		+ "with capability override certain methods/capabilities")
public class BaseDelegatingExecutionFactory<F, C> extends ExecutionFactory<F, C>
		implements DelegatingExecutionFactory<F, C> {

	private String delegateName;
	private ExecutionFactory<F, C> delegate;
	
	/**
	 * For testing only
	 */
	protected ExecutionFactory<F, C> getDelegate() {
		return this.delegate;
	}
	
	/**
	 * Sets the delegate, will be called by Teiid after {@link #start()}
	 */
	public void setDelegate(ExecutionFactory<F, C> delegate) {
		this.delegate = delegate;
	}
	
	@TranslatorProperty(display="Delegate name", required = true)
	public String getDelegateName() {
		return this.delegateName;
	}
	
	public void setDelegateName(String delegateName) {
		this.delegateName = delegateName;
	}
	
	@Override
	public boolean areLobsUsableAfterClose() {
		return delegate.areLobsUsableAfterClose();
	}
	@Override
	public void closeConnection(C connection, F factory) {
		delegate.closeConnection(connection, factory);
	}
	@Override
	public ProcedureExecution createProcedureExecution(Call command,
			ExecutionContext executionContext, RuntimeMetadata metadata,
			C connection) throws TranslatorException {
		return (ProcedureExecution) delegate.createExecution(command, executionContext,
				metadata, connection);
	}
	@Override
	public ResultSetExecution createResultSetExecution(QueryExpression command,
			ExecutionContext executionContext, RuntimeMetadata metadata,
			C connection) throws TranslatorException {
		return (ResultSetExecution) delegate.createExecution(command, executionContext,
				metadata, connection);
	}
	@Override
	public UpdateExecution createUpdateExecution(Command command,
			ExecutionContext executionContext, RuntimeMetadata metadata,
			C connection) throws TranslatorException {
		return (UpdateExecution) delegate.createExecution(command, executionContext,
				metadata, connection);
	}
	@Override
    public C getConnection(F factory, ExecutionContext executionContext) throws TranslatorException {
		return delegate.getConnection(factory, executionContext);
	}
	
	NullOrder defaultNullOrder;
	@TranslatorProperty(display="Default Null Order", advanced=true)
	@Override
	public NullOrder getDefaultNullOrder() {
		if (defaultNullOrder != null) {
			return defaultNullOrder;
		}
		return delegate.getDefaultNullOrder();
	}
	public void setDefaultNullOrder(NullOrder nullOrder) {
		defaultNullOrder = nullOrder;
	}
	
	@Override
	public LanguageFactory getLanguageFactory() {
		return delegate.getLanguageFactory();
	}
	
	Integer maxFromGroups;
	@TranslatorProperty(display = "Max FROM Allowed", description = "The number of groups supported in the from clause", advanced = true)
	@Override
	public int getMaxFromGroups() {
		if (maxFromGroups != null) {
			return maxFromGroups;
		}
		return delegate.getMaxFromGroups();
	}
	public void setMaxFromGroups(int value) {
		maxFromGroups = value;
	}
	
	@Override
	public void getMetadata(MetadataFactory metadataFactory, C conn)
			throws TranslatorException {
		delegate.getMetadata(metadataFactory, conn);
	}
	
	@Override
	public List<FunctionMethod> getPushDownFunctions() {
		return delegate.getPushDownFunctions();
	}
	
	ArrayList<String> supportedFunctions;
	@Override
	public List<String> getSupportedFunctions() {
		if (supportedFunctions != null) {
			return supportedFunctions;
		}
		return delegate.getSupportedFunctions();
	}
	
	@TranslatorProperty(display = "Add Supported Functions(CSV)", description = "Add comma seperated names to system functions", advanced = true)
	public void setAddSupportedFunctions(String functionNames) {
		if (supportedFunctions == null) {
			supportedFunctions = new ArrayList<String>();
			supportedFunctions.addAll(this.delegate.getSupportedFunctions());
		}
		StringTokenizer st = new StringTokenizer(functionNames, ",");
		while(st.hasMoreTokens()) {
			supportedFunctions.add(st.nextToken().trim());
		}
	}

	@TranslatorProperty(display = "Remove Supported Functions(CSV)", description = "Remove comma seperated names from system functions", advanced = true)
	public void setRemoveSupportedFunctions(String functionNames) {
		if (supportedFunctions == null) {
			supportedFunctions = new ArrayList<String>();
			supportedFunctions.addAll(this.delegate.getSupportedFunctions());
		}
		StringTokenizer st = new StringTokenizer(functionNames, ",");
		while(st.hasMoreTokens()) {
			supportedFunctions.remove(st.nextToken().trim());
		}
	}
	
	@Override
	public TypeFacility getTypeFacility() {
		return delegate.getTypeFacility();
	}
	
	@Override
	public boolean isImmutable() {
		return delegate.isImmutable();
	}
	public void setImmutable(boolean value) {
		delegate.setImmutable(value);
	}
	
	@TranslatorProperty(display="Is Source Required", advanced=true)
	@Override
	public boolean isSourceRequired() {
		return delegate.isSourceRequired();
	}
	public void setSourceRequired(boolean value) {
		delegate.setSourceRequired(value);
	}

	Boolean supportsAggregatesAvg;
	@TranslatorProperty(display="Supports AVG()", advanced=true)
	@Override
	public boolean supportsAggregatesAvg() {
		if (supportsAggregatesAvg != null) {
			return supportsAggregatesAvg;
		}
		return delegate.supportsAggregatesAvg();
	}
	public void setSupportsAggregatesAvg(boolean value) {
		this.supportsAggregatesAvg = value;
	}
	
	Boolean supportsAggregatesCount;
	@TranslatorProperty(display="Supports COUNT()", advanced=true)
	@Override
	public boolean supportsAggregatesCount() {
		if (supportsAggregatesCount != null) {
			return supportsAggregatesCount;
		}
		return delegate.supportsAggregatesCount();
	}
	public void setSupportsAggregatesCount(boolean value) {
		this.supportsAggregatesCount = value;
	}
	
	Boolean supportsAggregatesCountStar;
	@TranslatorProperty(display="Supports Count(*)", advanced=true)
	@Override
	public boolean supportsAggregatesCountStar() {
		if (supportsAggregatesCountStar != null) {
			return supportsAggregatesCountStar;
		}
		return delegate.supportsAggregatesCountStar();
	}
	public void setSupportsAggregatesCountStar(boolean value) {
		this.supportsAggregatesCountStar = value;
	}
	
	Boolean supportsAggregatesDistinct;
	@TranslatorProperty(display="Supports DISTINCT", advanced=true)
	@Override
	public boolean supportsAggregatesDistinct() {
		if (supportsAggregatesDistinct != null) {
			return supportsAggregatesDistinct;
		}
		return delegate.supportsAggregatesDistinct();
	}
	public void setSupportsAggregatesDistinct(boolean value) {
		supportsAggregatesDistinct = value;
	}
	
	Boolean supportsAggregatesEnhancedNumeric;
	@TranslatorProperty(display="Supports Aggegate Enhanced Numeric", advanced=true)
	@Override
	public boolean supportsAggregatesEnhancedNumeric() {
		if (supportsAggregatesEnhancedNumeric != null) {
			return supportsAggregatesEnhancedNumeric;
		}
		return delegate.supportsAggregatesEnhancedNumeric();
	}
	public void setSupportsAggregatesEnhancedNumeric(boolean value) {
		supportsAggregatesEnhancedNumeric = value;
	}
	
	Boolean supportsAggregatesMax;
	@TranslatorProperty(display="Supports MAX", advanced=true)
	@Override
	public boolean supportsAggregatesMax() {
		if (supportsAggregatesMax != null) {
			return supportsAggregatesMax;
		}
		return delegate.supportsAggregatesMax();
	}
	public void setSupportsAggregatesMax(boolean value) {
		supportsAggregatesMax = value;
	}
	
	Boolean supportsAggregatesMin;
	@TranslatorProperty(display="Supports MIN", advanced=true)
	@Override
	public boolean supportsAggregatesMin() {
		if (supportsAggregatesMin != null) {
			return supportsAggregatesMin;
		}
		return delegate.supportsAggregatesMin();
	}
	public void setSupportsAggregatesMin(boolean value) {
		supportsAggregatesMin = value;
	}
	
	Boolean supportsAggregatesSum;
	@TranslatorProperty(display="Supports SUM", advanced=true)
	@Override
	public boolean supportsAggregatesSum() {
		if (supportsAggregatesSum != null) {
			return supportsAggregatesSum;
		}
		return delegate.supportsAggregatesSum();
	}
	public void setSupportsAggregatesSum(boolean value) {
		supportsAggregatesSum = value;
	}
	
	Boolean supportsAliasedTable;
	@TranslatorProperty(display="Supports Alias (ex: as A)", advanced=true)
	@Override
	public boolean supportsAliasedTable() {
		if (supportsAliasedTable != null) {
			return supportsAliasedTable;
		}
		return delegate.supportsAliasedTable();
	}
	public void setSupportsAliasedTable(boolean value) {
		supportsAliasedTable = value;
	}
	
	Boolean supportsBatchedUpdates;
	@TranslatorProperty(display="Supports Batched Updates", advanced=true)
	@Override
	public boolean supportsBatchedUpdates() {
		if (supportsBatchedUpdates != null) {
			return supportsBatchedUpdates;
		}
		return delegate.supportsBatchedUpdates();
	}
	public void setSupportsBatchedUpdates(boolean value) {
		supportsBatchedUpdates = value;
	}
	
	Boolean supportsBulkUpdate;
	@TranslatorProperty(display="Supports Bulk Updates", advanced=true)
	@Override
	public boolean supportsBulkUpdate() {
		if (supportsBulkUpdate != null) {
			return supportsBulkUpdate;
		}
		return delegate.supportsBulkUpdate();
	}
	public void setSupportsBulkUpdate(boolean value) {
		supportsBulkUpdate = value;
	}
	
	Boolean supportsCommonTableExpressions;
	@TranslatorProperty(display="Supports Common Table Expressions", advanced=true)
	@Override
	public boolean supportsCommonTableExpressions() {
		if (supportsCommonTableExpressions != null) {
			return supportsCommonTableExpressions;
		}
		return delegate.supportsCommonTableExpressions();
	}
	public void setSupportsCommonTableExpressions(boolean value) {
		supportsCommonTableExpressions = value;
	}
	
	Boolean supportsCompareCriteriaEquals;
	@TranslatorProperty(display="Supports Compare Criteria Equals", advanced=true)
	@Override
	public boolean supportsCompareCriteriaEquals() {
		if (supportsCompareCriteriaEquals != null) {
			return supportsCompareCriteriaEquals;
		}
		return delegate.supportsCompareCriteriaEquals();
	}
	public void setSupportsCompareCriteriaEquals(boolean value) {
		supportsCompareCriteriaEquals = value;
	}
	
	Boolean supportsCompareCriteriaOrdered;
	@TranslatorProperty(display="Supports Compare Criteria Ordered", advanced=true)
	@Override
	public boolean supportsCompareCriteriaOrdered() {
		if (supportsCompareCriteriaOrdered != null) {
			return supportsCompareCriteriaOrdered;
		}
		return delegate.supportsCompareCriteriaOrdered();
	}
	public void setSupportsCompareCriteriaOrdered(boolean value) {
		supportsCompareCriteriaOrdered = value;
	}
	
	Boolean supportsCorrelatedSubqueries;
	@TranslatorProperty(display="Supports Correlated Subqueries", advanced=true)
	@Override
	public boolean supportsCorrelatedSubqueries() {
		if (supportsCorrelatedSubqueries != null) {
			return supportsCorrelatedSubqueries;
		}
		return delegate.supportsCorrelatedSubqueries();
	}
	public void setSupportsCorrelatedSubqueries(boolean value) {
		supportsCorrelatedSubqueries = value;
	}
	
	Boolean supportsExcept;
	@TranslatorProperty(display="Supports EXCEPT", advanced=true)
	@Override
	public boolean supportsExcept() {
		if (supportsExcept != null) {
			return supportsExcept;
		}
		return delegate.supportsExcept();
	}
	public void setSupportsExcept(boolean value) {
		supportsExcept = value;
	}
	
	Boolean supportsExistsCriteria;
	@TranslatorProperty(display="Supports EXISTS", advanced=true)
	@Override
	public boolean supportsExistsCriteria() {
		if (supportsExistsCriteria != null) {
			return supportsExistsCriteria;
		}
		return delegate.supportsExistsCriteria();
	}
	public void setSupportsExistsCriteria(boolean value) {
		supportsExistsCriteria = value;
	}
	
	Boolean supportsFunctionsInGroupBy;
	@TranslatorProperty(display="Supports Functions in GROUP BY", advanced=true)
	@Override
	public boolean supportsFunctionsInGroupBy() {
		if (supportsFunctionsInGroupBy != null) {
			return supportsFunctionsInGroupBy;
		}
		return delegate.supportsFunctionsInGroupBy();
	}
	public void setSupportsFunctionsInGroupBy(boolean value) {
		supportsFunctionsInGroupBy = value;
	}
	
	Boolean supportsGroupBy;
	@TranslatorProperty(display="Supports GROUP BY", advanced=true)
	@Override
	public boolean supportsGroupBy() {
		if (supportsGroupBy != null) {
			return supportsGroupBy;
		}
		return delegate.supportsGroupBy();
	}
	public void setSupportsGroupBy(boolean value) {
		supportsGroupBy = value;
	}
	
	Boolean supportsHaving;
	@TranslatorProperty(display="Supports HAVING", advanced=true)
	@Override
	public boolean supportsHaving() {
		if (supportsHaving != null) {
			return supportsHaving;
		}
		return delegate.supportsHaving();
	}
	public void setSupportsHaving(boolean value) {
		supportsHaving = value;
	}
	
	Boolean supportsInCriteria;
	@TranslatorProperty(display="Supports IN", advanced=true)
	@Override
	public boolean supportsInCriteria() {
		if (supportsInCriteria != null) {
			return supportsInCriteria;
		}
		return delegate.supportsInCriteria();
	}
	public void setSupportsInCriteria(boolean value) {
		supportsInCriteria = value;
	}
	
	Boolean supportsInCriteriaSubquery;
	@TranslatorProperty(display="Supports IN in Subquery", advanced=true)
	@Override
	public boolean supportsInCriteriaSubquery() {
		if (supportsInCriteriaSubquery != null) {
			return supportsInCriteriaSubquery;
		}
		return delegate.supportsInCriteriaSubquery();
	}
	public void setSupportsInCriteriaSubquery(boolean value) {
		supportsInCriteriaSubquery = value;
	}
	
	Boolean supportsInlineViews;
	@TranslatorProperty(display="Supports Inline Views", advanced=true)
	@Override
	public boolean supportsInlineViews() {
		if (supportsInlineViews != null) {
			return supportsInlineViews;
		}
		return delegate.supportsInlineViews();
	}
	public void setSupportsInlineViews(boolean value) {
		supportsInlineViews = value;
	}
	
	Boolean supportsInsertWithQueryExpression;
	@TranslatorProperty(display="Supports INSERT with Query Expression", advanced=true)
	@Override
	public boolean supportsInsertWithQueryExpression() {
		if (supportsInsertWithQueryExpression != null) {
			return supportsInsertWithQueryExpression;
		}
		return delegate.supportsInsertWithQueryExpression();
	}
	public void setSupportsInsertWithQueryExpression(boolean value) {
		supportsInsertWithQueryExpression = value;
	}
	
	Boolean supportsIntersect;
	@TranslatorProperty(display="Supports INTERSECT", advanced=true)
	@Override
	public boolean supportsIntersect() {
		if (supportsIntersect != null) {
			return supportsIntersect;
		}
		return delegate.supportsIntersect();
	}
	public void setSupportsIntersect(boolean value) {
		supportsIntersect = value;
	}
	
	Boolean supportsIsNullCriteria;
	@TranslatorProperty(display="Supports ISNULL", advanced=true)
	@Override
	public boolean supportsIsNullCriteria() {
		if (supportsIsNullCriteria != null) {
			return supportsIsNullCriteria;
		}
		return delegate.supportsIsNullCriteria();
	}
	public void setSupportsIsNullCriteria(boolean value) {
		supportsIsNullCriteria = value;
	}
	
	Boolean supportsLikeCriteria;
	@TranslatorProperty(display="Supports LIKE", advanced=true)
	@Override
	public boolean supportsLikeCriteria() {
		if (supportsLikeCriteria != null) {
			return supportsLikeCriteria;
		}
		return delegate.supportsLikeCriteria();
	}
	public void setSupportsLikeCriteria(boolean value) {
		supportsLikeCriteria = value;
	}
	
	Boolean supportsLikeCriteriaEscapeCharacter;
	@TranslatorProperty(display="Supports Escape Char in LIKE", advanced=true)
	@Override
	public boolean supportsLikeCriteriaEscapeCharacter() {
		if (supportsLikeCriteriaEscapeCharacter != null) {
			return supportsLikeCriteriaEscapeCharacter;
		}
		return delegate.supportsLikeCriteriaEscapeCharacter();
	}
	public void setSupportsLikeCriteriaEscapeCharacter(boolean value) {
		supportsLikeCriteriaEscapeCharacter = value;
	}
	
	Boolean supportsNotCriteria;
	@TranslatorProperty(display="Supports NOT", advanced=true)
	@Override
	public boolean supportsNotCriteria() {
		if (supportsNotCriteria != null) {
			return supportsNotCriteria;
		}
		return delegate.supportsNotCriteria();
	}
	public void setSupportsNotCriteria(boolean value) {
		supportsNotCriteria = value;
	}
	
	Boolean supportsOrCriteria;
	@TranslatorProperty(display="Supports OR", advanced=true)
	@Override
	public boolean supportsOrCriteria() {
		if (supportsOrCriteria != null) {
			return supportsOrCriteria;
		}
		return delegate.supportsOrCriteria();
	}
	public void setSupportsOrCriteria(boolean value) {
		supportsOrCriteria = value;
	}
	
	Boolean supportsOrderByNullOrdering;
	@TranslatorProperty(display="Supports ORDER BY w/Null [FIRST|LAST]", advanced=true)
	@Override
	public boolean supportsOrderByNullOrdering() {
		if (supportsOrderByNullOrdering != null) {
			return supportsOrderByNullOrdering;
		}
		return delegate.supportsOrderByNullOrdering();
	}
	public void setSupportsOrderByNullOrdering(boolean value) {
		supportsOrderByNullOrdering = value;
	}
	
	Boolean supportsOrderByUnrelated;
	@TranslatorProperty(display="Supports ORDER BY Unrelated", advanced=true)
	@Override
	public boolean supportsOrderByUnrelated() {
		if (supportsOrderByUnrelated != null) {
			return supportsOrderByUnrelated;
		}
		return delegate.supportsOrderByUnrelated();
	}
	public void setSupportsOrderByUnrelated(boolean value) {
		supportsOrderByUnrelated = value;
	}
	
	Boolean supportsQuantifiedCompareCriteriaAll;
	@TranslatorProperty(display="Supports ALL", advanced=true)
	@Override
	public boolean supportsQuantifiedCompareCriteriaAll() {
		if (supportsQuantifiedCompareCriteriaAll != null) {
			return supportsQuantifiedCompareCriteriaAll;
		}
		return delegate.supportsQuantifiedCompareCriteriaAll();
	}
	public void setSupportsQuantifiedCompareCriteriaAll(boolean value) {
		supportsQuantifiedCompareCriteriaAll = value;
	}
	
	Boolean supportsQuantifiedCompareCriteriaSome;
	@TranslatorProperty(display="Supports SOME", advanced=true)
	@Override
	public boolean supportsQuantifiedCompareCriteriaSome() {
		if (supportsQuantifiedCompareCriteriaSome != null) {
			return supportsQuantifiedCompareCriteriaSome;
		}
		return delegate.supportsQuantifiedCompareCriteriaSome();
	}
	public void setSupportsQuantifiedCompareCriteriaSome(boolean value) {
		supportsQuantifiedCompareCriteriaSome = value;
	}
	
	Boolean supportsRowLimit;
	@TranslatorProperty(display="Supports LIMIT", advanced=true)
	@Override
	public boolean supportsRowLimit() {
		if (supportsRowLimit != null) {
			return supportsRowLimit;
		}
		return delegate.supportsRowLimit();
	}
	public void setSupportsRowLimit(boolean value) {
		supportsRowLimit = value;
	}
	
	Boolean supportsRowOffset;
	@TranslatorProperty(display="Supports LIMIT OFFSET", advanced=true)
	@Override
	public boolean supportsRowOffset() {
		if (supportsRowOffset != null) {
			return supportsRowOffset;
		}
		return delegate.supportsRowOffset();
	}
	public void setSupportsRowOffset(boolean value) {
		supportsRowOffset = value;
	}
	
	Boolean supportsScalarSubqueries;
	@TranslatorProperty(display="Supports Scalar Sub-Queries", advanced=true)
	@Override
	public boolean supportsScalarSubqueries() {
		if (supportsScalarSubqueries != null) {
			return supportsScalarSubqueries;
		}
		return delegate.supportsScalarSubqueries();
	}
	public void setSupportsScalarSubqueries(boolean value) {
		supportsScalarSubqueries = value;
	}
	
	Boolean supportsSearchedCaseExpressions;
	@TranslatorProperty(display="Supports CASE Expression", advanced=true)
	@Override
	public boolean supportsSearchedCaseExpressions() {
		if (supportsSearchedCaseExpressions != null) {
			return supportsSearchedCaseExpressions;
		}
		return delegate.supportsSearchedCaseExpressions();
	}
	public void setSupportsSearchedCaseExpressions(boolean value) {
		supportsSearchedCaseExpressions = value;
	}
	
	Boolean supportsSelectExpression;
	@TranslatorProperty(display="Supports SELECT", advanced=true)
	@Override
	public boolean supportsSelectExpression() {
		if (supportsSelectExpression != null) {
			return supportsSelectExpression;
		}
		return delegate.supportsSelectExpression();
	}
	public void setSupportsSelectExpression(boolean value) {
		supportsSelectExpression = value;
	}
	
	Boolean supportsSelfJoins;
	@TranslatorProperty(display="Supports Self JOINS", advanced=true)
	@Override
	public boolean supportsSelfJoins() {
		if (supportsSelfJoins != null) {
			return supportsSelfJoins;
		}
		return delegate.supportsSelfJoins();
	}
	public void setSupportsSelfJoins(boolean value) {
		supportsSelfJoins = value;
	}
	
	Boolean supportsSetQueryOrderBy;
	@TranslatorProperty(display="Supports Set Query Orderby", advanced=true)
	@Override
	public boolean supportsSetQueryOrderBy() {
		if (supportsSetQueryOrderBy != null) {
			return supportsSetQueryOrderBy;
		}
		return delegate.supportsSetQueryOrderBy();
	}
	public void setSupportsSetQueryOrderBy(boolean value) {
		supportsSetQueryOrderBy = value;
	}
	
	Boolean supportsUnions;
	@TranslatorProperty(display="Supports UNION", advanced=true)
	@Override
	public boolean supportsUnions() {
		if (supportsUnions != null) {
			return supportsUnions;
		}
		return delegate.supportsUnions();
	}
	public void setSupportsUnions(boolean value) {
		supportsUnions = value;
	}
	
	@Override
	public String toString() {
		return delegate.toString();
	}
	
	Boolean useAnsiJoin;
	@TranslatorProperty(display="Supports ANSI Joins", advanced=true)
	@Override
	public boolean useAnsiJoin() {
		if (useAnsiJoin != null) {
			return useAnsiJoin;
		}
		return delegate.useAnsiJoin();
	}
	public void setUseAnsiJoin(boolean value) {
		useAnsiJoin = value;
	}
	
	@Override
	public boolean equals(Object obj) {
		return delegate.equals(obj);
	}
	@Override
	public int hashCode() {
		return delegate.hashCode();
	}
	
	@TranslatorProperty(display="Supports Copy LOBS", advanced=true)
	@Override
	public boolean isCopyLobs() {
		return delegate.isCopyLobs();
	}
	public void setCopyLobs(boolean value) {
		delegate.setCopyLobs(value);
	}
	
	Boolean supportsArrayAgg;
	@TranslatorProperty(display="Supports Array Aggregation", advanced=true)
	@Override
	public boolean supportsArrayAgg() {
		if (supportsArrayAgg != null) {
			return supportsArrayAgg;
		}
		return delegate.supportsArrayAgg();
	}
	public void setSupportsArrayAgg(boolean value) {
		supportsArrayAgg = value;
	}
	
	Boolean supportsElementaryOlapOperations;
	@TranslatorProperty(display="Supports OLAP Operations", advanced=true)
	@Override
	public boolean supportsElementaryOlapOperations() {
		if (supportsElementaryOlapOperations != null) {
			return supportsElementaryOlapOperations;
		}
		return delegate.supportsElementaryOlapOperations();
	}
	public void setSupportsElementaryOlapOperations(boolean value) {
		supportsElementaryOlapOperations = value;
	}
	
	@Override
	public boolean supportsFormatLiteral(String literal,
			org.teiid.translator.ExecutionFactory.Format format) {
		return delegate.supportsFormatLiteral(literal, format);
	}
	
	Boolean supportsLikeRegex;
	@TranslatorProperty(display="Supports REGEX in LIKE", advanced=true)
	@Override
	public boolean supportsLikeRegex() {
		if (supportsLikeRegex != null) {
			return supportsLikeRegex;
		}
		return delegate.supportsLikeRegex();
	}
	public void setSupportsLikeRegex(boolean value) {
		supportsLikeRegex = value;	
	}
	
	Boolean supportsOnlyFormatLiterals;
	@TranslatorProperty(display="Supports only Format Literals", advanced=true)
	@Override
	public boolean supportsOnlyFormatLiterals() {
		if (supportsOnlyFormatLiterals != null) {
			return supportsOnlyFormatLiterals;
		}
		return delegate.supportsOnlyFormatLiterals();
	}
	public void setSupportsOnlyFormatLiterals(boolean value) {
		supportsOnlyFormatLiterals = value;
	}
	
	Boolean supportsOnlySingleTableGroupBy;
	@TranslatorProperty(display="Supports Single Table GROUP BY", advanced=true)
	@Override
	public boolean supportsOnlySingleTableGroupBy() {
		if (supportsOnlySingleTableGroupBy != null) {
			return supportsOnlySingleTableGroupBy;
		}
		return delegate.supportsOnlySingleTableGroupBy();
	}
	public void setSupportsOnlySingleTableGroupBy(boolean value) {
		supportsOnlySingleTableGroupBy = value;
	}
	
	Boolean supportsSimilarTo;
	@TranslatorProperty(display="Supports SIMILAR TO", advanced=true)
	@Override
	public boolean supportsSimilarTo() {
		if (supportsSimilarTo != null) {
			return supportsSimilarTo;
		}
		return delegate.supportsSimilarTo();
	}
	public void setSupportsSimilarTo(boolean value) {
		supportsSimilarTo = value;
	}
	
	Boolean supportsWindowDistinctAggregates;
	@TranslatorProperty(display="Supports Windowed Aggregates", advanced=true)
	@Override
	public boolean supportsWindowDistinctAggregates() {
		if (supportsWindowDistinctAggregates != null) {
			return supportsWindowDistinctAggregates;
		}
		return delegate.supportsWindowDistinctAggregates();
	}
	public void setSupportsWindowDistinctAggregates(boolean value) {
		supportsWindowDistinctAggregates = value;
	}
	
	Boolean supportsWindowOrderByWithAggregates;
	@TranslatorProperty(display="Supports Order by With Windowed Aggregates", advanced=true)
	@Override
	public boolean supportsWindowOrderByWithAggregates() {
		if (supportsWindowOrderByWithAggregates != null) {
			return supportsWindowOrderByWithAggregates;
		}
		return delegate.supportsWindowOrderByWithAggregates();
	}
	public void setSupportsWindowOrderByWithAggregates(boolean value) {
		supportsWindowOrderByWithAggregates = value;
	}
	
	@Override
	public int getMaxInCriteriaSize() {
		return delegate.getMaxInCriteriaSize();
	}
	public void setMaxInCriteriaSize(int max) {
		delegate.setMaxInCriteriaSize(max);
	}
	
	@Override
	public org.teiid.translator.ExecutionFactory.SupportedJoinCriteria getSupportedJoinCriteria() {
		return delegate.getSupportedJoinCriteria();
	}
	public void setSupportedJoinCriteria(org.teiid.translator.ExecutionFactory.SupportedJoinCriteria value) {
		this.delegate.setSupportedJoinCriteria(value);
	}
	
	@Override
	public boolean requiresCriteria() {
		return delegate.requiresCriteria();
	}
	public void setRequiresCriteria(boolean value) {
		delegate.setRequiresCriteria(value);
	}
	
	@Override
	public boolean supportsFullOuterJoins() {
		return delegate.supportsFullOuterJoins();
	}
	@Override
	public void setSupportsFullOuterJoins(boolean supportsFullOuterJoins) {
		delegate.setSupportsFullOuterJoins(supportsFullOuterJoins);
	}
	
	@Override
	public boolean supportsInnerJoins() {
		return delegate.supportsInnerJoins();
	}
	@Override
	public void setSupportsInnerJoins(boolean supportsInnerJoins) {
		delegate.setSupportsInnerJoins(supportsInnerJoins);
	}
	
	@Override
	public boolean supportsOrderBy() {
		return delegate.supportsOrderBy();
	}
	
	@Override
	public void setSupportsOrderBy(boolean supportsOrderBy) {
		delegate.setSupportsOrderBy(supportsOrderBy);
	}
	
	@Override
	public boolean supportsOuterJoins() {
		return delegate.supportsOuterJoins();
	}
	@Override
	public void setSupportsOuterJoins(boolean supportsOuterJoins) {
		delegate.setSupportsOuterJoins(supportsOuterJoins);
	}
	
	@Override
	public boolean supportsSelectDistinct() {
		return delegate.supportsSelectDistinct();
	}
	@Override
	public void setSupportsSelectDistinct(boolean supportsSelectDistinct) {
		delegate.setSupportsSelectDistinct(supportsSelectDistinct);
	}
	
	@Override
	public int getMaxDependentInPredicates() {
		return delegate.getMaxDependentInPredicates();
	}
	@Override
	public void setMaxDependentInPredicates(int maxDependentInPredicates) {
		this.delegate.setMaxDependentInPredicates(maxDependentInPredicates);
	}
	
	Boolean supportsAdvancedOlapOperations;
	@TranslatorProperty(display="Supports Advanced OLAP Operations", advanced=true)
	@Override
	public boolean supportsAdvancedOlapOperations() {
		if (supportsAdvancedOlapOperations != null) {
			return supportsAdvancedOlapOperations;
		}
		return delegate.supportsAdvancedOlapOperations();
	}	
	public void setSupportsAdvancedOlapOperations(boolean value) {
		supportsAdvancedOlapOperations = value;	
	}
	
	Boolean supportsSubqueryInOn;
	@TranslatorProperty(display="Supports Subquery In ON", advanced=true)
	@Override
	public boolean supportsSubqueryInOn() {
		if (supportsSubqueryInOn != null) {
			return supportsSubqueryInOn;
		}
		return delegate.supportsSubqueryInOn();
	}
	public void setSupportsSubqueryInOn(boolean value) {
		supportsSubqueryInOn = value;
	}
	
	@Override
	public boolean supportsConvert(int fromType, int toType) {
		return delegate.supportsConvert(fromType, toType);
	}
	
	Boolean supportsDependentJoins;
	@TranslatorProperty(display="Supports Dependent Joins", advanced=true)
	@Override
	public boolean supportsDependentJoins() {
		if (supportsDependentJoins != null) {
			return supportsDependentJoins;
		}
		return delegate.supportsDependentJoins();
	}
	public void setSupportsDependentJoins(boolean value) {
		supportsDependentJoins = value;
	}
	
	Boolean supportsOnlyLiteralComparison;
	@TranslatorProperty(display="Supports Only Literal Comparision", advanced=true)
	@Override
	public boolean supportsOnlyLiteralComparison() {
		if (supportsOnlyLiteralComparison != null) {
			return supportsOnlyLiteralComparison;
		}
		return delegate.supportsOnlyLiteralComparison();
	}
	public void setSupportsOnlyLiteralComparison(boolean value) {
		supportsOnlyLiteralComparison = value;
	}
	
	@Override
	public CacheDirective getCacheDirective(Command command,
			ExecutionContext executionContext, RuntimeMetadata metadata)
			throws TranslatorException {
		return delegate.getCacheDirective(command, executionContext, metadata);
	}
	
	@TranslatorProperty(display="Is Source Required For Metadata", advanced=true)
	@Override	
	public boolean isSourceRequiredForMetadata() {
		return delegate.isSourceRequiredForMetadata();
	}
	public void setSourceRequiredForMetadata(boolean value) {
		delegate.setSourceRequiredForMetadata(value);
	}
	
	Boolean forkable;
	@TranslatorProperty(display="Is Forkable", description="When forkable the engine may use a separate thread to interact with returned Exection", advanced=true)
	@Override
	public boolean isForkable() {
		if (forkable != null) {
			return forkable;
		}
		return delegate.isForkable();
	}
	public void setForkable(boolean value) {
		forkable = value;
	}
	
	Boolean supportsArrayType;
	@TranslatorProperty(display="Supports Array Type", advanced=true)
	@Override
	public boolean supportsArrayType() {
		if (supportsArrayType != null) {
			return supportsArrayType;
		}
		return delegate.supportsArrayType();
	}
	public void setSupportsArrayType(boolean value) {
		supportsArrayType = value;
	}
	
	@Override
	@TranslatorProperty(display="Direct Query Procedure Name", advanced=true)
	public String getDirectQueryProcedureName() {
		return delegate.getDirectQueryProcedureName();
	}
	public void setDirectQueryProcedureName(String name) {
		this.delegate.setDirectQueryProcedureName(name);
	}
	
	@Override
	public boolean supportsDirectQueryProcedure() {
		return delegate.supportsDirectQueryProcedure();
	}
	public void setSupportsDirectQueryProcedure(boolean value) {
		delegate.setSupportsDirectQueryProcedure(value);
	}
	
	@Override
	public ProcedureExecution createDirectExecution(List<Argument> arguments,
			Command command, ExecutionContext executionContext,
			RuntimeMetadata metadata, C connection) throws TranslatorException {
		 return delegate.createDirectExecution(arguments, command, executionContext, metadata, connection);
	}
	
	Boolean supportsOnlyCorrelatedSubqueries;
	@TranslatorProperty(display="Supports Correlated Sub Queries", advanced=true)
	@Override
	public boolean supportsOnlyCorrelatedSubqueries() {
		if (supportsOnlyCorrelatedSubqueries != null) {
			return supportsOnlyCorrelatedSubqueries;
		}
		return delegate.supportsOnlyCorrelatedSubqueries();
	}
	public void setSupportsOnlyCorrelatedSubqueries(boolean value) {
		supportsOnlyCorrelatedSubqueries = value;
	}
	
	Boolean sourceRequiredForCapabilities;
	@TranslatorProperty(display="Source required for Capabilities", advanced=true)
	@Override
	public boolean isSourceRequiredForCapabilities() {
		if (sourceRequiredForCapabilities != null) {
			return sourceRequiredForCapabilities;
		}
		return delegate.isSourceRequiredForCapabilities();
	}
	public void setSourceRequiredForCapabilities(boolean value) {
		sourceRequiredForCapabilities = value;
	}
	
	@Override
	public void initCapabilities(C connection) throws TranslatorException {
		delegate.initCapabilities(connection);
	}
	
	Boolean supportsStringAgg;
	@TranslatorProperty(display="Supports STRING_AGG", advanced=true)
	@Override
	public boolean supportsStringAgg() {
		if (supportsStringAgg != null) {
			return supportsStringAgg;
		}
		return delegate.supportsStringAgg();
	}
	public void setSupportsStringAgg(boolean value) {
		supportsStringAgg = value;
	}
	
	Boolean supportsFullDependentJoins;
	@TranslatorProperty(display="Supports Full Dependent Joins", advanced=true)
	@Override
	public boolean supportsFullDependentJoins() {
		if (supportsFullDependentJoins != null) {
			return supportsFullDependentJoins;
		}
		return delegate.supportsFullDependentJoins();
	}
	public void setSupportsFullDependentJoins(boolean value) {
		supportsFullDependentJoins = value;
	}
	
	Boolean supportsSelectWithoutFrom;
	@TranslatorProperty(display="Supports SELECT w/o FROM", advanced=true)
	@Override
	public boolean supportsSelectWithoutFrom() {
		if (supportsSelectWithoutFrom != null) {
			return supportsSelectWithoutFrom;
		}
		return delegate.supportsSelectWithoutFrom();
	}
	public void setSupportsSelectWithoutFrom(boolean value) {
		supportsSelectWithoutFrom = value;
	}
	
	Boolean supportsGroupByRollup;
	@TranslatorProperty(display="Supports GROUP BY ROLLUP", advanced=true)
	@Override
	public boolean supportsGroupByRollup() {
		if (supportsGroupByRollup != null) {
			return supportsGroupByRollup;
		}
		return delegate.supportsGroupByRollup();
	}
	public void setSupportsGroupByRollup(boolean value) {
		supportsGroupByRollup = value;
	}
	
	Boolean supportsOrderByWithExtendedGrouping;
	@TranslatorProperty(display="Supports Orderby w/extended grouping", advanced=true)
	@Override
	public boolean supportsOrderByWithExtendedGrouping() {
		if (supportsOrderByWithExtendedGrouping != null) {
			return supportsOrderByWithExtendedGrouping;
		}
		return delegate.supportsOrderByWithExtendedGrouping();
	}
	public void setSupportsOrderByWithExtendedGrouping(boolean value) {
		supportsOrderByWithExtendedGrouping = value;
	}
	
	@Override
	public boolean isThreadBound() {
		return delegate.isThreadBound();
	}
	public void setThreadBound(boolean value) {
		delegate.setThreadBound(value);
	}
	
	@Override
	public String getCollationLocale() {
		return delegate.getCollationLocale();
	}
	public void setCollationLocale(String value) {
		delegate.setCollationLocale(value);
	}
	
	Boolean supportsRecursiveCommonTableExpressions;
	@TranslatorProperty(display="Supports Recursive Common Table Expresions", advanced=true)
	@Override
	public boolean supportsRecursiveCommonTableExpressions() {
		if (supportsRecursiveCommonTableExpressions != null) {
			return supportsRecursiveCommonTableExpressions;
		}
		return delegate.supportsRecursiveCommonTableExpressions();
	}
	public void setSupportsRecursiveCommonTableExpressions(boolean value) {
		supportsRecursiveCommonTableExpressions = value;
	}
	
	Boolean supportsCompareCriteriaOrderedExclusive;
	@TranslatorProperty(display="Supports Criteria Ordered Exclusive", advanced=true)
	@Override
	public boolean supportsCompareCriteriaOrderedExclusive() {
		if (supportsCompareCriteriaOrderedExclusive != null) {
			return supportsCompareCriteriaOrderedExclusive;
		}
		return delegate.supportsCompareCriteriaOrderedExclusive();
	}
	public void supportsCompareCriteriaOrderedExclusive(boolean value) {
		supportsCompareCriteriaOrderedExclusive = value;
	}
	
	@Override
	public boolean returnsSingleUpdateCount() {
		return delegate.returnsSingleUpdateCount();
	}
	
	Boolean supportsPartialFiltering;
	@TranslatorProperty(display="Supports Partial Filtering", advanced=true)
	@Override
	public boolean supportsPartialFiltering() {
		if (supportsPartialFiltering != null) {
			return supportsPartialFiltering;
		}
		return delegate.supportsPartialFiltering();
	}
	public void setSupportsPartialFiltering(boolean value) {
		supportsPartialFiltering = value;
	}
	
	Boolean useBindingsForDependentJoin;
	@TranslatorProperty(display="Use Bindings for Dependent Joins", advanced=true)
	@Override
	public boolean useBindingsForDependentJoin() {
		if (useBindingsForDependentJoin != null) {
			return useBindingsForDependentJoin;
		}
		return delegate.useBindingsForDependentJoin();
	}
	public void setUseBindingsForDependentJoin(boolean value) {
		useBindingsForDependentJoin = value;
	}
	
	Boolean supportsSubqueryCommonTableExpressions;
	@TranslatorProperty(display="Supports Subquery Common Table Expressions", advanced=true)
	@Override
	public boolean supportsSubqueryCommonTableExpressions() {
		if (supportsSubqueryCommonTableExpressions != null) {
			return supportsSubqueryCommonTableExpressions;
		}
		return delegate.supportsSubqueryCommonTableExpressions();
	}
	public void setSupportsSubqueryCommonTableExpressions(boolean value) {
		supportsSubqueryCommonTableExpressions = value;
	}
	
	Boolean supportsCorrelatedSubqueryLimit;
	@TranslatorProperty(display="Supports Correlated Subquery Limit", advanced=true)
	@Override
	public boolean supportsCorrelatedSubqueryLimit() {
		if (supportsCorrelatedSubqueryLimit != null) {
			return supportsCorrelatedSubqueryLimit;
		}
		return delegate.supportsCorrelatedSubqueryLimit();
	}
	public void setSupportsCorrelatedSubqueryLimit(boolean value) {
		supportsCorrelatedSubqueryLimit = value;
	}
	
	Character requiredLikeEscape;
	@TranslatorProperty(display="Escape char for LIKE", advanced=true)
	@Override
	public Character getRequiredLikeEscape() {
		if (requiredLikeEscape != null) {
			return requiredLikeEscape;
		}
		return delegate.getRequiredLikeEscape();
	}
	public void setRequiredLikeEscape(Character c) {
		requiredLikeEscape = c;
	}
	
	Boolean supportsScalarSubqueryProjection;
	@TranslatorProperty(display="Supports Scalar SubQuery in SELECT", advanced=true)
	@Override
	public boolean supportsScalarSubqueryProjection() {
		if (supportsScalarSubqueryProjection != null) {
			return supportsScalarSubqueryProjection;
		}
		return delegate.supportsScalarSubqueryProjection();
	}
	public void setSupportsScalarSubqueryProjection(boolean value) {
		supportsScalarSubqueryProjection = value;
	}
	
	@Override
	public org.teiid.translator.ExecutionFactory.TransactionSupport getTransactionSupport() {
		return delegate.getTransactionSupport();
	}
	
	public void setTransactionSupport(TransactionSupport transactionSupport) {
		delegate.setTransactionSupport(transactionSupport);
	}
	
	@Override
	@TranslatorProperty(display="Excluded Common Table Expression Name", advanced=true)
	public String getExcludedCommonTableExpressionName() {
		return delegate.getExcludedCommonTableExpressionName();
	}
	public void setExcludedCommonTableExpressionName(String value) {
		delegate.setExcludedCommonTableExpressionName(value);
	}
	
	Boolean supportsLateralJoin;
	@TranslatorProperty(display="Supports Lateral Join", advanced=true)
	@Override
	public boolean supportsLateralJoin() {
		if (supportsLateralJoin != null) {
			return supportsLateralJoin;
		}
		return delegate.supportsLateralJoin();
	}
	public void setSupportsLateralJoin(boolean value) {
		supportsLateralJoin = value;
	}
	
	Boolean supportsLateralJoinCondition;
	@TranslatorProperty(display="Supports Lateral Join Condition", advanced=true)
	@Override
	public boolean supportsLateralJoinCondition() {
		if (supportsLateralJoinCondition != null) {
			return supportsLateralJoinCondition;
		}
		return delegate.supportsLateralJoinCondition();
	}
	public void setSupportsLateralJoinCondition(boolean value) {
		supportsLateralJoinCondition = value;
	}
	
	Boolean supportsProcedureTable;
	@TranslatorProperty(display="Supports Procedure Table", advanced=true)
	@Override
	public boolean supportsProcedureTable() {
		if (supportsProcedureTable != null) {
			return supportsProcedureTable;
		}
		return delegate.supportsProcedureTable();
	}
	public void setSupportsProcedureTable(boolean value) {
		supportsProcedureTable = value;
	}
	
	Boolean supportsGroupByMultipleDistinctAggregates;
	@TranslatorProperty(display="Supports GROUP By with Multiple DISTINCTS", advanced=true)
	@Override
	public boolean supportsGroupByMultipleDistinctAggregates() {
		if (supportsGroupByMultipleDistinctAggregates != null) {
			return supportsGroupByMultipleDistinctAggregates;
		}
		return delegate.supportsGroupByMultipleDistinctAggregates();
	}
	public void setSupportsGroupByMultipleDistinctAggregates(boolean value) {
		supportsGroupByMultipleDistinctAggregates = value;
	}
	
	@Override
	public void start() throws TranslatorException {
		//nothing to do
	}
	
    Boolean supportsUpsert;
    @TranslatorProperty(display="Supports Upsert", advanced=true)
    @Override
    public boolean supportsUpsert() {
        if (supportsUpsert != null) {
            return supportsUpsert;
        }
        return delegate.supportsGroupByMultipleDistinctAggregates();
    }
    public void setSupportsUpsert(boolean value) {
        supportsUpsert = value;
    }
}
