public void setcs(String viewName, String configSpec) throws IOException, InterruptedException {
    FilePath workspace = launcher.getWorkspace();
    FilePath configSpecFile = workspace.createTextTempFile("configspec", ".txt", configSpec);
    String configSpecLocation = ".." + File.separatorChar + configSpecFile.getName();
    configSpecLocation = PathUtil.convertPathForOS(configSpecLocation, launcher.getLauncher());

    // cleartool setcs <configspec>
    ArgumentListBuilder cmd = new ArgumentListBuilder();
    cmd.add("setcs");
    cmd.add("-tag");
    cmd.add(viewName);
    cmd.add(configSpecLocation);

    // run the cleartool command
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    launcher.run(cmd.toCommandArray(), null, baos, workspace.child(viewName));
    String cleartoolOutput = ClearCaseUcmBaselineUtils.processCleartoolOuput(baos);
    baos.close();

    configSpecFile.delete();

    // ensure no error has occured
    if (cleartoolOutput.contains("cleartool: Error")) {
      launcher.getListener().error("Failed to set the config spec of the view " + viewName + ".");
      throw new IOException(
          "Failed to set the config spec of the view " + viewName + ": " + cleartoolOutput);
    }
  }
  public void mkview(
      String viewName, String mkviewOptionalParam, boolean snapshotView, String streamSelector)
      throws IOException, InterruptedException {
    // cleartool mkview -tag <tag> <view path> <optional parameters>
    ArgumentListBuilder cmd = new ArgumentListBuilder();
    cmd.add("mkview");
    if (snapshotView) {
      cmd.add("-snapshot");
    }
    cmd.add("-tag");
    cmd.add(viewName); // let's save user config stuff: we reuse the view name as the tag name

    // HUDSON-6409
    if (StringUtils.isNotBlank(mkviewOptionalParam)) {
      cmd.addTokenized(Util.replaceMacro(mkviewOptionalParam, variableResolver));
    }

    cmd.add(viewName);

    // run the cleartool command
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    launcher.run(cmd.toCommandArray(), null, baos, null);
    String cleartoolOutput = ClearCaseUcmBaselineUtils.processCleartoolOuput(baos);
    baos.close();

    // ensure no error has occured
    if (cleartoolOutput.contains("cleartool: Error")) {
      launcher.getListener().error("Failed to create view " + viewName + ".");
      throw new IOException("Failed to create view " + viewName + ": " + cleartoolOutput);
    }
  }
  @Override
  public void rmview(String viewName) throws IOException, InterruptedException {
    // cleartool rmview -force <view name>
    ArgumentListBuilder cmd = new ArgumentListBuilder();
    cmd.add("rmview");
    cmd.add("-force");
    cmd.add(viewName);

    // run the cleartool command
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    launcher.run(cmd.toCommandArray(), null, baos, null);
    String cleartoolOutput = ClearCaseUcmBaselineUtils.processCleartoolOuput(baos);
    baos.close();

    // ensure no error has occured
    if (cleartoolOutput.contains("cleartool: Error")) {
      launcher.getListener().error("Failed to remove view " + viewName + ".");
      throw new IOException("Failed to remove view " + viewName + ": " + cleartoolOutput);
    }

    // manually delete the view folder if cleartool rmview didn't actually remove it
    FilePath viewFilePath = launcher.getWorkspace().child(viewName);
    if (viewFilePath.exists()) {
      launcher
          .getListener()
          .getLogger()
          .println(
              "View folder was not actually removed by \"cleartool rmview\"; Removing it now...");
      viewFilePath.deleteRecursive();
    }
  }
  /**
   * Returns, for a given ClearCase UCM composite baseline, all the baselines in the dependencies
   * graph.
   *
   * @return An array of ClearCase UCM baseline selectors (it may be empty)
   * @see ftp://ftp.software.ibm.com/software/rational/docs/v2002/cc/cc_ref_1.pdf
   *     (%[depends_on_closure]p, page 392)
   */
  public String[] getDependentBaselines(String pvob, String baseline)
      throws IOException, InterruptedException {
    String baselineSelector = baseline + '@' + pvob;

    if (dependentBaselinesCache.containsKey(baselineSelector)) {
      return dependentBaselinesCache.get(baselineSelector);
    }

    String[] dependentBaselines = null;

    ArgumentListBuilder cmd = new ArgumentListBuilder();
    cmd.clear();
    cmd.add("lsbl");
    cmd.add("-fmt");
    cmd.add("%[depends_on_closure]p");
    cmd.add(baselineSelector);

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    launcher.run(cmd.toCommandArray(), null, baos, null);
    String cleartoolOutput = ClearCaseUcmBaselineUtils.processCleartoolOuput(baos);
    baos.close();

    // ensure no error has occured
    if (cleartoolOutput.contains("cleartool: Error")) {
      launcher
          .getListener()
          .error(
              "Failed to get the dependent baselines from the baseline " + baselineSelector + ".");
      throw new IOException(
          "Failed to get the dependent baselines from the baseline "
              + baselineSelector
              + ": "
              + cleartoolOutput);
    }

    if (cleartoolOutput.length() > 0) {
      dependentBaselines = cleartoolOutput.split(" ");
    } else {
      dependentBaselines = new String[0];
    }

    // caching
    dependentBaselinesCache.put(baselineSelector, dependentBaselines);

    return dependentBaselines;
  }
  /**
   * Returns, for a given ClearCase UCM component, its root dir.
   *
   * <p>Note that in case the component is rootless, an empty string is returned (cf. HUDSON-6398).
   *
   * <p>The root dirs are cached for each instance of the class.
   *
   * @see ftp://ftp.software.ibm.com/software/rational/docs/v2002/cc/cc_ref_1.pdf (%[root_dir]p,
   *     page 392)
   */
  public String getComponentRootDir(String pvob, String component)
      throws IOException, InterruptedException {
    String componentSelector = component + '@' + pvob;

    if (componentRootDirsCache.containsKey(componentSelector)) {
      return componentRootDirsCache.get(componentSelector);
    }

    // cleartool lscomp -fmt "%[root_dir]p" <component>@<pvob>
    ArgumentListBuilder cmd = new ArgumentListBuilder();
    cmd.add("lscomp");
    cmd.add("-fmt");
    cmd.add("%[root_dir]p");
    cmd.add(componentSelector);

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    launcher.run(cmd.toCommandArray(), null, baos, null);
    String cleartoolOutput = ClearCaseUcmBaselineUtils.processCleartoolOuput(baos);
    baos.close();

    // ensure no error has occured
    if (cleartoolOutput != null && cleartoolOutput.contains("cleartool: Error")) {
      launcher
          .getListener()
          .error("Failed to get root dir of the component " + componentSelector + ".");
      throw new IOException(
          "Failed to get the root dir of the component "
              + componentSelector
              + ": "
              + cleartoolOutput);
    }

    // no error ==> it means the cleartool ouput just contains the root dir
    // or an empty string if the component is rootless -- cf. HUDSON-6398

    // caching
    componentRootDirsCache.put(componentSelector, cleartoolOutput);

    return cleartoolOutput != null ? cleartoolOutput.trim() : StringUtils.EMPTY;
  }
  /**
   * Returns, for a given ClearCase UCM baseline, the ClearCase UCM component this baseline refers
   * to.
   *
   * <p>The ClearCase UCM components are cached for each instance of the class.
   *
   * @see ftp://ftp.software.ibm.com/software/rational/docs/v2002/cc/cc_ref_1.pdf (%[component]p,
   *     page 392)
   */
  public String getComponentFromBaseline(String pvob, String baseline)
      throws IOException, InterruptedException {
    String baselineSelector = baseline + '@' + pvob;

    if (componentsCache.containsKey(baselineSelector)) {
      return componentsCache.get(baselineSelector);
    }

    // cleartool lsbl -fmt "%[component]p" <baseline>@<pvob>
    ArgumentListBuilder cmd = new ArgumentListBuilder();
    cmd.add("lsbl");
    cmd.add("-fmt");
    cmd.add("%[component]p");
    cmd.add(baselineSelector);

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    launcher.run(cmd.toCommandArray(), null, baos, null);
    String cleartoolOutput = ClearCaseUcmBaselineUtils.processCleartoolOuput(baos);
    baos.close();

    // ensure no error has occured
    if (cleartoolOutput.contains("cleartool: Error")) {
      launcher
          .getListener()
          .error("Failed to get component from the baseline " + baselineSelector + ".");
      throw new IOException(
          "Failed to get the component from the baseline "
              + baselineSelector
              + ": "
              + cleartoolOutput);
    }

    // no error ==> it means the cleartool ouput just contains the component

    // caching
    componentsCache.put(baselineSelector, cleartoolOutput);

    return cleartoolOutput;
  }