internal void PrepareForBind(
            OracleConnection connection,
            ref int offset
            )
        {
            OracleParameter parameter = Parameter;

            // Don't bother with parameters where the user asks for the default value.
            if (!IsDirection(parameter, ParameterDirection.Output) && null == parameter.Value)
            {
                _bufferLengthInBytes = 0;
                return;
            }

            _bindingMetaType = parameter.GetMetaType();

            // We currently don't support binding a REF CURSOR as an input parameter; that
            // is for a future release.
            if (OCI.DATATYPE.RSET == _bindingMetaType.OciType && ParameterDirection.Output != parameter.Direction)
            {
                throw ADP.InputRefCursorNotSupported(parameter.ParameterName);
            }

            // Make sure we have a coerced value, if we haven't already done
            // so, then save it.
            parameter.SetCoercedValue(_bindingMetaType.BaseType, _bindingMetaType.NoConvertType);
            _coercedValue = parameter.CoercedValue;

            // When they're binding a LOB type, but not providing a LOB object,
            // we have to change the binding under the covers so we aren't forced
            // to create a temporary LOB.
            switch (_bindingMetaType.OciType)
            {
            case OCI.DATATYPE.BFILE:
            case OCI.DATATYPE.BLOB:
            case OCI.DATATYPE.CLOB:
                if (!ADP.IsNull(_coercedValue) && !(_coercedValue is OracleLob || _coercedValue is OracleBFile))
                {
                    _bindingMetaType = MetaType.GetMetaTypeForType(_bindingMetaType.DbType);
                }

                break;
            }

            // For fixed-width types, we take the bind size from the meta type
            // information; if it's zero, then the type must be variable width
            // (or it's an output parameter) and we require that they specify a
            // size.

            _bufferLength = _bindingMetaType.BindSize;

            if ((IsDirection(parameter, ParameterDirection.Output) &&
                 _bindingMetaType.IsVariableLength) ||                  // they must specify a size for variable-length output parameters...
                (0 == _bufferLength && !ADP.IsNull(_coercedValue)) ||   // ...or if it's a non-null, variable-length input paramter...
                (_bufferLength > short.MaxValue))                       // ...or if the parameter type's maximum size is huge.
            {
                int size = parameter.BindSize;

                if (0 != size)
                {
                    _bufferLength = size;
                }

                if (0 == _bufferLength || MetaType.LongMax == _bufferLength)
                {
                    throw ADP.ParameterSizeIsMissing(parameter.ParameterName, _bindingMetaType.BaseType);
                }
            }

            _bufferLengthInBytes = _bufferLength;

            if (_bindingMetaType.IsCharacterType && connection.ServerVersionAtLeastOracle8)
            {
                _bindAsUCS2           = true;
                _bufferLengthInBytes *= ADP.CharSize;
            }

            // Anything with a length that exceeds what fits into a two-byte integer
            // requires special binding because the base types don't allow more than
            // 65535 bytes.  We change the binding under the covers to reflect the
            // different type.

            if (!ADP.IsNull(_coercedValue) &&
                _bufferLength > _bindingMetaType.MaxBindSize)
            {
                // DEVNOTE: it is perfectly fine to bind values less than 65535 bytes
                //          as long, so there's no problem with using the maximum number
                //          of bytes for each Unicode character above.

                switch (_bindingMetaType.OciType)
                {
                case OCI.DATATYPE.CHAR:
                case OCI.DATATYPE.LONG:
                case OCI.DATATYPE.VARCHAR2:
                    _bindingMetaType = (_bindingMetaType.UsesNationalCharacterSet)
                                                ? MetaType.oracleTypeMetaType_LONGNVARCHAR
                                                : MetaType.oracleTypeMetaType_LONGVARCHAR;
                    break;

                case OCI.DATATYPE.RAW:
                case OCI.DATATYPE.LONGRAW:
                    _bindingMetaType = MetaType.oracleTypeMetaType_LONGVARRAW;
                    break;

                default:
                    Debug.Assert(false, "invalid type for long binding!");      // this should never happen!
                    break;
                }

                // Long data requires a LONGVARCHAR or LONGVARRAW binding instead, which
                // mean we have to add another 4 bytes for the length.
                _bufferLengthInBytes += 4;
            }

            if (0 > _bufferLengthInBytes)
            {
                throw ADP.ParameterSizeIsTooLarge(parameter.ParameterName);
            }

            // Fill in the buffer offsets. We lay out the buffer as follows:
            //
            //      indicator   0-3
            //      length      4-7
            //      data        8-...
            //
            _indicatorOffset = offset;   offset += 4;
            _lengthOffset    = offset;   offset += 4;
            _valueOffset     = offset;   offset += _bufferLengthInBytes;

            offset = (offset + 3) & ~0x3;   // DWORD align, please.
        }
        internal void PrepareForBind(OracleConnection connection, ref int offset)
        {
            OracleParameter parameter = this.Parameter;
            bool            flag      = false;
            object          obj2      = parameter.Value;

            if (!IsDirection(parameter, ParameterDirection.Output) && (obj2 == null))
            {
                this._bufferLength = 0;
            }
            else
            {
                this._bindingMetaType = parameter.GetMetaType(obj2);
                if ((OCI.DATATYPE.RSET == this._bindingMetaType.OciType) && System.Data.Common.ADP.IsDirection(parameter.Direction, ParameterDirection.Input))
                {
                    throw System.Data.Common.ADP.InputRefCursorNotSupported(parameter.ParameterName);
                }
                parameter.SetCoercedValueInternal(obj2, this._bindingMetaType);
                this._coercedValue = parameter.GetCoercedValueInternal();
                switch (this._bindingMetaType.OciType)
                {
                case OCI.DATATYPE.CLOB:
                case OCI.DATATYPE.BLOB:
                case OCI.DATATYPE.BFILE:
                    if ((!System.Data.Common.ADP.IsNull(this._coercedValue) && !(this._coercedValue is OracleLob)) && !(this._coercedValue is OracleBFile))
                    {
                        if (!connection.HasTransaction)
                        {
                            this._bindingMetaType = MetaType.GetMetaTypeForType(this._bindingMetaType.DbType);
                            flag = true;
                            break;
                        }
                        this._freeTemporaryLob = true;
                        this._coercedValue     = this.CreateTemporaryLobForValue(connection, this._bindingMetaType.OracleType, this._coercedValue);
                    }
                    break;
                }
                this._bindSize = this._bindingMetaType.BindSize;
                if (((IsDirection(parameter, ParameterDirection.Output) && this._bindingMetaType.IsVariableLength) || ((this._bindSize == 0) && !System.Data.Common.ADP.IsNull(this._coercedValue))) || (this._bindSize > 0x7fff))
                {
                    int bindSize = parameter.BindSize;
                    if (bindSize != 0)
                    {
                        this._bindSize = bindSize;
                    }
                    if (((this._bindSize == 0) || (0x7fffffff == this._bindSize)) && !this.IsEmpty(this._coercedValue))
                    {
                        throw System.Data.Common.ADP.ParameterSizeIsMissing(parameter.ParameterName, this._bindingMetaType.BaseType);
                    }
                }
                this._bufferLength = this._bindSize;
                if (this._bindingMetaType.IsCharacterType && connection.ServerVersionAtLeastOracle8)
                {
                    this._bindAsUCS2    = true;
                    this._bufferLength *= System.Data.Common.ADP.CharSize;
                }
                if (!System.Data.Common.ADP.IsNull(this._coercedValue) && ((this._bindSize > this._bindingMetaType.MaxBindSize) || flag))
                {
                    switch (this._bindingMetaType.OciType)
                    {
                    case OCI.DATATYPE.RAW:
                    case OCI.DATATYPE.LONGRAW:
                        this._bindingMetaType = MetaType.oracleTypeMetaType_LONGVARRAW;
                        break;

                    case OCI.DATATYPE.CHAR:
                    case OCI.DATATYPE.VARCHAR2:
                    case OCI.DATATYPE.LONG:
                        this._bindingMetaType = this._bindingMetaType.UsesNationalCharacterSet ? MetaType.oracleTypeMetaType_LONGNVARCHAR : MetaType.oracleTypeMetaType_LONGVARCHAR;
                        break;
                    }
                    this._bufferLength += 4;
                }
                if (0 > this._bufferLength)
                {
                    throw System.Data.Common.ADP.ParameterSizeIsTooLarge(parameter.ParameterName);
                }
                this._indicatorOffset = offset;
                offset            += IntPtr.Size;
                this._lengthOffset = offset;
                offset            += IntPtr.Size;
                this._valueOffset  = offset;
                offset            += this._bufferLength;
                offset             = (offset + (IntPtr.Size - 1)) & ~(IntPtr.Size - 1);
            }
        }