     */
     
     func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
-        return CGFloat(TableViewCell.heightWithItem(self.itemAtIndexPath(indexPath), tableView: tableView, indexPath: indexPath))
-    }
-    
-    func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
-        if let headerView = self.sectionAtIndexPath(NSIndexPath(forRow: 0, inSection: section)).headerView {
+        if let item = self.itemAtIndexPath(indexPath) {
+            return CGFloat(TableViewCell.heightWithItem(item, tableView: tableView, indexPath: indexPath))
+        }
+        return UITableViewAutomaticDimension
+    }
+    
+    func tableView(tableView: UITableView, heightForHeaderInSection index: Int) -> CGFloat {
+        if let section = self.sectionAtIndexPath(NSIndexPath(forRow: 0, inSection: index)), let headerView = section.headerView {
             return headerView.frame.height
         }
         return UITableViewAutomaticDimension
     }
     
-    func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
-        if let footerView = self.sectionAtIndexPath(NSIndexPath(forRow: 0, inSection: section)).footerView {
+    func tableView(tableView: UITableView, heightForFooterInSection index: Int) -> CGFloat {
+        if let section = self.sectionAtIndexPath(NSIndexPath(forRow: 0, inSection: index)), let footerView = section.footerView {
             return footerView.frame.height
         }
         return UITableViewAutomaticDimension
     }
     
     func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
-        let item = self.itemAtIndexPath(indexPath)
-        return CGFloat(TableViewCell.estimatedHeightWithItem(item, tableView: tableView, indexPath: indexPath))
+        if let item = self.itemAtIndexPath(indexPath) {
+            return CGFloat(TableViewCell.estimatedHeightWithItem(item, tableView: tableView, indexPath: indexPath))
+        }
+        return UITableViewAutomaticDimension
     }
     
     func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
-        return self.sectionAtIndexPath(NSIndexPath(forRow: 0, inSection: section)).headerView
+        return self.sectionAtIndexPath(NSIndexPath(forRow: 0, inSection: section))?.headerView
     }
     
     func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
-        return self.sectionAtIndexPath(NSIndexPath(forRow: 0, inSection: section)).footerView
+        return self.sectionAtIndexPath(NSIndexPath(forRow: 0, inSection: section))?.footerView
     }
     
     /*

    */

    func tableView(tableView: UITableView, targetIndexPathForMoveFromRowAtIndexPath sourceIndexPath: NSIndexPath, toProposedIndexPath proposedDestinationIndexPath: NSIndexPath) -> NSIndexPath {
        let sourceSection = self.sectionAtIndexPath(sourceIndexPath)
        let item = self.itemAtIndexPath(sourceIndexPath)
        if let moveHandler = item.moveHandler {
            let allowed = moveHandler(section: sourceSection, item: item, tableView: tableView, sourceIndexPath: sourceIndexPath, destinationIndexPath: proposedDestinationIndexPath)
            if !allowed {
                return sourceIndexPath
            }
        }
        
        return proposedDestinationIndexPath
    }

    func tableView(tableView: UITableView, indentationLevelForRowAtIndexPath indexPath: NSIndexPath) -> Int {
        return self.itemAtIndexPath(indexPath).indentationLevel
    }
    
    func tableView(tableView: UITableView, shouldShowMenuForRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        let item = self.itemAtIndexPath(indexPath)
        return item.copyHandler != nil || item.pasteHandler != nil || item.cutHandler != nil
        
    }
    
    func tableView(tableView: UITableView, canPerformAction action: Selector, forRowAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject) -> Bool {
        let item = self.itemAtIndexPath(indexPath)
        
        if item.copyHandler != nil && action == Selector("copy:") {
            return true
        }
        
        if item.pasteHandler != nil && action == Selector("paste:") {
            return true
        }
        
        if item.cutHandler != nil && action == Selector("cut:") {
            return true
        }
        
        return false
    }
    
    func tableView(tableView: UITableView, performAction action: Selector, forRowAtIndexPath indexPath: NSIndexPath, withSender sender: AnyObject!) {
        let item = self.itemAtIndexPath(indexPath)
        let section = self.sectionAtIndexPath(indexPath)
        if let copyHandler = item.copyHandler where action == Selector("copy:") {
            copyHandler(section: section, item: item, tableView: tableView, indexPath: indexPath)
        }
        if let pasteHandler = item.pasteHandler where action == Selector("paste:") {
            pasteHandler(section: section, item: item, tableView: tableView, indexPath: indexPath)
        }
        if let cutHandler = item.cutHandler where action == Selector("cut:") {
            cutHandler(section: section, item: item, tableView: tableView, indexPath: indexPath)
        }
    }
}
    }
    
    func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if let section = self.sectionAtIndexPath(indexPath), let item = self.itemAtIndexPath(indexPath) {
            if editingStyle == .Delete {
                if let deletionHandlerWithCompletion = item.deletionHandlerWithCompletion {
                    deletionHandlerWithCompletion(section: section, item: item, tableView: tableView, indexPath: indexPath, completionHandler: { (Void) -> (Void) in
                        section.items.removeAtIndex(indexPath.row)
                        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
                    })
                } else {
                    if let deletionHandler = item.deletionHandler {
                        deletionHandler(section: section, item: item, tableView: tableView, indexPath: indexPath)
                    }
                    section.items.removeAtIndex(indexPath.row)
                    tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
                }
            }
            
            if editingStyle == .Insert {
                if let insertionHandler = item.insertionHandler {
                    insertionHandler(section: section, item: item, tableView: tableView, indexPath: indexPath)
                }
            }
        }
    }
