/// <summary>
        /// This method adds a CSharpParam to the container
        /// and adds to user parameter dictionary as well.
        /// </summary>
        public unsafe void AddParam(
            ushort paramNumber,
            string paramName,
            SqlDataType dataType,
            ulong paramSize,
            short decimalDigits,
            void *paramValue,
            int strLenOrNullMap,
            short inputOutputType)
        {
            Logging.Trace("CSharpParamContainer::AddParam");
            if (paramName == null)
            {
                throw new ArgumentException("Invalid input parameter name supplied");
            }

            else if (paramNumber >= TotalParams || paramNumber < 0)
            {
                throw new ArgumentException("Invalid input parameter id supplied: " + paramNumber.ToString());
            }

            _params[paramNumber] = new CSharpParam {
                DataType        = dataType,
                DecimalDigits   = decimalDigits,
                Name            = paramName,
                InputOutputType = inputOutputType,
                Number          = paramNumber,
                Size            = paramSize,
                StrLenOrNullMap = strLenOrNullMap
            };

            if (strLenOrNullMap == SQL_NULL_DATA)
            {
                return;
            }

            switch (dataType)
            {
            case SqlDataType.DotNetInteger:
                _params[paramNumber].Value = *(int *)paramValue;
                break;

            case SqlDataType.DotNetUInteger:
                _params[paramNumber].Value = *(uint *)paramValue;
                break;

            case SqlDataType.DotNetBigInt:
                _params[paramNumber].Value = *(long *)paramValue;
                break;

            case SqlDataType.DotNetUBigInt:
                _params[paramNumber].Value = *(ulong *)paramValue;
                break;

            case SqlDataType.DotNetTinyInt:
                _params[paramNumber].Value = *(sbyte *)paramValue;
                break;

            case SqlDataType.DotNetUTinyInt:
                _params[paramNumber].Value = *(byte *)paramValue;
                break;

            case SqlDataType.DotNetSmallInt:
                _params[paramNumber].Value = *(short *)paramValue;
                break;

            case SqlDataType.DotNetUSmallInt:
                _params[paramNumber].Value = *(ushort *)paramValue;
                break;

            case SqlDataType.DotNetDouble:
                _params[paramNumber].Value = *(double *)paramValue;
                break;

            case SqlDataType.DotNetFloat:
                _params[paramNumber].Value = *(double *)paramValue;
                break;

            case SqlDataType.DotNetReal:
                _params[paramNumber].Value = *(float *)paramValue;
                break;

            case SqlDataType.DotNetBit:
                _params[paramNumber].Value = *(bool *)paramValue;
                break;

            case SqlDataType.DotNetChar:
                _params[paramNumber].Value = Interop.UTF8PtrToStr((char *)paramValue, (ulong)strLenOrNullMap);
                break;

            default:
                throw new NotImplementedException("Parameter type for " + dataType.ToString() + " has not been implemented yet");
            }

            UserParams[paramName] = _params[paramNumber].Value;
        }
        /// <summary>
        /// This method replaces the parameter's ODBC-format input value stored in the container
        ///	with the updated output value from execution parameters' dictionary
        /// </summary>
        public unsafe void ReplaceParam(
            ushort paramNumber,
            void **paramValue,
            int *strLenOrNullMap)
        {
            Logging.Trace("CSharpParamContainer::ReplaceParam");
            if (!UserParams.ContainsKey(_params[paramNumber].Name))
            {
                *strLenOrNullMap = SQL_NULL_DATA;
                return;
            }

            _params[paramNumber].Value = UserParams[_params[paramNumber].Name];
            CSharpParam param = _params[paramNumber];

            if (param.Value == null)
            {
                *strLenOrNullMap = SQL_NULL_DATA;
                return;
            }

            *strLenOrNullMap = (int)param.Size;
            switch (param.DataType)
            {
            case SqlDataType.DotNetInteger:
                ReplaceNumericParam <int>((int)param.Value, paramValue);
                break;

            case SqlDataType.DotNetUInteger:
                ReplaceNumericParam <uint>((uint)param.Value, paramValue);
                break;

            case SqlDataType.DotNetBigInt:
                ReplaceNumericParam <long>((long)param.Value, paramValue);
                break;

            case SqlDataType.DotNetUBigInt:
                ReplaceNumericParam <ulong>((ulong)param.Value, paramValue);
                break;

            case SqlDataType.DotNetTinyInt:
                ReplaceNumericParam <sbyte>((sbyte)param.Value, paramValue);
                break;

            case SqlDataType.DotNetUTinyInt:
                ReplaceNumericParam <byte>((byte)param.Value, paramValue);
                break;

            case SqlDataType.DotNetSmallInt:
                ReplaceNumericParam <short>((short)param.Value, paramValue);
                break;

            case SqlDataType.DotNetUSmallInt:
                ReplaceNumericParam <ushort>((ushort)param.Value, paramValue);
                break;

            case SqlDataType.DotNetDouble:
                ReplaceNumericParam <double>((double)param.Value, paramValue);
                break;

            case SqlDataType.DotNetFloat:
                ReplaceNumericParam <double>((double)param.Value, paramValue);
                break;

            case SqlDataType.DotNetReal:
                ReplaceNumericParam <float>((float)param.Value, paramValue);
                break;

            case SqlDataType.DotNetBit:
                bool boolValue = Convert.ToBoolean(param.Value);
                ReplaceNumericParam <bool>(boolValue, paramValue);
                break;

            case SqlDataType.DotNetChar:
                *strLenOrNullMap = (param.Value.Length < *strLenOrNullMap) ? param.Value.Length : *strLenOrNullMap;
                ReplaceStringParam((string)param.Value, paramValue);
                break;

            default:
                throw new NotImplementedException("Parameter type for " + param.DataType.ToString() + " has not been implemented yet");
            }
        }