public static void removeInternalEventListenerJoystick(
      ItsNatCompNormalEventListenersJoystick listeners,
      ClientDocumentImpl clientDoc,
      String type,
      boolean useCapture,
      boolean updateClient) {
    ItsNatDocumentImpl itsNatDoc = listeners.getItsNatDocumentImpl();
    if (itsNatDoc.isLoadingPhaseAndFastLoadMode()) {
      EventListener listener = listeners.getLoadScheduledMap().remove(type + "_" + useCapture);
      Document doc = itsNatDoc.getDocument();

      Browser browser = clientDoc.getBrowser();
      EventTarget target;
      String eventType;
      if (!(browser instanceof BrowserSVGPlugin)) {
        target = (EventTarget) ((DocumentView) doc).getDefaultView();
        eventType = "load";
      } else {
        target = (EventTarget) doc.getDocumentElement();
        eventType = "SVGLoad";
      }

      clientDoc.removeEventListener(target, eventType, listener, false);
    } else {
      removeInternalEventListenerJoystick2(listeners, clientDoc, type, useCapture, updateClient);
    }
  }
  public static void addInternalEventListenerJoystick(
      final ItsNatCompNormalEventListenersJoystick listeners,
      final ClientDocumentImpl clientDoc,
      final String type,
      final boolean useCapture,
      final int commMode,
      final ParamTransport[] extraParams,
      final String preSendCode,
      final long eventTimeout,
      final String bindToCustomFunc) {
    ItsNatDocumentImpl itsNatDoc = listeners.getItsNatDocumentImpl();
    if (itsNatDoc.isLoadingPhaseAndFastLoadMode()) {
      // En tiempo de carga en modo fast load el acceso a nodos no tolera cambios en el DOM de
      // elementos eliminados/cambiados de posición
      // y eso puede ocurrir mientras se construye la lista
      // Tenemos que delegar el proceso a después de la carga
      EventListener listener =
          new EventListenerSerializableInternal() {
            @Override
            public void handleEvent(Event evt) {
              addInternalEventListenerJoystick2(
                  listeners,
                  clientDoc,
                  type,
                  useCapture,
                  commMode,
                  extraParams,
                  preSendCode,
                  eventTimeout,
                  bindToCustomFunc);
            }
          };
      Document doc = itsNatDoc.getDocument();

      Browser browser = clientDoc.getBrowser();
      EventTarget target;
      String eventType;
      if (!(browser instanceof BrowserSVGPlugin)) {
        target = (EventTarget) ((DocumentView) doc).getDefaultView();
        eventType = "load";
      } else {
        target = (EventTarget) doc.getDocumentElement();
        eventType = "SVGLoad";
      }
      clientDoc.addEventListener(target, eventType, listener, false);
      listeners.getLoadScheduledMap().put(type + "_" + useCapture, listener);
    } else {
      addInternalEventListenerJoystick2(
          listeners,
          clientDoc,
          type,
          useCapture,
          commMode,
          extraParams,
          preSendCode,
          eventTimeout,
          bindToCustomFunc);
    }
  }
  public static void addInternalEventListenerJoystick(
      ItsNatCompNormalEventListenersJoystick listeners,
      ClientDocumentImpl clientDoc,
      Element contentElem,
      String type) {
    if (contentElem == null) return;

    ItsNatCompNormalEventListenersImpl listenersBase =
        (ItsNatCompNormalEventListenersImpl) listeners;

    EventListenerParamsImpl params = listenersBase.getEventListenerParams(type);

    boolean useCapture = listenersBase.isUseCapture(params);
    int commMode = listenersBase.getCommModeDeclared(params);
    String preSendCode = listenersBase.getPreSendCode(params);
    long eventTimeout = listenersBase.getEventTimeout(params);
    String bindToCustomFunc = listenersBase.getBindToCustomFunc(params);

    ParamTransport[] extraParams = listenersBase.getParamTransports(type, params, clientDoc);

    clientDoc.addEventListener(
        (EventTarget) contentElem,
        type,
        listenersBase.getItsNatComponent(),
        useCapture,
        commMode,
        extraParams,
        preSendCode,
        eventTimeout,
        bindToCustomFunc);
  }
  public static void addInternalEventListenerJoystick2(
      ItsNatCompNormalEventListenersJoystick listeners,
      ClientDocumentImpl clientDoc,
      String type,
      boolean useCapture,
      int commMode,
      ParamTransport[] extraParams,
      String preSendCode,
      long eventTimeout,
      String bindToCustomFunc) {
    JoystickModeComponent comp = listeners.getJoystickModeComponent();
    Element[] elemList = comp.getContentElementList();

    for (int i = 0; i < elemList.length; i++) {
      Element contentElem = elemList[i];
      if (contentElem == null) continue;
      if (DOMUtilInternal.isNodeBoundToDocumentTree(
          contentElem)) // Esta comprobación es simplemente para que funcione el ejemplo del "Table
        // using Row Span" del Feat. Show. quizás valga para casos especiales del
        // usuario.
        clientDoc.addEventListener(
            (EventTarget) contentElem,
            type,
            (ItsNatComponentImpl) comp,
            useCapture,
            commMode,
            extraParams,
            preSendCode,
            eventTimeout,
            bindToCustomFunc);
    }
  }
  public static void removeInternalEventListenerJoystick(
      ItsNatCompNormalEventListenersJoystick listeners,
      ClientDocumentImpl clientDoc,
      Element contentElem,
      String type) {
    if (contentElem == null) return;

    ItsNatCompNormalEventListenersImpl listenersBase =
        (ItsNatCompNormalEventListenersImpl) listeners;

    EventListenerParamsImpl params = listenersBase.getEventListenerParams(type);
    boolean useCapture = listenersBase.isUseCapture(params);

    clientDoc.removeEventListener(
        (EventTarget) contentElem, type, listenersBase.getItsNatComponent(), useCapture);
  }
  public static void removeInternalEventListenerJoystick2(
      ItsNatCompNormalEventListenersJoystick listeners,
      ClientDocumentImpl clientDoc,
      String type,
      boolean useCapture,
      boolean updateClient) {
    JoystickModeComponent comp = listeners.getJoystickModeComponent();
    Element[] elemList = comp.getContentElementList();

    for (int i = 0; i < elemList.length; i++) {
      Element contentElem = elemList[i];
      if (contentElem == null) continue;
      if (DOMUtilInternal.isNodeBoundToDocumentTree(
          contentElem)) // Esta comprobación es simplemente para que funcione el ejemplo del "Table
        // using Row Span" del Feat. Show. quizás valga para casos especiales del
        // usuario.
        clientDoc.removeEventListener(
            (EventTarget) contentElem, type, (ItsNatComponentImpl) comp, useCapture);
    }
  }