     open func seek(timeInterval: TimeInterval) {
         playback?.seek(timeInterval)
     }
-
-    private func loadPlugins() {
+    
+    fileprivate func loadPlugins() {
         for type in loader.containerPlugins {
             addPlugin(type.init(context: self) as! UIContainerPlugin)
         }

        
        let playbackFactory = PlaybackFactory(loader: loader, options: playbackOptions)
        
        playback?.removeFromSuperview()
        playback = playbackFactory.createPlayback()
        renderPlayback()
        trigger(ContainerEvent.sourceChanged)
    }
    
    open override func render() {
        plugins.forEach(renderPlugin)
        renderPlayback()
    }

    fileprivate func renderPlayback() {
        guard let playback = playback else {
            return
        }

        addSubviewMatchingConstraints(playback)
        playback.render()
        sendSubview(toBack: playback)

            .bufferUpdate         : { [weak self] (info: EventUserInfo) in self?.forward(.progress, userInfo:info)} as EventCallback,
            .positionUpdate       : { [weak self] (info: EventUserInfo) in self?.forward(.timeUpdated, userInfo:info)} as EventCallback,
            .didUpdateSubtitleSource : { [weak self] (info: EventUserInfo) in self?.forward(.subtitleSourcesUpdated, userInfo:info)} as EventCallback,
            .didUpdateAudioSource : { [weak self] (info: EventUserInfo) in self?.forward(.audioSourcesUpdated, userInfo:info)} as EventCallback
        ]
    }
    
    fileprivate func onPlay() {
        if buffering {
            buffering = false
            trigger(.bufferFull)
        }
        
        options[kStartAt] = 0.0
        trigger(.play)
    }
    
    fileprivate func setReady() {
        ready = true
        trigger(ContainerEvent.ready)
    }
    
    fileprivate func trigger(_ event: ContainerEvent) {
        trigger(event.rawValue)
    }
