protected override SqlProvider VisitContainsTable(ContainsTableProvider provider)
        {
            SqlContainsTable fromTable;

            QueryParameterBinding[] bindings;

            var stringTypeMapping = Driver.GetTypeMapping(StringType);
            var criteriaBinding   = new QueryParameterBinding(
                stringTypeMapping, provider.SearchCriteria.Invoke, QueryParameterBindingType.Regular);

            var index   = provider.PrimaryIndex.Resolve(Handlers.Domain.Model);
            var table   = Mapping[index.ReflectedType];
            var columns = provider.Header.Columns.Select(column => column.Name).ToList();

            var targetColumnNames = provider.TargetColumns.Select(c => c.Name).ToArray();

            if (provider.TopN == null)
            {
                fromTable = SqlDml.ContainsTable(table, criteriaBinding.ParameterReference, columns, targetColumnNames);
                bindings  = new[] { criteriaBinding };
            }
            else
            {
                var intTypeMapping = Driver.GetTypeMapping(Int32Type);
                var topNBinding    = new QueryParameterBinding(intTypeMapping, context => provider.TopN.Invoke(context), QueryParameterBindingType.Regular);
                fromTable = SqlDml.ContainsTable(table, criteriaBinding.ParameterReference, columns, targetColumnNames, topNBinding.ParameterReference);
                bindings  = new[] { criteriaBinding, topNBinding };
            }
            var fromTableRef = SqlDml.QueryRef(fromTable);
            var select       = SqlDml.Select(fromTableRef);

            select.Columns.Add(fromTableRef.Columns[0]);
            select.Columns.Add(SqlDml.Cast(fromTableRef.Columns[1], SqlType.Double), "RANK");

            return(CreateProvider(select, bindings, provider));
        }