public IndexView BuildIndexView <T>(int?page                          = null,
                                            int?pageSize                      = null,
                                            string sortKey                    = null,
                                            string sortDirection              = null,
                                            IEnumerable <string> filterKeys   = null,
                                            IEnumerable <string> filterValues = null,
                                            string searchQuery                = null,
                                            params IIndexViewVisitor[] viewVisitors) where T : class, IIdentifiable
        {
            viewVisitors = viewVisitors ?? new IIndexViewVisitor[0];
            page         = page ?? 1;
            pageSize     = pageSize ?? 25;

            Type   modelType = typeof(T);
            string modelName = modelType.Name;

            var view = new IndexView(modelType.AssemblyQualifiedName)
            {
                Title = _pluralizer.Pluralize(modelName)
            };

            var urlHelper = new UrlHelper(RequestContextAdapter.Context);

            BuildSearchControl(searchQuery, view, urlHelper);

            var indexProperties = GetIndexProperties <T>();

            AddHeaderRow(view.Table, indexProperties);

            var entities = _repositoryFactory.Get <T>().All(CrudEntityExtensions.GetComplexPropertyNames(indexProperties)); // determine includes

            entities = Search <T>(entities, searchQuery);
            Filter <T>(ref entities, filterKeys, filterValues, indexProperties);

            int pageCount = entities.Count() / pageSize.Value;

            BuildPager(page, pageSize, sortKey, sortDirection, filterKeys, filterValues, searchQuery, view, ref pageCount, urlHelper);
            Sort <T>(ref entities, sortKey, sortDirection, indexProperties);

            entities = entities.Skip((page.Value - 1) * pageSize.Value).Take(pageSize.Value);

            int rowCount = 0;

            foreach (var mappable in entities)
            {
                var row = new Row(mappable)
                {
                    Id = mappable.Id
                };

                if (++rowCount % 2 == 0)
                {
                    row.Html["class"] = "pure-table-odd";
                }

                row.Html["data-link"] = urlHelper.RouteUrl("Details", new
                {
                    controller = _pluralizer.Pluralize(modelName),
                    action     = "Details",
                    id         = mappable.Id
                });

                foreach (var property in indexProperties)
                {
                    var value = GetPropertyValue <T>(mappable, property);

                    if (value == null)
                    {
                        value = string.Empty;
                    }

                    var column = new Column(property)
                    {
                        Value = value
                    };

                    foreach (var visitor in viewVisitors)
                    {
                        column.Accept(visitor);
                    }

                    row.Columns.Add(column);
                }

                if (row.Columns.Count > 0)
                {
                    foreach (var visitor in viewVisitors)
                    {
                        row.Accept(visitor);
                    }

                    view.Table.Rows.Add(row);
                }
            }

            foreach (var visitor in viewVisitors)
            {
                view.Table.Accept(visitor);
            }

            var create = new ActionModel
            {
                Type        = ActionType.Link,
                RouteName   = "Default",
                RouteValues = new AttributeDictionary(new
                {
                    controller = _pluralizer.Pluralize(modelName),
                    action     = "Update"
                }),
                Html = new AttributeDictionary(new
                {
                    @class = "pure-button button-success",
                    title  = "Create New " + modelName
                })
            };

            create.IconHtmlClasses.Add("fa fa-plus fa-lg");
            view.CreateButton = create;

            foreach (var visitor in viewVisitors)
            {
                view.Accept(visitor);
            }

            return(view);
        }