public static function move_uploaded_file($filename, $destination,
                                            array $context_options = null) {
    // move_uploaded_file() does not support moving a file between two different
    // stream wrappers. Other file handling functions like rename() have the
    // same problem, but copy() works since it explicitly sends the contents to
    // the new source. As such move_uploaded_file() is replaced by
    // is_uploaded_file(), copy(), and unlink() the old file.
    //
    // This also supports upload proxying during which the file may be remotely
    // located and referenced by a stream wrapper. In that case $filename may be
    // something like gs://... and $destination public://... which may end up on
    // the same remote filesystem, but PHP does not make the distinction. Of
    // course, this also means the file can be moved between two different file
    // systems.
    //
    // In the simple case gs:// to gs:// rename() will be called first and
    // invoke the more performant operation.
    if (is_uploaded_file($filename)) {
      // Either use the user provided context options, otherwise use the default
      // context with the Content-Type overridden.
      if ($context_options !== null) {
        $context = stream_context_create($context_options);
      } else {
        // Default to content type provided in $_FILES array.
        $context = stream_context_get_default([
          'gs' => ['Content-Type' => static::lookupContentType($filename)],
        ]);
      }

      // Attempt rename() which is less expensive if the origin and destination
      // use the same stream wrapper, otherwise perform copy() and unlink().
      if (@rename($filename, $destination, $context)) {
        static::removeUploadedFile($filename);
        return true;
      }
      if (copy($filename, $destination, $context) &&
          unlink($filename, $context)) {
        static::removeUploadedFile($filename);
        return true;
      }
    }
    return false;
  }