     
     open override func numberOfSections(in tableView: UITableView) -> Int {
         var numberOfSections = 0
-        for section in 0 ..< super.numberOfSections(in: tableView) {
-            if !shouldHideSection(section) {
+        for superSection in 0 ..< super.numberOfSections(in: tableView) {
+            if shouldInclude(superSection: superSection) {
                 numberOfSections += 1
             }
         }
         return numberOfSections
     }
     
+    open override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
+        return super.tableView(tableView, heightForHeaderInSection: superSection(forSection: section))
+    }
+    
+    open override func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
+        return super.tableView(tableView, heightForFooterInSection: superSection(forSection: section))
+    }
+    
+    open override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
+        return super.tableView(tableView, titleForHeaderInSection: superSection(forSection: section))
+    }
+    
+    open override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
+        return super.tableView(tableView, titleForFooterInSection: superSection(forSection: section))
+    }
+    
+    open override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
+        return super.tableView(tableView, viewForHeaderInSection: superSection(forSection: section))
+    }
+    
+    open override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
+        return super.tableView(tableView, viewForFooterInSection: superSection(forSection: section))
+    }
+    
     open override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
-        let numberOfRowsInSection = super.tableView(tableView, numberOfRowsInSection: section)
-        let numberOfExcludedCellsInThisSection: Int
-        if numberOfRowsInSection == 0 {
-            numberOfExcludedCellsInThisSection = 0
-        } else {
-            numberOfExcludedCellsInThisSection = numberOfExcludedRows(inSection: section)
-        }
-        return super.tableView(tableView, numberOfRowsInSection: section) - numberOfExcludedCellsInThisSection
+        let superSection = self.superSection(forSection: section)
+        let numberOfRowsInSuperSection = super.tableView(tableView, numberOfRowsInSection: superSection)
+        let numberOfExcludedRowsInThisSection: Int = numberOfRowsInSuperSection == 0
+            ? 0
+            : numberOfExcludedRows(inSuperSection: superSection)
+        return numberOfRowsInSuperSection - numberOfExcludedRowsInThisSection
     }
     
     open override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    private func numberOfExcludedSections(beforeSection section: Int) -> Int {
        var numberOfExcludedSections = 0
        for superSection in 0 ..< super.numberOfSections(in: tableView) {
            if shouldHideSection(superSection) {
                numberOfExcludedSections += 1
            }
        }
        return numberOfExcludedSections
    }
    
    fileprivate func numberOfExcludedRowsInSection(before indexPath: IndexPath) -> Int {
        var numberOfExcludedRows = 0
        if let excludedCells = excludedCells {
            for superRow in 0 ..< super.tableView(tableView, numberOfRowsInSection: indexPath.section) {
                let superIndexPath = IndexPath(row: superRow, section: indexPath.section)
                let cell = super.tableView(tableView, cellForRowAt: superIndexPath)
                if excludedCells.contains(cell) {
                    numberOfExcludedRows += 1
                } else if superRow - numberOfExcludedRows == indexPath.row {
                    break
                }
            }

            return tableView.frame.size.height - tableView.contentInset.top
        }
    }
    
    // MARK: - Functions
    
    open func indexPaths(toInsert cells: [UITableViewCell]) -> [IndexPath] {
        var indexPaths = [IndexPath]()
        for section in 0 ..< super.numberOfSections(in: tableView) {
            var numberOfExcludedRows = 0
            for row in 0 ..< super.tableView(tableView, numberOfRowsInSection: superSection(forSection: section)) {
                let superIndexPath = IndexPath(row: row, section: section)
                let superCell = super.tableView(tableView, cellForRowAt: superIndexPath)
                if cells.contains(superCell) && tableView.indexPath(for: superCell) == nil {
