@Override
  public InputStream getInputStream() throws IOException, UnsupportedFileOperationException {
    VsphereConnHandler connHandler = null;
    try {
      connHandler = getConnHandler();
      ManagedObjectReference fileManager = getFileManager(connHandler);

      FileTransferInformation fileDlInfo =
          connHandler
              .getClient()
              .getVimPort()
              .initiateFileTransferFromGuest(fileManager, vm, credentials, getPathInVm());
      String fileDlUrl = fileDlInfo.getUrl().replace("*", connHandler.getClient().getServer());

      // http://stackoverflow.com/questions/921262/how-to-download-and-save-a-file-from-internet-using-java
      URL website = new URL(fileDlUrl);
      return website.openStream();

    } catch (InvalidPropertyFaultMsg e) {
      translateandLogException(e);
    } catch (RuntimeFaultFaultMsg e) {
      translateandLogException(e);
    } catch (FileFaultFaultMsg e) {
      translateandLogException(e);
    } catch (GuestOperationsFaultFaultMsg e) {
      translateandLogException(e);
    } catch (InvalidStateFaultMsg e) {
      translateandLogException(e);
    } catch (TaskInProgressFaultMsg e) {
      translateandLogException(e);
    } finally {
      releaseConnHandler(connHandler);
    }
    return null;
  }
  private void getMor(VsphereConnHandler connHandler) throws RuntimeFaultFaultMsg {
    vm = connHandler.getClient().findVmByIp(vmIdentifier);
    if (vm == null) {
      vm = connHandler.getClient().findVmByUuid(vmIdentifier, true);
    }
    if (vm == null) {
      vm = connHandler.getClient().findVmByUuid(vmIdentifier, false);
    }

    if (vm == null) {
      throw new IllegalArgumentException("Machine identifier " + vmIdentifier + " not found.");
    }
  }
  @Override
  public void renameTo(AbstractFile destFile)
      throws IOException, UnsupportedFileOperationException {

    // can't copy\rename to a different host
    // os might be windows, so can't rename with different case.
    checkRenamePrerequisites(destFile, false, false);

    VsphereConnHandler connHandler = null;
    try {
      connHandler = getConnHandler();
      ManagedObjectReference fileManager = getFileManager(connHandler);
      if (isDirectory()) {
        connHandler
            .getClient()
            .getVimPort()
            .moveDirectoryInGuest(
                fileManager,
                vm,
                credentials,
                getPathInVm(),
                ((VSphereFile) destFile).getPathInVm());

      } else {
        connHandler
            .getClient()
            .getVimPort()
            .moveFileInGuest(
                fileManager,
                vm,
                credentials,
                getPathInVm(),
                ((VSphereFile) destFile).getPathInVm(),
                true);
      }
    } catch (FileFaultFaultMsg e) {
      translateandLogException(e);
    } catch (GuestOperationsFaultFaultMsg e) {
      translateandLogException(e);
    } catch (InvalidStateFaultMsg e) {
      translateandLogException(e);
    } catch (RuntimeFaultFaultMsg e) {
      translateandLogException(e);
    } catch (TaskInProgressFaultMsg e) {
      translateandLogException(e);
    } catch (InvalidPropertyFaultMsg e) {
      translateandLogException(e);
    } finally {
      releaseConnHandler(connHandler);
    }
  }
 @Override
 public void mkdir() throws IOException, UnsupportedFileOperationException {
   VsphereConnHandler connHandler = null;
   try {
     connHandler = getConnHandler();
     connHandler
         .getClient()
         .getVimPort()
         .makeDirectoryInGuest(getFileManager(connHandler), vm, credentials, getPathInVm(), false);
   } catch (FileFaultFaultMsg e) {
     translateandLogException(e);
   } catch (GuestOperationsFaultFaultMsg e) {
     translateandLogException(e);
   } catch (InvalidStateFaultMsg e) {
     translateandLogException(e);
   } catch (RuntimeFaultFaultMsg e) {
     translateandLogException(e);
   } catch (TaskInProgressFaultMsg e) {
     translateandLogException(e);
   } catch (InvalidPropertyFaultMsg e) {
     translateandLogException(e);
   } finally {
     releaseConnHandler(connHandler);
   }
 }
  @Override
  public void changeDate(long lastModified) throws IOException, UnsupportedFileOperationException {

    VsphereConnHandler connHandler = null;
    try {
      GuestFileAttributes gfa = new GuestFileAttributes();
      gfa.setModificationTime(getTimeToXmlTime(lastModified));
      connHandler = getConnHandler();
      connHandler
          .getClient()
          .getVimPort()
          .changeFileAttributesInGuest(
              getFileManager(connHandler), vm, credentials, getPathInVm(), gfa);
    } catch (FileFaultFaultMsg e) {
      translateandLogException(e);
    } catch (GuestOperationsFaultFaultMsg e) {
      translateandLogException(e);
    } catch (InvalidStateFaultMsg e) {
      translateandLogException(e);
    } catch (RuntimeFaultFaultMsg e) {
      translateandLogException(e);
    } catch (TaskInProgressFaultMsg e) {
      translateandLogException(e);
    } catch (InvalidPropertyFaultMsg e) {
      translateandLogException(e);
    } catch (DatatypeConfigurationException e) {
      translateandLogException(e);
    } finally {
      releaseConnHandler(connHandler);
    }
  }
  private void checkAttributues(VsphereConnHandler connHandler)
      throws IOException, FileFaultFaultMsg, GuestOperationsFaultFaultMsg, InvalidStateFaultMsg,
          RuntimeFaultFaultMsg, TaskInProgressFaultMsg, InvalidPropertyFaultMsg {

    ManagedObjectReference fileManager = getFileManager(connHandler);
    GuestListFileInfo res = null;
    try {
      res =
          connHandler
              .getClient()
              .getVimPort()
              .listFilesInGuest(fileManager, vm, credentials, getPathInVm(), null, null, null);
    } catch (SOAPFaultException e) {
      if (isFileNotFound(e)) {
        return;
      }
      throw e;
    }
    if (res.getFiles().size() == 1) {
      // only one result - it's a file
      GuestFileInfo guestFileInfo = res.getFiles().get(0);

      updateAttributes(guestFileInfo);
    } else {
      // more than one result - it's a directory.
      // find the entry for "."
      for (GuestFileInfo f : res.getFiles()) {
        if (f.getPath().equals(".")) {
          updateAttributes(f);
          break;
        }
      }
    }
  }
 private ManagedObjectReference getFileManager(VsphereConnHandler connHandler)
     throws RemoteException, InvalidPropertyFaultMsg, RuntimeFaultFaultMsg {
   ManagedObjectReference fileManager =
       (ManagedObjectReference)
           connHandler.getClient().getProperties(guestOperationsManager, "fileManager")[0];
   return fileManager;
 }
  private void fixPathInVmIfNeeded(VsphereConnHandler connHandler)
      throws RuntimeFaultFaultMsg, RemoteException, InvalidPropertyFaultMsg {

    if (this.guestOsId == null) {
      if (connHandler != null) {
        this.guestOsId = (String) connHandler.getClient().getProperties(vm, "config.guestId")[0];
      }
    }

    boolean isWin = false;
    if (this.guestOsId != null) {
      // is it a windows machine ?
      // see possible values for guest id here:
      // http://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.vm.GuestOsDescriptor.GuestOsIdentifier.html
      isWin = guestOsId.startsWith("win");
    }

    if (pathInsideVm.isEmpty()) {

      if (isWin) {
        // we assume that "C:" is a good default for windows
        pathInsideVm = "C:";
      } else {
        pathInsideVm = "/";
      }

      // set the url to reflect the path inside the vm
      fileURL.setPath(fileURL.getPath() + pathInsideVm);
    }
  }
  public VSphereFile(FileURL url) throws IOException {
    super(url);
    VsphereConnHandler connHandler = null;
    try {
      setPath(url.getPath());

      connHandler = getConnHandler();
      guestOperationsManager =
          connHandler.getClient().getServiceContent().getGuestOperationsManager();

      getMor(connHandler);
      fixPathInVmIfNeeded(connHandler);

      checkAttributues(connHandler);
    } catch (RuntimeFaultFaultMsg e) {
      translateandLogException(e);
    } catch (FileFaultFaultMsg e) {
      translateandLogException(e);
    } catch (GuestOperationsFaultFaultMsg e) {
      translateandLogException(e);
    } catch (InvalidStateFaultMsg e) {
      translateandLogException(e);
    } catch (TaskInProgressFaultMsg e) {
      translateandLogException(e);
    } catch (InvalidPropertyFaultMsg e) {
      translateandLogException(e);
    } catch (URISyntaxException e) {
      translateandLogException(e);
    } finally {
      releaseConnHandler(connHandler);
    }
  }
  @Override
  public AbstractFile[] ls() throws IOException, UnsupportedFileOperationException {
    List<GuestFileInfo> fileInfos = new ArrayList<GuestFileInfo>();
    int index = 0;
    VsphereConnHandler connHandler = null;
    try {

      connHandler = getConnHandler();

      ManagedObjectReference fileManager = getFileManager(connHandler);
      boolean haveRemaining;
      do {
        GuestListFileInfo res =
            connHandler
                .getClient()
                .getVimPort()
                .listFilesInGuest(fileManager, vm, credentials, getPathInVm(), index, null, null);
        haveRemaining = (res.getRemaining() != 0);

        fileInfos.addAll(res.getFiles());
        index = fileInfos.size();
      } while (haveRemaining);

      String parentPath = PathUtils.removeTrailingSeparator(fileURL.getPath()) + SEPARATOR;

      Collection<AbstractFile> res = new ArrayList<AbstractFile>();
      for (GuestFileInfo f : fileInfos) {
        final String name = getFileName(f.getPath());
        if (name.equals(".") || name.equals("..")) {
          continue;
        }

        FileURL childURL = (FileURL) fileURL.clone();
        childURL.setPath(parentPath + name);

        AbstractFile newFile = new VSphereFile(childURL, this, f);
        res.add(newFile);
      }
      return res.toArray(new AbstractFile[0]);
    } catch (FileFaultFaultMsg e) {
      translateandLogException(e);
    } catch (GuestOperationsFaultFaultMsg e) {
      translateandLogException(e);
    } catch (InvalidStateFaultMsg e) {
      translateandLogException(e);
    } catch (RuntimeFaultFaultMsg e) {
      translateandLogException(e);
    } catch (TaskInProgressFaultMsg e) {
      translateandLogException(e);
    } catch (InvalidPropertyFaultMsg e) {
      translateandLogException(e);
    } catch (URISyntaxException e) {
      translateandLogException(e);
    } finally {
      releaseConnHandler(connHandler);
    }
    // we never get here..
    return null;
  }
  private String getFileUploadUrl(
      String remotePathName,
      long fileSize,
      VsphereConnHandler connHandler,
      ManagedObjectReference fileManager)
      throws RemoteException, InvalidPropertyFaultMsg, RuntimeFaultFaultMsg, FileFaultFaultMsg,
          GuestOperationsFaultFaultMsg, InvalidStateFaultMsg, TaskInProgressFaultMsg {

    GuestFileAttributes gfa = new GuestFileAttributes();
    boolean override = true;
    String fileUploadUrl =
        connHandler
            .getClient()
            .getVimPort()
            .initiateFileTransferToGuest(
                fileManager, vm, credentials, remotePathName, gfa, fileSize, override);

    // replace * with the address of the server. see vsphere docs.
    fileUploadUrl = fileUploadUrl.replace("*", connHandler.getClient().getServer());
    return fileUploadUrl;
  }
  @Override
  public void delete() throws IOException, UnsupportedFileOperationException {
    VsphereConnHandler connHandler = null;
    try {
      connHandler = getConnHandler();
      ManagedObjectReference fileManager = getFileManager(connHandler);
      if (isDirectory()) {
        connHandler
            .getClient()
            .getVimPort()
            .deleteDirectoryInGuest(fileManager, vm, credentials, getPathInVm(), false);
        isDir = false;

      } else {
        connHandler
            .getClient()
            .getVimPort()
            .deleteFileInGuest(fileManager, vm, credentials, getPathInVm());
        isFile = isSymLink = false;
      }
    } catch (FileFaultFaultMsg e) {
      translateandLogException(e);
    } catch (GuestOperationsFaultFaultMsg e) {
      translateandLogException(e);
    } catch (InvalidStateFaultMsg e) {
      translateandLogException(e);
    } catch (RuntimeFaultFaultMsg e) {
      translateandLogException(e);
    } catch (TaskInProgressFaultMsg e) {
      translateandLogException(e);
    } catch (InvalidPropertyFaultMsg e) {
      translateandLogException(e);
    } finally {
      releaseConnHandler(connHandler);
    }
  }