// ----------------------------------------------------------------------------------------------------
  protected synchronized void taskDone(ParserTask task) {

    // Solo hace algo si la tarea finalizada era del trabajo en curso y no una antigua
    if (task.jobID.equals(getCurrentJobID())) {

      // Crea el status
      ParserWorkerStatus pws = new ParserWorkerStatus();
      pws.hotelDataList = task.hotelDataList;

      // Decrementa el numero de tareas en ejecucion
      m_numTasksForJob--;

      // Actua dependiendo de lo que quede
      if (m_numTasksForJob > 0) {

        // **** AVISAR DE QUE SE HA TERMINADO CON UNA DE LAS PAGINAS
        pws.type = PWStatusType.PageEnded;
        m_monitor.processingEnded(false, pws);

      } else if (m_numTasksForJob == 0) {

        // **** AVISAR DE QUE SE HA TERMINADO CON TODAS LAS PAGINAS
        Tracer._info("***** All parsing tasks have ended *********************************");
        pws.type = PWStatusType.AllPagesEnded;
        m_monitor.processingEnded(false, pws);

      } else {
        // No debería salir una cuenta negativa
        String MSG = "Task count for job decremented below zero";
        Tracer._error(MSG);
        m_monitor.processingEnded(true, MSG);
      }
    }
  }
  private void _initFields() throws Exception {

    m_tracer = new TabbedTracerImpl(m_debugTabItem, m_infoTabItem, m_warnTabItem, m_errorTabItem);
    Tracer.setTracer(m_tracer);
    m_monitor = new ProgressMonitor();
    m_txtWKSPFolder.setText(s_prefs.getPref("WKSPFolder", ""));
    m_txtStorageFile.setText(s_prefs.getPref("StorageFile", ""));
  }
  // ----------------------------------------------------------------------------------------------------
  protected synchronized ParserTask getNextTask() {

    // Espera a tener una tarea para el JobID en curso
    // Se descartan tareas con JobIDs diferentes
    for (; ; ) {

      if (m_tasksQueue.isEmpty()) {
        try {
          this.wait();
        } catch (InterruptedException ex) {
          Tracer._warn("Error waiting for a new ParserTask in queue", ex);
        }
      } else {
        ParserTask task = m_tasksQueue.poll();
        if (task != null && task.jobID.equals(getCurrentJobID())) {
          return task;
        } else {
          Tracer._debug("Discarding task from previous job");
        }
      }
    }
  }
  // ----------------------------------------------------------------------------------------------------
  public static void str_to_minRoomCapacities(String str) {

    minRoomCapacities.clear();

    StringTokenizer st = new StringTokenizer(str, ",");
    while (st.hasMoreTokens()) {
      String token = st.nextToken();
      try {
        token = token.trim();
        int v = Integer.parseInt(token);
        minRoomCapacities.add(v);
      } catch (Throwable th) {
        Tracer._warn("Error parsing capacity value:" + token, th);
      }
    }
  }
  // ----------------------------------------------------------------------------------------------------
  public synchronized void parseHtmlText(final String baseURL, final String htmlText) {

    // Si es la primera tarea del trabajo, actualiza el contador
    if (m_numTasksForJob == 0) {
      m_numTasksForJob++;
    }

    ParserTask task = new ParserTask();
    task.jobID = getCurrentJobID();
    task.htmlText = htmlText;
    task.baseURL = baseURL;
    try {
      m_tasksQueue.add(task);
      this.notifyAll();
    } catch (Exception ex) {
      Tracer._error("Error putting a new ParserTask in the queue", ex);
    }
  }
 // ----------------------------------------------------------------------------------------------------
 public synchronized void reset() {
   Tracer._info("***** Reset parsing JOB ****************************************************");
   Tracer._info("");
   m_numTasksForJob = 0;
   createNewJobID();
 }
 private void _executionStarted() {
   Tracer.reset();
   _disableButtons();
 }
  /** Create contents of the window */
  protected void createContents() {

    m_shell = new Shell();

    m_shell.setImage(SWTResourceManager.getImage(IPAToolAppWnd.class, "/Properties.ico"));
    final BorderLayout borderLayout = new BorderLayout(0, 0);
    borderLayout.setVgap(5);
    m_shell.setLayout(borderLayout);
    m_shell.setSize(800, 400);
    m_shell.setMinimumSize(new Point(800, 400));
    m_shell.setText("IPATool2");

    Composite composite;
    composite = new Composite(m_shell, SWT.NONE);
    {
      TabFolder tabFolder = new TabFolder(composite, SWT.NONE);
      tabFolder.setBounds(10, 10, 748, 200);

      {
        TabItem tbtmTools = new TabItem(tabFolder, SWT.NONE);
        tbtmTools.setText("Tools");

        Composite composite_1 = new Composite(tabFolder, SWT.NONE);
        tbtmTools.setControl(composite_1);

        m_txtUpdFolder = new Text(composite_1, SWT.BORDER);
        m_txtUpdFolder.setText("");
        m_txtUpdFolder.setBounds(122, 14, 564, 21);

        Button btnUpdFolder = new Button(composite_1, SWT.NONE);
        btnUpdFolder.addSelectionListener(
            new SelectionAdapter() {

              @Override
              public void widgetSelected(SelectionEvent e) {
                _selectFolder(m_txtUpdFolder);
              }
            });
        btnUpdFolder.setText("...");
        btnUpdFolder.setBounds(692, 12, 38, 25);

        m_txtExistingFolder = new Text(composite_1, SWT.BORDER);
        m_txtExistingFolder.setText("");
        m_txtExistingFolder.setBounds(122, 45, 564, 21);

        Button btnExFolder = new Button(composite_1, SWT.NONE);
        btnExFolder.addSelectionListener(
            new SelectionAdapter() {

              @Override
              public void widgetSelected(SelectionEvent e) {
                _selectFolder(m_txtExistingFolder);
              }
            });
        btnExFolder.setText("...");
        btnExFolder.setBounds(692, 43, 38, 25);

        m_txtITunesFolder = new Text(composite_1, SWT.BORDER);
        m_txtITunesFolder.setText("");
        m_txtITunesFolder.setBounds(122, 76, 564, 21);

        Button btnitunesFolder = new Button(composite_1, SWT.NONE);
        btnitunesFolder.addSelectionListener(
            new SelectionAdapter() {

              @Override
              public void widgetSelected(SelectionEvent e) {
                _selectFolder(m_txtITunesFolder);
              }
            });
        btnitunesFolder.setText("...");
        btnitunesFolder.setBounds(692, 74, 38, 25);

        m_lbliTunes = new Label(composite_1, SWT.NONE);
        m_lbliTunes.setText("iTunes IPAs Folder:");
        m_lbliTunes.setBounds(10, 79, 119, 15);

        m_lblExFolder = new Label(composite_1, SWT.NONE);
        m_lblExFolder.setText("Current IPAs Folder:");
        m_lblExFolder.setBounds(10, 48, 119, 15);

        Label lblUpdFolder = new Label(composite_1, SWT.NONE);
        lblUpdFolder.setFont(SWTResourceManager.getFont("Segoe UI", 9, SWT.BOLD));
        lblUpdFolder.setForeground(SWTResourceManager.getColor(SWT.COLOR_RED));
        lblUpdFolder.setText(" IPAs Folder:");
        lblUpdFolder.setBounds(10, 17, 119, 15);
        {
          m_chkRecurseFolders = new Button(composite_1, SWT.CHECK);
          m_chkRecurseFolders.addSelectionListener(
              new SelectionAdapter() {

                @Override
                public void widgetSelected(SelectionEvent e) {}
              });
          m_chkRecurseFolders.setLocation(122, 103);
          m_chkRecurseFolders.setSize(107, 16);
          m_chkRecurseFolders.setSelection(true);
          m_chkRecurseFolders.setText("Recurse folders");
        }
        {
          m_btnRenameIPAs = new Button(composite_1, SWT.NONE);
          m_btnRenameIPAs.setBackground(SWTResourceManager.getColor(SWT.COLOR_RED));
          m_btnRenameIPAs.setLocation(120, 137);
          m_btnRenameIPAs.setSize(94, 25);
          m_btnRenameIPAs.addSelectionListener(
              new SelectionAdapter() {

                @Override
                public void widgetSelected(SelectionEvent e) {
                  renameIPAs();
                }
              });
          m_btnRenameIPAs.setText("Rename IPAs");
        }

        m_btnUpdateIPAs = new Button(composite_1, SWT.NONE);
        m_btnUpdateIPAs.addSelectionListener(
            new SelectionAdapter() {

              @Override
              public void widgetSelected(SelectionEvent e) {
                updateIPAs();
              }
            });
        m_btnUpdateIPAs.setBounds(216, 137, 94, 25);
        m_btnUpdateIPAs.setText("Update IPAs");

        m_chkUseAllFolders = new Button(composite_1, SWT.CHECK);
        m_chkUseAllFolders.addSelectionListener(
            new SelectionAdapter() {

              @Override
              public void widgetSelected(SelectionEvent e) {
                if (m_chkUseAllFolders.getSelection()) {
                  m_lblExFolder.setForeground(SWTResourceManager.getColor(SWT.COLOR_RED));
                  m_lbliTunes.setForeground(SWTResourceManager.getColor(SWT.COLOR_RED));
                } else {
                  m_lblExFolder.setForeground(null);
                  m_lbliTunes.setForeground(null);
                }
              }
            });
        m_chkUseAllFolders.setBounds(244, 103, 107, 16);
        m_chkUseAllFolders.setText("Use all folders");

        m_btnCleanJPGs = new Button(composite_1, SWT.NONE);
        m_btnCleanJPGs.setBackground(SWTResourceManager.getColor(SWT.COLOR_RED));
        m_btnCleanJPGs.setBounds(310, 137, 94, 25);
        m_btnCleanJPGs.addSelectionListener(
            new SelectionAdapter() {

              @Override
              public void widgetSelected(SelectionEvent e) {
                cleanJPEGs();
              }
            });
        m_btnCleanJPGs.setText("Clean JPEGs");
      }

      TabItem tbtmCheckIPAs = new TabItem(tabFolder, SWT.NONE);
      tbtmCheckIPAs.setText("Check");

      Composite composite_1 = new Composite(tabFolder, SWT.NONE);
      tbtmCheckIPAs.setControl(composite_1);

      m_txtIPhoneFolder = new Text(composite_1, SWT.BORDER);
      m_txtIPhoneFolder.setText("");
      m_txtIPhoneFolder.setBounds(122, 14, 564, 21);

      Button btnIPhoneFolder = new Button(composite_1, SWT.NONE);
      btnIPhoneFolder.addSelectionListener(
          new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {
              _selectFolder(m_txtIPhoneFolder);
            }
          });
      btnIPhoneFolder.setText("...");
      btnIPhoneFolder.setBounds(692, 12, 38, 25);

      m_txtIPadFolder = new Text(composite_1, SWT.BORDER);
      m_txtIPadFolder.setText("");
      m_txtIPadFolder.setBounds(122, 45, 564, 21);

      Button btnIPadFolder = new Button(composite_1, SWT.NONE);
      btnIPadFolder.addSelectionListener(
          new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {
              _selectFolder(m_txtIPadFolder);
            }
          });
      btnIPadFolder.setText("...");
      btnIPadFolder.setBounds(692, 43, 38, 25);

      m_txtMixedFolder = new Text(composite_1, SWT.BORDER);
      m_txtMixedFolder.setText("");
      m_txtMixedFolder.setBounds(122, 76, 564, 21);

      Button btnMixedFolder = new Button(composite_1, SWT.NONE);
      btnMixedFolder.addSelectionListener(
          new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {
              _selectFolder(m_txtMixedFolder);
            }
          });
      btnMixedFolder.setText("...");
      btnMixedFolder.setBounds(692, 74, 38, 25);

      Label lblBothIpasFolder = new Label(composite_1, SWT.NONE);
      lblBothIpasFolder.setText("mixed Folder:");
      lblBothIpasFolder.setBounds(10, 79, 119, 15);

      Label lblIpadIpasFolder = new Label(composite_1, SWT.NONE);
      lblIpadIpasFolder.setText("iPad Folder:");
      lblIpadIpasFolder.setBounds(10, 48, 119, 15);

      Label lblIphoneFolder = new Label(composite_1, SWT.NONE);
      lblIphoneFolder.setText("iPhone Folder:");
      lblIphoneFolder.setBounds(10, 17, 119, 15);

      m_btnCheck = new Button(composite_1, SWT.NONE);
      m_btnCheck.addSelectionListener(
          new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {
              checkIPAs();
            }
          });
      m_btnCheck.setText("Check IPAs");
      m_btnCheck.setBounds(122, 122, 90, 25);
    }
    composite.setLayoutData(BorderLayout.NORTH);

    final Label lblX = new Label(composite, SWT.NONE);
    lblX.setBounds(10, 10, 14, 211);
    final TabFolder m_tabTraces = new TabFolder(m_shell, SWT.NONE);
    m_tabTraces.setLayoutData(BorderLayout.CENTER);

    final Composite composite_1 = new Composite(m_shell, SWT.NONE);
    composite_1.setLayout(new BorderLayout(0, 0));
    composite_1.setLayoutData(BorderLayout.CENTER);

    // ------------------------------------------------------------------------
    // ********** TabbedTracer ***********************************************
    final CTabFolder tabTraces = m_tabbedTracer.createTabFolder(composite_1);
    tabTraces.setLayoutData(BorderLayout.CENTER);
    Tracer.setTracer(m_tabbedTracer);
  }