public WebBrowserAssistantEngine(Session session)
        {
            var experiment = _experiment = (WebBrowserAssistantExperiment)session.Experiment;

            _server = new WebBrowserAssistantServer(session);
            _server.AddMessageHandler(this);
            if (!session.StreamerCollection.TryFindFirst(out _gazePointStreamer))
            {
                throw new UserException("Gaze-point streamer not found");
            }
            if (!session.StreamerCollection.TryFindFirst(out _biosignalStreamer))
            {
                throw new UserException("Biosignal streamer not found");
            }
            _gazePointProvider               = new GazePointProvider();
            _dwellTrialController            = new DwellTrialController(session.Clock, _gazePointProvider, experiment.Config.User);
            _dwellTrialController.Triggered += (sender, e) => _trialStartEvent.Set();
            _dwellTrialController.Cancelled += (sender, e) => _trialCancelled.Set();

            _ssvepDetector = new SsvepDetector(session.Clock, 4, Frequencies.Concat(ExtraFrequencies)
                                               .Select(f => new CompositeTemporalPattern <SinusoidalPattern>(new SinusoidalPattern(f))).ToArray(), new[]
            {
                new SsvepDetector.BandpassFilter(12, 90),
                new SsvepDetector.BandpassFilter(24, 90)
            }, new SsvepDetector.FbccaSubBandMixingParams(1.25, 0.25), 2, 0,
                                               experiment.Config.System.Channels.Enumerate(1, _biosignalStreamer.BiosignalSampler.ChannelNum).Select(i => (uint)(i - 1)).ToArray(),
                                               _biosignalStreamer.BiosignalSampler.Frequency, experiment.Config.User.TrialDuration, 0);
        }
        public DwellTrialController(IClock clock, GazePointProvider gazePointProvider,
                                    WebBrowserAssistantExperiment.Configuration.UserConfig userConfig)
        {
            _clock                   = clock;
            _gazePointProvider       = gazePointProvider;
            _cancellable             = userConfig.TrialCancellable;
            _cursorMovementTolerance = userConfig.CursorMovementTolerance;
            _dwellToSelectDelay      = userConfig.DwellSelectionDelay;

            Reset();
        }