public JSRedirectWindowController(UserRequest ureq) {
    Translator trans =
        Util.createPackageTranslator(JSRedirectWindowController.class, ureq.getLocale());
    VelocityContainer msg =
        new VelocityContainer("jsredirect", VELOCITY_ROOT + "/js_redirect.html", trans, this);

    String callbackUrl = Settings.getServerContextPathURI() + OAuthConstants.CALLBACK_PATH;
    msg.contextPut("callbackUrl", callbackUrl);

    Windows ws = Windows.getWindows(ureq);
    WindowBackOffice wbo =
        ws.getWindowManager()
            .createWindowBackOffice("jsredirectwindow", this, new WindowSettings());
    Window w = wbo.getWindow();
    msg.contextPut("theme", w.getGuiTheme());
    w.setContentPane(msg);
    setWindow(w);
  }
  /**
   * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest,
   *     org.olat.core.gui.components.Component, org.olat.core.gui.control.Event)
   */
  @Override
  public void event(UserRequest ureq, Component source, Event event) {
    if (source == onCommand) {
      // toggle on
      Preferences prefs = ureq.getUserSession().getGuiPreferences();
      prefs.put(CourseGlossaryToolLinkController.class, guiPrefsKey, Boolean.TRUE);
      prefs.save();
      // update gui
      mainVC.remove(onCommand);
      offCommand = LinkFactory.createLink("command.glossary.off", mainVC, this);
      offCommand.setTitle("command.glossary.off.alt");
      offCommand.setCustomEnabledLinkCSS("b_toolbox_toggle");
      // notify textmarker controller
      glossMarkupItmCtr.setTextMarkingEnabled(true);
      fireEvent(ureq, new Event("glossaryOn"));

    } else if (source == offCommand) {
      // toggle off
      Preferences prefs = ureq.getUserSession().getGuiPreferences();
      prefs.put(CourseGlossaryToolLinkController.class, guiPrefsKey, Boolean.FALSE);
      prefs.save();
      // update gui
      mainVC.remove(offCommand);
      onCommand = LinkFactory.createLink("command.glossary.on", mainVC, this);
      onCommand.setTitle("command.glossary.on.alt");
      onCommand.setCustomEnabledLinkCSS("b_toolbox_toggle");
      // notify textmarker controller
      glossMarkupItmCtr.setTextMarkingEnabled(false);
      fireEvent(ureq, new Event("glossaryOff"));
    } else if (source == mainVC && event.getCommand().equals("command.glossary")) {
      // start glossary in window
      final CourseConfig cc = courseEnvir.getCourseConfig(); // do not cache cc, not save

      // if glossary had been opened from LR as Tab before, warn user:
      DTabs dts = Windows.getWindows(ureq).getWindow(ureq).getDTabs();
      RepositoryEntry repoEntry =
          RepositoryManager.getInstance()
              .lookupRepositoryEntryBySoftkey(cc.getGlossarySoftKey(), false);
      DTab dt = dts.getDTab(repoEntry.getOlatResource());
      if (dt != null) {
        List<ContextEntry> entries =
            BusinessControlFactory.getInstance()
                .createCEListFromResourceType(allowGlossaryEditing ? "true" : "false");
        dts.activate(ureq, dt, entries);
      } else {
        ControllerCreator ctrlCreator =
            new ControllerCreator() {
              public Controller createController(UserRequest lureq, WindowControl lwControl) {
                GlossaryMainController glossaryController =
                    CourseGlossaryFactory.createCourseGlossaryMainRunController(
                        lwControl, lureq, cc, allowGlossaryEditing);
                listenTo(glossaryController);
                if (glossaryController == null) {
                  // happens in the unlikely event of a user who is in a course and
                  // now
                  // tries to access the glossary
                  String text = translate("error.noglossary");
                  return MessageUIFactory.createInfoMessage(lureq, lwControl, null, text);
                } else {
                  // use a one-column main layout
                  LayoutMain3ColsController layoutCtr =
                      new LayoutMain3ColsController(
                          lureq,
                          lwControl,
                          null,
                          null,
                          glossaryController.getInitialComponent(),
                          null);
                  // dispose glossary on layout dispose
                  layoutCtr.addDisposableChildController(glossaryController);
                  return layoutCtr;
                }
              }
            };

        ControllerCreator layoutCtrlr =
            BaseFullWebappPopupLayoutFactory.createAuthMinimalPopupLayout(ureq, ctrlCreator);
        // open in new browser window
        openInNewBrowserWindow(ureq, layoutCtrlr);
        return; // immediate return after opening new browser window!
      }
    }
  }
  /**
   * @see org.olat.core.dispatcher.Dispatcher#execute(javax.servlet.http.HttpServletRequest,
   *     javax.servlet.http.HttpServletResponse, java.lang.String)
   */
  @Override
  public void execute(HttpServletRequest request, HttpServletResponse response) {
    UserRequest ureq = null;

    try {
      String uriPrefix = DispatcherModule.getLegacyUriPrefix(request);
      ureq = new UserRequestImpl(uriPrefix, request, response);
      if (!ContextHelpModule.isContextHelpEnabled()) {
        // disabled context help - redirect immediately
        DispatcherModule.sendNotFound(ureq.getNonParsedUri(), response);
        return;
      }

      ChiefController cc =
          (ChiefController)
              Windows.getWindows(ureq.getUserSession()).getAttribute(CONTEXTHELPCHIEFCONTROLLER);
      // reuse existing chief controller for this user
      if (cc != null) {
        Window currentWindow = cc.getWindow();
        // Check if this is a start URL or a framework URL
        if (ureq.isValidDispatchURI()) {
          // A standard framework request, dispatch by component
          currentWindow.dispatchRequest(ureq, false);
          return;
        } else {
          // If path contains complete URL, dispose and start from scratch
          Windows.getWindows(ureq).deregisterWindow(currentWindow);
          cc.dispose();
        }
      }

      // Creator code to create
      // 1) the chief controller
      // 2) the layout controller
      // 3) the context help main controller
      ControllerCreator cHelpPopupWindowControllerCreator =
          new ControllerCreator() {
            public Controller createController(UserRequest lureq, WindowControl lwControl) {
              ControllerCreator cHelpMainControllerCreator =
                  new ControllerCreator() {
                    public Controller createController(UserRequest lureq, WindowControl lwControl) {
                      // create the context help controller and wrapp it using the layout controller
                      ContextHelpMainController helpCtr =
                          new ContextHelpMainController(lureq, lwControl);
                      LayoutMain3ColsController layoutCtr =
                          new LayoutMain3ColsController(
                              lureq, lwControl, null, null, helpCtr.getInitialComponent(), null);
                      layoutCtr.addDisposableChildController(helpCtr);
                      return layoutCtr;
                    }
                  };
              ContextHelpLayoutControllerCreator cHelpPopupLayoutCreator =
                  new ContextHelpLayoutControllerCreator(cHelpMainControllerCreator);
              return new BaseFullWebappPopupBrowserWindow(
                  lureq, lwControl, cHelpPopupLayoutCreator.getFullWebappParts());
            }
          };

      BaseChiefControllerCreator bbc = new BaseChiefControllerCreator();
      bbc.setContentControllerCreator(cHelpPopupWindowControllerCreator);
      cc = bbc.createChiefController(ureq);
      // add to user session for cleanup on user logout
      Windows.getWindows(ureq.getUserSession()).setAttribute(CONTEXTHELPCHIEFCONTROLLER, cc);
      Window currentWindow = cc.getWindow();
      currentWindow.setUriPrefix(WebappHelper.getServletContextPath() + PATH_CHELP);
      Windows.getWindows(ureq).registerWindow(currentWindow);
      // finally dispatch the initial request
      currentWindow.dispatchRequest(ureq, true);

    } catch (Throwable th) {
      try {
        ChiefController msgcc = MsgFactory.createMessageChiefController(ureq, th);
        // the controller's window must be failsafe also
        msgcc.getWindow().dispatchRequest(ureq, true);
        // do not dispatch (render only), since this is a new Window created as
        // a result of another window's click.
      } catch (Throwable t) {
        logError("Sorry, can't handle this context help request....", t);
      }
    }
  }