public function rename($from, $to) {
    if (!CloudStorageTools::parseFilename($from, $from_bucket, $from_object) ||
        !isset($from_object)) {
      trigger_error(sprintf("Invalid Google Cloud Storage path: %s", $from),
                    E_USER_ERROR);
      return false;
    }
    if (!CloudStorageTools::parseFilename($to, $to_bucket, $to_object) ||
        !isset($to_object)) {
      trigger_error(sprintf("Invalid Google Cloud Storage path: %s", $to),
                    E_USER_ERROR);
      return false;
    }

    // If the file being renamed is an uploaded file being moved to an allowed
    // include bucket trigger a warning.
    $allowed_buckets = $this->getAllowedBuckets();
    foreach ($_FILES as $file) {
      if ($file['tmp_name'] == $from) {
        foreach ($allowed_buckets as $allowed_bucket) {
          // 5th character indicates start of bucket since it ignores 'gs://'.
          if (strpos($to, $allowed_bucket) === 5) {
            trigger_error(sprintf('Moving uploaded file (%s) to an allowed ' .
                                  'include bucket (%s) which may be ' .
                                  'vulnerable to local file inclusion (LFI).',
                                  $from, $allowed_bucket),
                          E_USER_WARNING);
            break 2;
          }
        }
      }
    }

    $client = new CloudStorageRenameClient($from_bucket,
                                           $from_object,
                                           $to_bucket,
                                           $to_object,
                                           $this->context);
    return $client->rename();
  }