/**
   * Sends a request to the client using the given socket and returns the response received via the
   * given reader.
   *
   * @param socket The socket on which the communication will take place.
   * @param reader Reader for the given socket's input stream.
   * @param inputStream the input stream of the given socket
   * @param timeout Maximum time to wait (in milliseconds) for a response.
   * @return the response received from the client, or <code>null</code> if a timeout occurs.
   * @throws IOException from getting (and writing to) the outputstream of the given socket
   */
  public static String requestClientType(
      Socket socket, BufferedReader reader, InputStream inputStream, long timeout)
      throws IOException {
    PrintStream outputStream = new PrintStream(socket.getOutputStream());
    final String request =
        ConnectionState.CLIENT_TYPE_REQUEST
            + ConnectionState.SEPARATOR
            + IVersion.JB_PROTOCOL_MAJOR_VERSION;

    log.debug("sending request: " + request); // $NON-NLS-1$

    outputStream.println(request);
    outputStream.flush();

    if (log.isDebugEnabled()) {
      log.debug(
          "waiting for client type response using timeout: " //$NON-NLS-1$
              + String.valueOf(timeout));
    }

    long waitTime = 0;
    while (waitTime <= timeout) {
      if (inputStream.available() > 0) {
        return reader.readLine();
      }
      waitTime += TimeUtil.delay(TimingConstantsServer.POLLING_DELAY_AUT_REGISTER);
    }

    log.debug("no client type response received from client"); // $NON-NLS-1$
    return null;
  }
  /**
   * Takes a screenshot and saves the image to disk, in JPEG format.
   *
   * @param destination Path and filename for the created image. If the extension is not ".jpeg"
   *     (case-insensitive), ".jpeg" will be appended to the filename.
   * @param delay Amount of time to wait (in milliseconds) before taking the screenshot.
   * @param fileAccess Determines how the file will be created if a file with the given name and
   *     path already exists:<br>
   *     <code>SwingApplicationImplClass.RENAME</code> - The screenshot will be saved with a
   *     sequential integer appended to the filename.<br>
   *     <code>SwingApplicationImplClass.OVERWRITE</code> - The screenshot will overwrite the file.
   * @param scaling Degree to which the image should be scaled, in percent. A <code>scaling</code>
   *     value of <code>100</code> produces an unscaled image. This value must be greater than
   *     <code>0</code> and less than or equal to <code>200</code>.
   * @param createDirs Determines whether a path will be created if it does not already exist. A
   *     value of <code>true</code> means that all necessary directories that do not exist will be
   *     created automatically.
   * @param screenShotRect the rectangle to take the screenshot of
   */
  private void takeScreenshot(
      String destination,
      int delay,
      String fileAccess,
      int scaling,
      boolean createDirs,
      Rectangle screenShotRect) {
    if (scaling <= 0 || scaling > 200) {
      throw new StepExecutionException(
          "Invalid scaling factor: Must be between 1 and 200", //$NON-NLS-1$
          EventFactory.createActionError(TestErrorEvent.INVALID_PARAM_VALUE));
    }

    double scaleFactor = scaling * 0.01;

    // Check if file name is valid
    String outFileName = destination;
    String imageExtension = getExtension(outFileName);
    if (imageExtension.length() == 0) {
      // If not, then we simply append the default extension
      imageExtension = DEFAULT_IMAGE_FORMAT;
      outFileName += EXTENSION_SEPARATOR + imageExtension;
    }

    // Wait for a user-specified time
    if (delay > 0) {
      TimeUtil.delay(delay);
    }

    // Create path, if necessary
    File pic = new File(outFileName);
    if (pic.getParent() == null) {
      throw new StepExecutionException(
          "Invalid file name: specify a file name", //$NON-NLS-1$
          EventFactory.createActionError(TestErrorEvent.INVALID_PARAM_VALUE));
    }

    File path = new File(pic.getParent());
    if (createDirs && !path.exists() && !path.mkdirs()) {
      throw new StepExecutionException(
          "Directory path does not exist and could not be created", //$NON-NLS-1$
          EventFactory.createActionError(TestErrorEvent.FILE_IO_ERROR));
    }

    // Rename file if file already exists
    // FIXME zeb This naming scheme can lead to sorting problems when
    //           filenames have varying numbers of digits (ex. "pic_9" and
    //           "pic_10")
    if (fileAccess.equals(RENAME)) {
      String completeExtension = EXTENSION_SEPARATOR + imageExtension.toLowerCase();
      int extensionIndex = pic.getName().toLowerCase().lastIndexOf(completeExtension);
      String fileName = pic.getName().substring(0, extensionIndex);
      for (int i = 1; pic.exists(); i++) {
        pic = new File(pic.getParent(), fileName + "_" + i + completeExtension); // $NON-NLS-1$
      }
    }

    takeScreenshot(screenShotRect, scaleFactor, pic);
  }
 /**
  * Waits a specified time.
  *
  * @param timeMilliSec the time to wait in MilliSec
  */
 public void rcWait(int timeMilliSec) {
   TimeUtil.delay(timeMilliSec);
 }