/**
   * Rename a file or folder.
   *
   * @param from the source to rename, this will be a complete reference to a file or folder
   * @param to the destination name, this will be a complete reference to the new name (including
   *     path)
   * @param overwrite <tt>true</tt> if any existing destination should be overwritten. If this
   *     parameter is <tt>false</tt> a unique name should be generated based on <tt>to</tt>.
   * @return the name of the new file (excluding the path)
   */
  public String renameFile(
      @ParamName(name = "from") String from,
      @ParamName(name = "to") String to,
      @ParamName(name = "overwrite") boolean overwrite) {

    Resource source = getResource(from, Resource.class);

    ResourcePath destination = new ResourcePath().get(to);
    Folder destinationFolder = getResource(destination.getParent().toString(), Folder.class);
    Assert.state(
        destinationFolder.exists(),
        "The destination folder '" + destinationFolder + "' does not exist");

    String destinationName = destination.getName();
    if (destinationFolder.hasExisting(destinationName) && !overwrite) {
      destinationName = generateUniqueNumberedFileName(destinationFolder, destinationName);
    }

    Resource renamed = source;
    if (!destinationFolder.equals(renamed.getParent())) {
      renamed = renamed.moveTo(destinationFolder);
    }
    if (!renamed.getName().equals(destinationName)) {
      renamed = renamed.rename(destinationName);
    }
    return renamed.getName();
  }