internal void Bind (OciStatementHandle statement, OracleConnection connection) 
		{
			if (bindHandle == null)
				bindHandle = new OciBindHandle ((OciHandle) statement);

			IntPtr tmpHandle = bindHandle.Handle;

			if (Direction != ParameterDirection.Input)
				AssertSizeIsSet ();
			if (!sizeSet)
				size = InferSize ();

			byte[] bytes = null;
			int status = 0;
			int indicator = 0;
			OciDataType bindType = ociType;
			IntPtr bindValue = IntPtr.Zero;
			int bindSize = size;
			int rsize = 0;

			if (value == DBNull.Value) {
				indicator = 0;
				bindType = OciDataType.VarChar2;
				bindSize = 0;
			}
			else {
				// TODO: do other data types and oracle data types
				// should I be using IConvertible to convert?
				if (oracleType == OracleType.DateTime) {
					string oraDateFormat = connection.GetSessionDateFormat ();
					string sysDateFormat = OracleDateTime.ConvertOracleDateFormatToSystemDateTime (oraDateFormat);

					string sDate = "";
					DateTime dt = DateTime.MinValue;
					if (value is String) {
						sDate = (string) value;
						dt = DateTime.Parse (sDate);
					}
					else if (value is DateTime)
						dt = (DateTime) value;
					else if (value is OracleString) {
						sDate = (string) value;
						dt = DateTime.Parse (sDate);
					}
					else if (value is OracleDateTime) {
						OracleDateTime odt = (OracleDateTime) value;
						dt = (DateTime) odt.Value;
					}
					else
						throw new NotImplementedException (); // ?

					sDate = dt.ToString (sysDateFormat);
					rsize = 0;
			
					// Get size of buffer
					OciCalls.OCIUnicodeToCharSet (statement.Parent, null, sDate, out rsize);
			
					// Fill buffer
					bytes = new byte[rsize];
					OciCalls.OCIUnicodeToCharSet (statement.Parent, bytes, sDate, out rsize);
					
					bindType = OciDataType.VarChar2; 
					//bindValue = Marshal.StringToHGlobalAnsi (sDate);
					bindSize = sDate.Length;
				}
				else if (oracleType == OracleType.Blob) {
					bytes = (byte[]) value;
					bindType = OciDataType.LongRaw;
					bindSize = bytes.Length;
				}
				else if (oracleType == OracleType.Clob) {
					string v = (string) value;
					rsize = 0;
			
					// Get size of buffer
					OciCalls.OCIUnicodeToCharSet (statement.Parent, null, v, out rsize);
			
					// Fill buffer
					bytes = new byte[rsize];
					OciCalls.OCIUnicodeToCharSet (statement.Parent, bytes, v, out rsize);

					bindType = OciDataType.Long;
					bindSize = bytes.Length;
				}
				else if (oracleType == OracleType.Raw) {
					byte[] val = value as byte[];
					bindValue = Marshal.AllocHGlobal (val.Length);
					Marshal.Copy (val, 0, bindValue, val.Length);
					bindSize = val.Length;
				}
				else {
					string svalue = value.ToString ();
					rsize = 0;
			
					// Get size of buffer
					OciCalls.OCIUnicodeToCharSet (statement.Parent, null, svalue, out rsize);
			
					// Fill buffer
					bytes = new byte[rsize];
					OciCalls.OCIUnicodeToCharSet (statement.Parent, bytes, svalue, out rsize);

					//bindValue = Marshal.StringToHGlobalAnsi (value.ToString ());
					bindType = OciDataType.VarChar2;
					bindSize = value.ToString ().Length;
				}
			}

			if (bytes != null) {
				status = OciCalls.OCIBindByNameBytes (statement,
					out tmpHandle,
					connection.ErrorHandle,
					ParameterName,
					ParameterName.Length,
					bytes,
					bindSize,
					bindType,
					indicator,
					IntPtr.Zero,
					IntPtr.Zero,
					0,
					IntPtr.Zero,
					0);
			}
			else {
				status = OciCalls.OCIBindByName (statement,
					out tmpHandle,
					connection.ErrorHandle,
					ParameterName,
					ParameterName.Length,
					bindValue,
					bindSize,
					bindType,
					indicator,
					IntPtr.Zero,
					IntPtr.Zero,
					0,
					IntPtr.Zero,
					0);
			}


			if (status != 0) {
				OciErrorInfo info = connection.ErrorHandle.HandleError ();
				throw new OracleException (info.ErrorCode, info.ErrorMessage);
			}

			bindHandle.SetHandle (tmpHandle);
		}