package eu.dnetlib.dlms.jdbc;

import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Date;
import java.sql.NClob;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLXML;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import eu.dnetlib.dlms.jdbc.server.AbstractDOLEngine;
import eu.dnetlib.dlms.jdbc.server.ParamInfo;
import eu.dnetlib.dlms.lowlevel.objects.Atom;
import eu.dnetlib.dlms.lowlevel.objects.LLDigitalObject;
import eu.dnetlib.dlms.lowlevel.objects.Relation;
import eu.dnetlib.dlms.lowlevel.objects.structures.BooleanBasicValue;
import eu.dnetlib.dlms.lowlevel.objects.structures.DateBasicValue;
import eu.dnetlib.dlms.lowlevel.objects.structures.DescriptionValueCollection;
import eu.dnetlib.dlms.lowlevel.objects.structures.DoubleBasicValue;
import eu.dnetlib.dlms.lowlevel.objects.structures.IntBasicValue;
import eu.dnetlib.dlms.lowlevel.objects.structures.LabelValue;
import eu.dnetlib.dlms.lowlevel.objects.structures.StringBasicValue;
import eu.dnetlib.dlms.lowlevel.objects.structures.Structure;

/**
 * PreparedStatement implementation.
 * 
 * @author lexis
 */
public class DOLPreparedStatement extends DOLStatement implements PreparedStatement {

	/** Parameters of the string to be executed. */
	private Map<String, ParamInfo> parameters = new HashMap<String, ParamInfo>();
	/**
	 * ParameterMetadata instance that holds info about the parameter placeholders' properties and types.
	 */
	private DOLParameterMetadata parameterMetaData;

	/**
	 * Constructor.
	 * 
	 * @param connection
	 *            DorotyConnection instance
	 * @throws SQLException
	 *             Constructor Exception
	 */
	public DOLPreparedStatement(final DorotyConnection connection) throws SQLException {
		super(connection);
		this.parameterMetaData = new DOLParameterMetadata(this);
	}

	/**
	 * Constructor.
	 * 
	 * @param connection
	 *            a DorotyConnection instance
	 * @param dol
	 *            a DOL statement that may contain one or more '?' IN parameter placeholders
	 * @throws SQLException
	 *             Constructor Exception
	 */
	public DOLPreparedStatement(final DorotyConnection connection, final String dol) throws SQLException {
		this(connection);
		this.setDolString(dol);
	}

	public void setParameterMetaData(final DOLParameterMetadata paramMetadata) {
		this.parameterMetaData = paramMetadata;
	}

	public Map<String, ParamInfo> getParameters() {
		return parameters;
	}

