    
    fileprivate var _cvLeadingSpaceConstraint: NSLayoutConstraint = NSLayoutConstraint()
    fileprivate var _animatingIndexPaths: [IndexPath]?
-   fileprivate var _needsReload: Bool = false
-   fileprivate var _needsLayout: Bool = false
-   fileprivate var _needsAnimatedLayout: Bool = false
    fileprivate var _elements: [Elemental] = []
+   
+   struct ReloadState {
+      var needsReload = false
+      var transition: ElementalTransition = .none
+      
+      mutating func reset() {
+         self = ReloadState()
+      }
+   }
+   fileprivate var _reloadState = ReloadState()
+   
+   struct LayoutState {
+      var needsLayout = false
+      var animated = false
+      
+      mutating func reset() {
+         self = LayoutState()
+      }
+   }
+   fileprivate var _layoutState = LayoutState()
    
    // MARK: - Public Properties
    public var footerViewTopPadding: CGFloat = 0 {

      return true
   }
   
   open func reload() {
      _needsReload = false
      loadViewIfNeeded()
      configure(with: generateElements() ?? _elements, scrollToTop: false)
   }
   
   public func setNeedsReload() {
      guard !_needsReload else { return }
      _needsReload = true
      DispatchQueue.main.async {
         guard self._needsReload else { return }
         self.reload()
      }
   }
   
   public func setNeedsLayout(animated: Bool = true) {
      _needsAnimatedLayout = _needsAnimatedLayout || animated
      guard !_needsLayout else { return }
      _needsLayout = true
      DispatchQueue.main.async {
         guard self._needsLayout else { return }
         self.reloadLayout(animated: self._needsAnimatedLayout)
      }
   }
   

      _refreshControl.endRefreshing()
   }
   
   public func configure(with elements: [Elemental], transition: ElementalTransition = .none, scrollToTop: Bool = true) {
      elements.forEach { $0.register(collectionView: collectionView) }
      self._elements = elements
      
      func _animateReloadedCollectionViewIn(fromRight: Bool) {
         defer { collectionView.reloadData() }
         
         guard let screenshot = view.snapshotView(afterScreenUpdates: false) else { return }
         view.addSubview(screenshot)
         
         _cvLeadingSpaceConstraint.constant = collectionView.bounds.width * (fromRight ? 1 : -1)
         view.layoutIfNeeded()
         collectionView.scrollToItem(at: IndexPath(row: 0, section: 0), at: .top, animated: false)
         
         collectionView.alpha = 0
         UIView.animate(withDuration: 0.25, animations: {
            self._cvLeadingSpaceConstraint.constant = 0
            screenshot.frame.origin.x += self.view.bounds.width * (fromRight ? -1 : 1)
            self.view.layoutIfNeeded()
            self.collectionView.alpha = 1
            screenshot.alpha = 0
         }, completion: { finished in
            screenshot.removeFromSuperview()
         })
      }
      
      switch transition {
      case .none:
         collectionView.reloadData()
         if !elements.isEmpty, scrollToTop {
            collectionView.scrollToItem(at: IndexPath(row: 0, section: 0), at: .top, animated: false)
         }
      case .forwards: _animateReloadedCollectionViewIn(fromRight: true)
      case .backwards: _animateReloadedCollectionViewIn(fromRight: false)
      }
   }
   
