@ForAllEnvironments
  public void testCyclicLinksRefresh() throws Exception {
    String baseDir = null;
    try {
      baseDir = mkTempAndRefreshParent(true);
      String selfLinkName = "link";
      String linkName1 = "link1";
      String linkName2 = "link2";
      String baseDirlinkName = "linkToDir";
      String script =
          "cd "
              + baseDir
              + "; "
              + "ln -s "
              + selfLinkName
              + ' '
              + selfLinkName
              + ";"
              + "ln -s "
              + linkName1
              + ' '
              + linkName2
              + ";"
              + "ln -s "
              + linkName2
              + ' '
              + linkName1
              + ";"
              + "ln -s "
              + baseDir
              + ' '
              + baseDirlinkName;
      ProcessUtils.ExitStatus res = ProcessUtils.execute(execEnv, "sh", "-c", script);
      assertEquals("Error executing script \"" + script + "\": " + res.error, 0, res.exitCode);

      FileObject baseDirFO = getFileObject(baseDir);
      baseDirFO.refresh();
      FileObject[] children =
          baseDirFO.getChildren(); // otherwise existent children are empty => refresh won't cycle
      baseDirFO.refresh();
    } finally {
      removeRemoteDirIfNotNull(baseDir);
    }
  }
  @ForAllEnvironments
  public void testDirectoryLink() throws Exception {
    String baseDir = null;
    try {
      baseDir = mkTempAndRefreshParent(true);

      String realDir = baseDir + "/real_dir";
      String linkDirName = "link_dir";
      String linkDir = baseDir + '/' + linkDirName;
      String realFile = realDir + "/file";
      String linkFile = linkDir + "/file";

      String script =
          "cd "
              + baseDir
              + "; "
              + "mkdir -p "
              + realDir
              + "; "
              + "ln -s "
              + realDir
              + ' '
              + linkDirName
              + "; "
              + "echo 123 > "
              + realFile;

      ProcessUtils.ExitStatus res = ProcessUtils.execute(execEnv, "sh", "-c", script);
      assertEquals("Error executing script \"" + script + "\": " + res.error, 0, res.exitCode);

      FileObject realFO, linkFO;

      realFO = getFileObject(realFile);
      linkFO = getFileObject(linkFile);

      assertTrue("FileObject should be writable: " + linkFO.getPath(), linkFO.canWrite());
      String content = "a quick brown fox...";
      writeFile(linkFO, content);
      WritingQueue.getInstance(execEnv).waitFinished(null);
      CharSequence readContent = readFile(realFO);
      assertEquals("File content differ", content.toString(), readContent.toString());

      FileObject linkDirFO = getFileObject(linkDir);
      FileObject[] children = linkDirFO.getChildren();
      for (FileObject child : children) {
        String childPath = child.getPath();
        String parentPath = linkDirFO.getPath();
        assertTrue(
            "Incorrect link child path: "
                + childPath
                + " should start with parent path "
                + parentPath,
            child.getPath().startsWith(parentPath));
      }
      FileObject linkFO2;
      linkFO2 = getFileObject(linkFile);
      assertTrue("Duplicate instances for " + linkFile, linkFO == linkFO2);
      linkDirFO.refresh();
      linkFO2 = getFileObject(linkFile);
      assertTrue("Duplicate instances for " + linkFile, linkFO == linkFO2);
    } finally {
      removeRemoteDirIfNotNull(baseDir);
    }
  }