	public void setParameters(final Map<String, ParamInfo> parameters) {
		this.parameters = parameters;
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#addBatch()
	 */
	public void addBatch() throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#clearParameters()
	 */
	public void clearParameters() throws SQLException {
		if (this.isClosed())
			throw new SQLException();
		this.parameters.clear();
		this.parameterMetaData = null;
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#execute()
	 */
	public boolean execute() throws SQLException {
		if (this.isClosed()) {
			throw new SQLException("Cannot call execute on a closed PreparedStatement");
		}
		AbstractDOLEngine eng = this.getConnection().getDolEngine();
		this.setDolExecuter(eng.execute(this.getDolString(), this.parameters));
		DOLResultSet rs = this.getResultSetFactory().createDOLResultSet(this, this.getDolExecuter().getColumns());
		this.setResultSet(rs);
		return true;
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#executeQuery()
	 */
	public ResultSet executeQuery() throws SQLException {
		if (this.getResultSet() != null)
			this.getResultSet().close();
		boolean hasResult = this.execute();
		if (!hasResult) {
			throw new SQLException("Called executeQuery on a DOLPreparedStatement that does not return a ResultSet");
		}
		return this.getResultSet();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#executeUpdate()
	 */
	public int executeUpdate() throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#getMetaData()
	 */
	public ResultSetMetaData getMetaData() throws SQLException {
		return this.getResultSet().getMetaData();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#getParameterMetaData()
	 */
	public ParameterMetaData getParameterMetaData() throws SQLException {
		return this.parameterMetaData;
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setArray(int, java.sql.Array)
	 */
	public void setArray(final int parameterIndex, final Array x) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setAsciiStream(int, java.io.InputStream)
	 */
	public void setAsciiStream(final int parameterIndex, final InputStream x) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setAsciiStream(int, java.io.InputStream, int)
	 */
	public void setAsciiStream(final int parameterIndex, final InputStream x, final int length) throws SQLException {
		throw new SQLFeatureNotSupportedException();

	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setAsciiStream(int, java.io.InputStream, long)
	 */
	public void setAsciiStream(final int parameterIndex, final InputStream x, final long length) throws SQLException {
		throw new SQLFeatureNotSupportedException();

	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setBigDecimal(int, java.math.BigDecimal)
	 */
	public void setBigDecimal(final int parameterIndex, final BigDecimal x) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setBinaryStream(int, java.io.InputStream)
	 */
	public void setBinaryStream(final int parameterIndex, final InputStream x) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setBinaryStream(int, java.io.InputStream, int)
	 */
	public void setBinaryStream(final int parameterIndex, final InputStream x, final int length) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setBinaryStream(int, java.io.InputStream, long)
	 */
	public void setBinaryStream(final int parameterIndex, final InputStream x, final long length) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setBlob(int, java.sql.Blob)
	 */
	public void setBlob(final int parameterIndex, final Blob x) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setBlob(int, java.io.InputStream)
	 */
	public void setBlob(final int parameterIndex, final InputStream x) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setBlob(int, java.io.InputStream, long)
	 */
	public void setBlob(final int parameterIndex, final InputStream x, final long length) throws SQLException {
		throw new SQLFeatureNotSupportedException();

	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setBoolean(int, boolean)
	 */
	public void setBoolean(final int parameterIndex, final boolean x) throws SQLException {
		this.setObjectBase(new BooleanBasicValue(x), DorotyObjectEnum.d_boolean, parameterIndex + "");
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setByte(int, byte)
	 */

	public void setByte(final int parameterIndex, final byte x) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setBytes(int, byte[])
	 */

	public void setBytes(final int parameterIndex, final byte[] x) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setCharacterStream(int, java.io.Reader)
	 */
	public void setCharacterStream(final int parameterIndex, final Reader x) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setCharacterStream(int, java.io.Reader, int)
	 */
	public void setCharacterStream(final int parameterIndex, final Reader x, final int length) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setCharacterStream(int, java.io.Reader, long)
	 */
	public void setCharacterStream(final int parameterIndex, final Reader x, final long length) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setClob(int, java.sql.Clob)
	 */
	public void setClob(final int parameterIndex, final Clob x) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setClob(int, java.io.Reader)
	 */
	public void setClob(final int parameterIndex, final Reader x) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setClob(int, java.io.Reader, long)
	 */
	public void setClob(final int parameterIndex, final Reader x, final long length) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setDate(int, java.sql.Date)
	 */
	public void setDate(final int parameterIndex, final Date x) throws SQLException {
		this.setObjectBase(new DateBasicValue(x), DorotyObjectEnum.d_date, parameterIndex + "");
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setDate(int, java.sql.Date, java.util.Calendar)
	 */
	public void setDate(final int parameterIndex, final Date x, final Calendar cal) throws SQLException {
		// TODO: what to do with the calendar??
		this.setObjectBase(new DateBasicValue(x), DorotyObjectEnum.d_date, parameterIndex + "");
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setDouble(int, double)
	 */
	public void setDouble(final int parameterIndex, final double x) throws SQLException {
		this.setObjectBase(new DoubleBasicValue(x), DorotyObjectEnum.d_double, parameterIndex + "");
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setFloat(int, float)
	 */
	public void setFloat(final int parameterIndex, final float x) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setInt(int, int)
	 */
	public void setInt(final int parameterIndex, final int x) throws SQLException {
		this.setObjectBase(new IntBasicValue(x), DorotyObjectEnum.d_int, parameterIndex + "");
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setLong(int, long)
	 */
	public void setLong(final int parameterIndex, final long x) throws SQLException {
		//FIXME transform long into IntBasicValue, which is the expected type wheen handling id attribute in XPathExecutor
		this.setObjectBase(new IntBasicValue((int) x), DorotyObjectEnum.d_int, parameterIndex + "");
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setNCharacterStream(int, java.io.Reader)
	 */
	public void setNCharacterStream(final int parameterIndex, final Reader x) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setNCharacterStream(int, java.io.Reader, long)
	 */
	public void setNCharacterStream(final int parameterIndex, final Reader x, final long length) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setNClob(int, java.sql.NClob)
	 */
	public void setNClob(final int parameterIndex, final NClob x) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setNClob(int, java.io.Reader)
	 */
	public void setNClob(final int parameterIndex, final Reader x) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setNClob(int, java.io.Reader, long)
	 */
	public void setNClob(final int parameterIndex, final Reader x, final long length) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setNString(int, java.lang.String)
	 */
	public void setNString(final int parameterIndex, final String x) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setNull(int, int)
	 */
	public void setNull(final int parameterIndex, final int sqlType) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setNull(int, int, java.lang.String)
	 */
	public void setNull(final int parameterIndex, final int sqlType, final String typeName) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setObject(int, java.lang.Object)
	 */
	public void setObject(final int parameterIndex, final Object x) throws SQLException {
		DorotyObjectEnum type = DorotyObjectEnum.unknown;
		//TODO: commented so that setting null will generate a SQLException and not a NullPointer
		//		if (x instanceof InformationObject)
		//			type = DorotyObjectEnum.unknown;
		//		else {
		if (x instanceof List)
			type = DorotyObjectEnum.d_coll;
		//}
		this.setObjectBase(x, type, parameterIndex + "");
	}

	/**
	 * {@inheritDoc} The value of targetType must match one of the DorotyCode values.
	 * 
	 * @see java.sql.PreparedStatement#setObject(int, java.lang.Object, int)
	 */
	public void setObject(final int parameterIndex, final Object x, final int targetType) throws SQLException {
		this.setObjectBase(x, DorotyObjectEnum.getEnumFromCode(targetType), parameterIndex + "");
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setObject(int, java.lang.Object, int, int)
	 */
	public void setObject(final int parameterIndex, final Object x, final int targetSqlType, final int scaleOrLength) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setRef(int, java.sql.Ref)
	 */
	public void setRef(final int parameterIndex, final Ref x) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setRowId(int, java.sql.RowId)
	 */
	public void setRowId(final int parameterIndex, final RowId x) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setSQLXML(int, java.sql.SQLXML)
	 */
	public void setSQLXML(final int parameterIndex, final SQLXML x) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setShort(int, short)
	 */
	public void setShort(final int parameterIndex, final short x) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setString(int, java.lang.String)
	 */
	public void setString(final int parameterIndex, final String x) throws SQLException {
		this.setObjectBase(new StringBasicValue(x), DorotyObjectEnum.d_string, parameterIndex + "");
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setTime(int, java.sql.Time)
	 */
	public void setTime(final int parameterIndex, final Time x) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setTime(int, java.sql.Time, java.util.Calendar)
	 */
	public void setTime(final int parameterIndex, final Time x, final Calendar cal) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setTimestamp(int, java.sql.Timestamp)
	 */
	public void setTimestamp(final int parameterIndex, final Timestamp x) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setTimestamp(int, java.sql.Timestamp, java.util.Calendar)
	 */
	public void setTimestamp(final int parameterIndex, final Timestamp x, final Calendar cal) throws SQLException {
		throw new SQLFeatureNotSupportedException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setURL(int, java.net.URL)
	 */
	public void setURL(final int parameterIndex, final URL x) throws SQLException {
		this.setObjectBase(x, DorotyObjectEnum.std_url, parameterIndex + "");

	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.PreparedStatement#setUnicodeStream(int, java.io.InputStream, int)
	 */
	public void setUnicodeStream(final int parameterIndex, final InputStream x, final int length) throws SQLException {
		throw new SQLFeatureNotSupportedException();

	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.sql.Statement#close()
	 */
	@Override
	public void close() throws SQLException {
		super.close();
		this.parameters = null;
		this.parameterMetaData = null;
	}

	// **********************************Utility*****************************************************//

	ParamInfo createParamInfo(final Object x, final DorotyObjectEnum dorotyType, final String paramName) throws SQLException {
		ParamInfo paramInfo = new ParamInfo();
		paramInfo.setType(dorotyType);
		try {
			switch (dorotyType) {
			case d_boolean:
				BooleanBasicValue boolValue = (BooleanBasicValue) x;
				paramInfo.setValue(boolValue);
				break;
			case std_boolean:
				boolean b = ((Boolean) x).booleanValue();
				paramInfo.setValue(b);
				break;
			case d_date:
				DateBasicValue dateValue = (DateBasicValue) x;
				paramInfo.setValue(dateValue);
				break;
			case std_date:
				Date date = (Date) x;
				paramInfo.setValue(date);
				break;
			case d_int:
				IntBasicValue intValue = (IntBasicValue) x;
				paramInfo.setValue(intValue);
				break;
			case std_int:
				int v = ((Integer) x).intValue();
				paramInfo.setValue(v);
				break;
			case d_string:
				StringBasicValue strValue = (StringBasicValue) x;
				paramInfo.setValue(strValue);
				break;
			case std_string:
				String str = (String) x;
				paramInfo.setValue(str);
				break;
			case std_double:
				double d = ((Double) x).doubleValue();
				paramInfo.setValue(d);
				break;
			case d_double:
				DoubleBasicValue dbv = ((DoubleBasicValue) x);
				paramInfo.setValue(dbv);
				break;
			case std_long:
				long l = ((Long) x).longValue();
				paramInfo.setValue(l);
				break;
			case d_coll:
				DescriptionValueCollection dvc = new DescriptionValueCollection();
				List<LabelValue> values = new ArrayList<LabelValue>();
				List<String> src = (List<String>) x;
				for (String s : src)
					values.add(new StringBasicValue(s));
				dvc.setValueCollection(values);
				paramInfo.setValue(dvc);
				break;
			case std_url:
				URL url = (URL) x;
				paramInfo.setValue(url);
				break;
			case atom:
				Atom atom = (Atom) x;
				paramInfo.setValue(atom);
				break;
			case object:
				LLDigitalObject obj = (LLDigitalObject) x;
				paramInfo.setValue(obj);
				break;
			case relation:
				Relation rel = (Relation) x;
				paramInfo.setValue(rel);
				break;
			case structure:
				Structure s = (Structure) x;
				paramInfo.setValue(s);
				break;
			case unknown:
				InformationObjectImpl info = (InformationObjectImpl) x;
				paramInfo.setValue(info);
				break;
			default:
				throw new SQLFeatureNotSupportedException("Unknwon Type");
			}
		} catch (ClassCastException cce) {
			throw new SQLException("Type mismatch for parameter at index " + paramName);
		}
		return paramInfo;
	}

	/**
	 * Sets the info for the parameter at the given position of this PreparedStatement.
	 * 
	 * @param parameterIndex
	 *            index of the parameter
	 * @param x
	 *            value of the parameter
	 * @param dorotyType
	 *            type of the parameter
	 * @throws SQLException
	 *             if the given type does not match the type of x or if it is not supported.
	 */
	void setObjectBase(final Object x, final DorotyObjectEnum dorotyType, final String parameterName) throws SQLException {
		ParamInfo paramInfo = this.createParamInfo(x, dorotyType, parameterName);
		this.setParameter(Integer.parseInt(parameterName), paramInfo);
	}

	/**
	 * Sets the Object x as the parameter at the parameterIndex index in the parameters array.
	 * 
	 * @param parameterIndex
	 *            index of the parameter to set. Allowed values go from 1 to this.parameters.length.
	 * @param x
	 *            the parameter value
	 * @throws SQLException
	 *             if the connection is closed or the index is not in the range [1,parameters.length]
	 */
	void setParameter(final int parameterIndex, final ParamInfo x) throws SQLException {
		//		if (this.isClosed() || !this.validIndexForParameters(parameterIndex)) {
		//			throw new SQLException();
		//		}
		if (this.isClosed()) {
			throw new SQLException();
		}
		x.setIndex(parameterIndex);
		this.parameters.put(parameterIndex + "", x);
	}

	//	/**
	//	 * Checks if every parameter has been set.
	//	 * 
	//	 * @return true if all parameters are set, false otherwise.
	//	 */
	//	private boolean allParametersSet() {
	//		if (this.parameters.size() == this.countNumberOfParameters()) {
	//			for (ParamInfo p : this.parameters.values())
	//				if (p == null)
	//					return false;
	//			return true;
	//		} else
	//			return false;
	//	}

	//	/**
	//	 * Checks if the given index is in the range of the valid parameters indexes [1,parameters.length].
	//	 * 
	//	 * @param index
	//	 *            int value
	//	 * @return true if index belongs to the range [1,parameters.length].
	//	 */
	//	private boolean validIndexForParameters(final int index) {
	//		return (index >= 1 && index <= this.countNumberOfParameters());
	//	}

	//	/**
	//	 * Counts the number of the parameter of the dol string.
	//	 * 
	//	 * @return the number of '?' char in this.dolString
	//	 */
	//	int countNumberOfParameters() {
	//		char[] sqlChars = this.getDolString().toCharArray();
	//		int numParams = 0;
	//		for (char c : sqlChars) {
	//			if (c == '?')
	//				numParams++;
	//		}
	//		return numParams;
	//	}

	// *************************************************************************************************//
}
