protected override bool ValidateInternal(UInt64 valA, IRowLockingWrapper valAStorage, string valAStr,
                                                     UInt64 valB, IRowLockingWrapper valBStorage, string valBStr,
                                                     out decimal strength)
            {
                if (valAStr != null ||
                    valBStr != null)
                {
                    return(base.ValidateInternal(valA, valAStorage, valAStr,
                                                 valB, valBStorage, valBStr,
                                                 out strength));
                }



                if (valA >= TensDigitsPlusOne)
                {
                    valA -= TensDigitsPlusOne;
                }
                if (valB >= TensDigitsPlusOne)
                {
                    valB -= TensDigitsPlusOne;
                }

                if (valB == valA)
                {
                    strength = 1M;
                    return(true);
                }

                int pow10A     = PowOfTen(valA);
                int pow10B     = PowOfTen(valB);
                int sameDigits = 0;

                if (pow10A == pow10B)
                {
                    sameDigits = Compare(valA, valB);
                }
                else if (pow10A > pow10B)
                {
                    sameDigits = Compare(valA, valB, (uint)(pow10A - pow10B));
                }
                else
                {
                    sameDigits = Compare(valB, valA, (uint)(pow10B - pow10A));
                }

                int numer = sameDigits;
                int denom = digitCount;

                if (denom == 0 ||
                    numer == 0)
                {
                    strength = 0M;
                }
                else if (numer == denom)
                {
                    strength = 1M;
                }
                else
                {
                    strength = (decimal)numer /
                               (decimal)denom;
                }

                return(true);
            }
        ///// <summary>
        ///// searches through rows in table for probable row matches. This uses the same algo as
        ///// the FindProbable() but does not require storage to populate maps with Data Masking
        ///// </summary>
        ///// <param name="value">value to lookup, will be converted to storage type</param>
        ///// <param name="extendedStorageRow">IExtendedStorageRow (can be null) that storage can store temp info into for quicker lookup/generation</param>
        ///// <param name="useValidateForStrength">run validation on looked up probable rows to get a better match strength</param>
        ///// <returns></returns>
        //public Dictionary<DataRow, MatchInfo> SearchForProbableUsingDataMasks(object value, IExtendedStorageRow extendedStorageRow, bool useValidateForStrength)
        //{
        //    throw new NotImplementedException();
        //    //return this.storage.SearchForProbableUsingDataMasks(value, extendedStorageRow, useValidateForStrength);
        //}

        ///// <summary>
        ///// searches through rows in table for row matches. This uses the validate() to calculate match strength as
        ///// but does not require storage to populate maps with DataMasks/// </summary>
        ///// <param name="value"></param>
        ///// <returns></returns>
        //public List<MatchInfo> SearchForProbableUsingValidate(object value)
        //{
        //    throw new NotImplementedException();
        //    //return this.storage.SearchForProbableUsingValidate(value);
        //}

        /// <summary>
        /// validate a value against a row. This is needed because when Finding probable the strength is not as accurate as
        /// the validation method.
        /// </summary>
        /// <param name="value">value to validate</param>
        /// <param name="row">row to check value against. (using sourceColumn)</param>
        /// <returns></returns>
        public MatchInfo Validate(object value, IRowLockingWrapper targetValidationRow, IDataModelTransaction dataModelTransaction)
        {
            return(this.storage.Validate(value, targetValidationRow, dataModelTransaction));
        }
 /// <summary>
 /// lookup exact match for value. returns list of matches or null
 /// </summary>
 /// <param name="value">value to lookup, will be converted to storage type</param>
 /// <param name="extendedStorageRow">IExtendedStorageRow (can be null) that storage can store temp info into for quicker lookup/generation</param>
 /// <returns></returns>
 public List <MatchInfo> FindExact(object value, IRowLockingWrapper valueDataRow, IDataModelTransaction dataModelTransaction)
 {
     return(this.storage.FindExact(value, valueDataRow, dataModelTransaction));
 }
 /// <summary>
 /// find rows that might match, or match some of the value
 /// </summary>
 /// <param name="value">value to lookup, will be converted to storage type</param>
 /// <param name="extendedStorageRow">IExtendedStorageRow (can be null) that storage can store temp info into for quicker lookup/generation</param>
 /// <param name="useValidateForStrength">run validation on looked up probable rows to get a better match strength</param>
 /// <returns></returns>
 public Dictionary <IRow, MatchInfo> FindProbable(object value, IRowLockingWrapper valueDataRow,
                                                  bool useValidateForStrength, IDataModelTransaction dataModelTransaction)
 {
     return(this.storage.FindProbable(value, valueDataRow, useValidateForStrength, dataModelTransaction));
 }
 public void AddTableRowToMap(IRowLockingWrapper rowWrapper)
 {
     this.storage.AddRowToMap(rowWrapper);
 }