/**
   * Retrieve
   *
   * @throws IOException
   * @throws IllegalArgumentException
   * @throws NoSuchProviderException
   * @throws NoSuchAlgorithmException
   */
  private long computeAndReturnTime(
      long remainTime, List<Entity> works, List<PlayWorkBean> playWorks)
      throws NoSuchAlgorithmException, NoSuchProviderException, IllegalArgumentException,
          IOException {

    int sortedSize = works.size();

    // randomize for getting work in the list
    int randomId = Random.getInstance().getNumericRandomInt(sortedSize);
    // get work
    Entity currentWork = works.remove(randomId);
    long randomWorkTime = 0;
    // music case
    if (WorkTypeEnum.MUSIC.name().equals(currentWork.getProperty("type"))) {
      Long musicTime = (Long) currentWork.getProperty("time");
      randomWorkTime = musicTime.longValue();
    } else {
      // randomize for work time displaying
      randomWorkTime = minWorkTime + Random.getInstance().getNumericRandomInt(maxWorkTime);
    }
    // avoid randomWorkTime to be superior at remain time
    if (remainTime < randomWorkTime) {
      randomWorkTime = remainTime;
    }

    playWorks.add(new PlayWorkBean(Long.valueOf(randomWorkTime), currentWork.getKey()));

    return randomWorkTime;
  }
  /**
   * Searches for the entity based on the search criteria and returns the token linked to the
   * result.
   */
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws ServletException, IOException {

    super.doGet(req, resp);

    String token = null;

    Iterable<Entity> iterable = Work.getAllWorks();

    Iterator<Entity> iter = iterable.iterator();

    List<Entity> sortedList = new LinkedList<Entity>();

    while (iter.hasNext()) {
      sortedList.add(iter.next());
    }

    if (!sortedList.isEmpty()) {

      long rightTime = sequenceTime; // in ms
      int rightId = 0;
      List<PlayWorkBean> rightFragment = new LinkedList<PlayWorkBean>();

      long leftTime = sequenceTime; // in ms
      int leftId = 0;
      List<PlayWorkBean> leftFragment = new LinkedList<PlayWorkBean>();

      try {

        // init sequence token
        token = Random.getInstance().getUniqueSessionId();
        logger.log(Level.INFO, "Generating a new Optimized Sequence with token[" + token + "]");

        while ((leftTime > 0 || rightTime > 0) && sortedList.size() > 1) {

          if (rightTime > 0) {
            rightTime = rightTime - computeAndReturnTime(rightTime, sortedList, rightFragment);
            if ((rightFragment.size() % Fragment.fragmentMaxSize)
                == 0) { // save the Fragment of fragmentMaxSize size
              saveFragment(token, rightId, DisplayTypeEnum.R, rightFragment);
              rightFragment = new LinkedList<PlayWorkBean>();
              rightId++;
            }
          }

          if (leftTime > 0) {
            leftTime = leftTime - computeAndReturnTime(leftTime, sortedList, leftFragment);
            if ((leftFragment.size() % Fragment.fragmentMaxSize)
                == 0) { // save the Fragment of fragmentMaxSize size
              saveFragment(token, leftId, DisplayTypeEnum.L, leftFragment);
              leftFragment = new LinkedList<PlayWorkBean>();
              leftId++;
            }
          }
        }

        // save right and left fragment without a complete fragmentMaxSize size
        if (!rightFragment.isEmpty())
          saveFragment(token, rightId, DisplayTypeEnum.R, rightFragment);
        if (!leftFragment.isEmpty()) saveFragment(token, leftId, DisplayTypeEnum.L, leftFragment);

      } catch (NoSuchAlgorithmException e) {
        logger.log(Level.WARNING, e.getMessage());
      } catch (NoSuchProviderException e) {
        logger.log(Level.WARNING, e.getMessage());
      } catch (IllegalArgumentException e) {
        logger.log(Level.WARNING, e.getMessage());
      } catch (IOException e) {
        logger.log(Level.WARNING, e.getMessage());
      }

      PrintWriter out = resp.getWriter();
      out.println(token);
      return;
    }

    return;
  }