public function deleteMatchingObjectsAsync($bucket, $prefix = '', $regex = '', array $options = [])
 {
     if (!$prefix && !$regex) {
         return new RejectedPromise(new \RuntimeException('A prefix or regex is required.'));
     }
     $params = ['Bucket' => $bucket, 'Prefix' => $prefix];
     $iter = $this->getIterator('ListObjects', $params);
     if ($regex) {
         $iter = \Aws\filter($iter, function ($c) use($regex) {
             return preg_match($regex, $c['Key']);
         });
     }
     return BatchDelete::fromIterator($this, $bucket, $iter, $options)->promise();
 }
 /**
  * @inheritdoc
  */
 public function rename($from, $to)
 {
     $fromUrl = parse_url($from);
     $repoId = $fromUrl["host"];
     $repoObject = ConfService::getRepositoryById($repoId);
     $isViPR = $repoObject->getOption("IS_VIPR");
     $isDir = false;
     if ($isViPR === true) {
         if (is_dir($from . "/")) {
             $from .= '/';
             $to .= '/';
             $isDir = true;
         }
     }
     if ($isDir === true || is_dir($from)) {
         AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Renaming dir {$from} to {$to}");
         require_once "aws-v2.phar";
         $fromUrl = parse_url($from);
         $repoId = $fromUrl["host"];
         $repoObject = ConfService::getRepositoryById($repoId);
         if (!isset($repoObject)) {
             $e = new Exception("Cannot find repository with id " . $repoId);
             self::$lastException = $e;
             throw $e;
         }
         $s3Client = self::getClientForRepository($repoObject, false);
         $bucket = $repoObject->getOption("CONTAINER");
         $basePath = $repoObject->getOption("PATH");
         $fromKeyname = trim(str_replace("//", "/", $basePath . parse_url($from, PHP_URL_PATH)), '/');
         $toKeyname = trim(str_replace("//", "/", $basePath . parse_url($to, PHP_URL_PATH)), '/');
         if ($isViPR) {
             $toKeyname .= '/';
             $parts = explode('/', $bucket);
             $bucket = $parts[0];
             if (isset($parts[1])) {
                 $fromKeyname = $parts[1] . "/" . $fromKeyname;
             }
         }
         // Perform a batch of CopyObject operations.
         $batch = array();
         $failed = array();
         $iterator = $s3Client->getIterator('ListObjects', array('Bucket' => $bucket, 'Prefix' => $fromKeyname . "/"));
         $toDelete = array();
         AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Got iterator looking for prefix " . $fromKeyname . "/ , and toKeyName=" . $toKeyname);
         foreach ($iterator as $object) {
             $currentFrom = $object['Key'];
             $currentTo = $toKeyname . substr($currentFrom, strlen($fromKeyname));
             if ($isViPR) {
                 if (isset($parts[1])) {
                     $currentTo = $parts[1] . "/" . $currentTo;
                 }
             }
             AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Should move one object " . $currentFrom . " to  new key :" . $currentTo);
             $batch[] = $s3Client->getCommand('CopyObject', array('Bucket' => $bucket, 'Key' => "{$currentTo}", 'CopySource' => "{$bucket}/" . rawurlencode($currentFrom)));
             $toDelete[] = $currentFrom;
         }
         AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Execute batch on " . count($batch) . " objects");
         ConfService::getConfStorageImpl()->_loadPluginConfig("access.s3", $globalOptions);
         $sdkVersion = $globalOptions["SDK_VERSION"];
         if ($sdkVersion === "v3") {
             foreach ($batch as $command) {
                 $successful = $s3Client->execute($command);
             }
             //We must delete the "/" in $fromKeyname because we want to delete the folder
             $clear = \Aws\S3\BatchDelete::fromIterator($s3Client, $bucket, $s3Client->getIterator('ListObjects', array('Bucket' => $bucket, 'Prefix' => $fromKeyname)));
             $clear->delete();
         } else {
             try {
                 $successful = $s3Client->execute($batch);
                 $clear = new \Aws\S3\Model\ClearBucket($s3Client, $bucket);
                 $iterator->rewind();
                 $clear->setIterator($iterator);
                 $clear->clear();
                 $failed = array();
             } catch (\Guzzle\Service\Exception\CommandTransferException $e) {
                 $successful = $e->getSuccessfulCommands();
                 $failed = $e->getFailedCommands();
             }
         }
         if (count($failed)) {
             foreach ($failed as $c) {
                 // $c is a Aws\S3\Command\S3Command
                 AJXP_Logger::error("S3Wrapper", __FUNCTION__, "Error while copying: " . $c->getOperation()->getServiceDescription());
             }
             self::$lastException = new Exception("Failed moving folder: " . count($failed));
             return false;
         }
         return true;
     } else {
         AJXP_Logger::debug(__CLASS__, __FUNCTION__, "S3 Execute standard rename on " . $from . " to " . $to);
         return parent::rename($from, $to);
     }
 }