/**
  * {@inheritDoc}
  *
  * @throws InvalidArgumentException When argument(s) is(are) incorrect
  */
 public function download($local, Filesystem $remote, array $options = array())
 {
     if (!$remote instanceof File) {
         throw new \InvalidArgumentException(sprintf("Invalid remote file given, expected instance of File, got %s", get_class($remote)));
     }
     if (true !== is_resource($local)) {
         throw new \InvalidArgumentException(sprintf("Invalid local file given. Expected resource, got %s", gettype($local)));
     }
     if (!isset($options[FTP::NON_BLOCKING]) || true !== $options[FTP::NON_BLOCKING]) {
         throw new \InvalidArgumentException("Invalid option given. Expected true as FTP::NON_BLOCKING parameter");
     }
     $defaults = array(FTP::NON_BLOCKING_CALLBACK => function () {
     }, FTP::TRANSFER_MODE => FTPWrapper::BINARY, FTP::START_POS => 0);
     $options = $options + $defaults;
     $callback = $options[FTP::NON_BLOCKING_CALLBACK];
     $state = $this->wrapper->fgetNb($local, $remote->getRealpath(), $options[FTP::TRANSFER_MODE], $options[FTP::START_POS]);
     call_user_func_array($callback, array());
     while ($state == FTPWrapper::MOREDATA) {
         $state = $this->wrapper->nbContinue();
         call_user_func_array($callback, array());
     }
     return $state === FTPWrapper::FINISHED;
 }