public ValidatingDataReader
        (
            IDataReader readerToWrap,
            SqlConnection conn,
            SqlBulkCopy bcp,
            bool trimLongStringsInsteadOfThrowing
        )
        {
            readerToWrap.ThrowIfNull("reader");
            conn.ThrowIfNull("conn");
            bcp.ThrowIfNull("bcp");
            bcp.DestinationTableName.ThrowIfNullOrEmpty("bcp.DestinationTableName");

            TrimLongStringsInsteadOfThrowing = trimLongStringsInsteadOfThrowing;
            wrappedReader      = readerToWrap;
            targetTableName    = bcp.DestinationTableName;
            targetDatabaseName = conn.Database;
            targetServerName   = conn.DataSource;
            currentRecord      = -1;

            ConnectionState origState = conn.State;

            if (conn.State == ConnectionState.Closed)
            {
                conn.Open();
            }

            ValidateBulkCopySourceColumnMappings(bcp.ColumnMappings);
            DataTable schemaTableOfDestinationTable = GetSchemaTable(conn, origState);

            lookup = new DataRow[readerToWrap.FieldCount];

            if (bcp.ColumnMappings.Count > 0)
            {
                DataRow[] columns = new DataRow[schemaTableOfDestinationTable.Rows.Count];
                Dictionary <string, int> columnLookup = new Dictionary <string, int>();

                foreach (DataRow column in schemaTableOfDestinationTable.Rows)
                {
                    string columnName    = (string)column["ColumnName"];
                    int    columnOrdinal = (int)column["ColumnOrdinal"];
                    columns[columnOrdinal]   = column;
                    columnLookup[columnName] = columnOrdinal;
                }

                ValidateBulkCopyDestinationColumnMappings(bcp.ColumnMappings, columnLookup, columns);
                CreateLookupFromColumnMappings(bcp.ColumnMappings, schemaTableOfDestinationTable);
            }
            else
            {
                foreach (DataRow column in schemaTableOfDestinationTable.Rows)
                {
                    int columnOrdinal = (int)column["ColumnOrdinal"];
                    lookup[columnOrdinal] = column;
                }
            }
        }
        /// <summary>
        /// Retrieve the total number of rows copied in a SqlBulkCopy operation.
        /// </summary>
        /// <param name="bulkCopy">The bulk copy object.</param>
        /// <returns>Total number of rows copied.</returns>
        public static int TotalRowsCopied(this SqlBulkCopy bulkCopy)
        {
            bulkCopy.ThrowIfNull("bulkCopy");

            if (rowsCopiedField == null)
            {
                rowsCopiedField = typeof(SqlBulkCopy).GetField
                                  (
                    "_rowsCopied",
                    BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance
                                  );
            }

            return((int)rowsCopiedField.GetValue(bulkCopy));
        }