                 self.whiteBalanceEnded()
             }
         })
-        
-        
 
         self._observers.append(currentDevice.observe(\.isFlashAvailable, options: [.new]) { (object, change) in
-            self.flashAndTorchAvailabilityChanged()
+            DispatchQueue.main.async {
+                self.flashDelegate?.nextLevelFlashAndTorchAvailabilityChanged(self)
+            }
         })
         
         self._observers.append(currentDevice.observe(\.isTorchAvailable, options: [.new]) { (object, change) in
-            self.flashAndTorchAvailabilityChanged()
+            DispatchQueue.main.async {
+                self.flashDelegate?.nextLevelFlashAndTorchAvailabilityChanged(self)
+            }
         })
         
         self._observers.append(currentDevice.observe(\.isFlashActive, options: [.new]) { (object, change) in
-            self.flashActiveChanged()
+            // adjust white balance mode depending on the flash
+            let whiteBalanceMode = self.whiteBalanceModeBestForExposureMode(exposureMode: object.exposureMode)
+            let currentWhiteBalanceMode = object.whiteBalanceMode
+            
+            if whiteBalanceMode != currentWhiteBalanceMode {
+                do {
+                    try object.lockForConfiguration()
+                    
+                    self.adjustWhiteBalanceForExposureMode(exposureMode: object.exposureMode)
+                    
+                    object.unlockForConfiguration()
+                }
+                catch {
+                    print("NextLevel, failed to lock device for white balance exposure configuration")
+                }
+            }
+            
+            DispatchQueue.main.async {
+                self.flashDelegate?.nextLevelFlashActiveChanged(self)
+            }
         })
         
         self._observers.append(currentDevice.observe(\.isTorchActive, options: [.new]) { (object, change) in
-            self.torchActiveChanged()
+            DispatchQueue.main.async {
+                self.flashDelegate?.nextLevelTorchActiveChanged(self)
+            }
         })
 
         self._observers.append(currentDevice.observe(\.lensPosition, options: [.new]) { (object, change) in

        })
        
        self._observers.append(currentDevice.observe(\.videoZoomFactor, options: [.new]) { (object, change) in
            self.videoZoomFactorChanged()
        })
    }
    

        }
    }
    
    /// Triggers a photo capture from the last video frame.
    public func capturePhotoFromVideo() {
        
