     }
 
     internal func clearSelected() {
-        for i in stride(from: selectedIndices.count-1, through: 0, by: -1) {
-            let path = selectedIndices[i]
-            selectedIndices.remove(at: i)
+        guard let indices = collectionView.indexPathsForSelectedItems else { return }
+        for i in stride(from: indices.count-1, through: 0, by: -1) {
+            let path = indices[i]
             collectionView?.deselectItem(at: path, animated: true)
             collectionView?.delegate?.collectionView?(collectionView, didDeselectItemAt: path)
         }
     }
-
-    internal func getSelectedCount() -> Int {
-        return selectedIndices.count
-    }
-
-    internal func isIndexSelected(_ indexPath: IndexPath) -> Bool {
-        return selectedIndices.contains(indexPath)
-    }
 }

    @discardableResult internal func setSelected(_ selected: Bool, for indexPath: IndexPath) -> Bool {
        if (collectionView.delegate?.collectionView?(collectionView, shouldSelectItemAt: indexPath) == false && selected)
        || (collectionView.delegate?.collectionView?(collectionView, shouldDeselectItemAt: indexPath) == false && !selected) {
            return selectedIndices.contains(indexPath) //return state of selection, don't do anything
        }

        if selected {
            if selectedIndices.contains(indexPath) {
                return true //already selected, don't do anything
            } else if maxSelectionCount == nil || selectedIndices.count < maxSelectionCount! {
                selectedIndices.append(indexPath)
                collectionView.selectItem(at: indexPath, animated: true, scrollPosition: [])
                collectionView.delegate?.collectionView?(collectionView, didSelectItemAt: indexPath)
                return true //not already selected and doesn't exceed max, insert
            } else {
                return false //not already selected but exceeds max, don't insert
            }
        } else if let i = selectedIndices.index(of: indexPath) {
            selectedIndices.remove(at: i)
            collectionView.deselectItem(at: indexPath, animated: true)
            collectionView.delegate?.collectionView?(collectionView, didDeselectItemAt: indexPath)
            return false //selected, remove selection

     `true` for selected, `false` for deselected.
     */
    @discardableResult internal func toggleSelected(indexPath: IndexPath) -> Bool {
        if collectionView.indexPathsForSelectedItems?.contains(indexPath) == true { //is selected, attempt remove selection
            if collectionView.delegate?.collectionView?(collectionView, shouldDeselectItemAt: indexPath) == true {
                collectionView.deselectItem(at: indexPath, animated: true)
                collectionView.delegate?.collectionView?(collectionView, didDeselectItemAt: indexPath)
                return false
            } else { return true } //deselection disallowed, keep selected
        } else { //is unselected, attempt selection
            if collectionView.delegate?.collectionView?(collectionView, shouldSelectItemAt: indexPath) == true &&
            (maxSelectionCount == nil || collectionView.indexPathsForSelectedItems?.count ?? 0 < maxSelectionCount!) {
                collectionView.selectItem(at: indexPath, animated: true, scrollPosition: [])
                collectionView.delegate?.collectionView?(collectionView, didSelectItemAt: indexPath)
                return true
