public function stat() {
    $prefix = $this->prefix;
    if (StringUtil::endsWith($prefix, parent::DELIMITER)) {
      $prefix = substr($prefix, 0, strlen($prefix) - 1);
    }

    if (ini_get("google_app_engine.enable_gcs_stat_cache") &&
        $this->tryGetFromStatCache($stat_result)) {
      return $stat_result;
    }

    if (isset($prefix)) {
      $result = $this->headObject($prefix);
      if ($result !== false) {
        $mode = parent::S_IFREG;
        $mtime = $result['mtime'];
        $size = $result['size'];
      } else {
        // Object doesn't exisit, check and see if it's a directory.
        do {
          $results = $this->listBucket($prefix);
          if (false === $results) {
            return false;
          }
          // If there are no results then we're done
          if (empty($results)) {
            return false;
          }
          // If there is an entry that contains object_name_$folder$ or
          // object_name/ then we have a 'directory'.
          $object_name_folder = $prefix . parent::FOLDER_SUFFIX;
          $object_name_delimiter = $prefix . parent::DELIMITER;
          foreach ($results as $result) {
            if ($result['name'] === $object_name_folder ||
                $result['name'] === $object_name_delimiter) {
              $mode = parent::S_IFDIR;
              break;
            }
          }
        } while (!isset($mode) && isset($this->next_marker));
      }
    } else {
      // We are now just checking that the bucket exists, as there was no
      // object prefix supplied
      $results = $this->listBucket();
      if ($results !== false) {
        $mode = parent::S_IFDIR;
      } else {
        return false;
      }
    }
    // If mode is not set, then there was no object that matched the criteria.
    if (!isset($mode)) {
      return false;
    }
    // If the app could stat the file, then it must be readable. As different
    // PHP internal APIs check the access mode, we'll set them all to readable.
    $mode |= parent::S_IRUSR | parent::S_IRGRP | parent::S_IROTH;

    if ($this->isBucketWritable($this->bucket_name)) {
      $mode |= parent::S_IWUSR | parent::S_IWGRP | parent::S_IWOTH;
    }

    $stat_args["mode"] = $mode;
    if (isset($mtime)) {
      $unix_time = strtotime($mtime);
      if ($unix_time !== false) {
        $stat_args["mtime"] = $unix_time;
      }
    }

    if (isset($size)) {
      $stat_args["size"] = intval($size);
    }
    $stat_result = $this->createStatArray($stat_args);
    $this->addToStatCache($stat_result);
    return $stat_result;
  }