protected function handlePATCH(): ResponseInterface
	{

		$offset = $this->request->getHeaderLine("Upload-Offset");
		if ($offset === "") // Note: Some PSR7 implementations discard headers set to 0.
			return $this->response->withStatus(400);

		// Check if the server supports the proposed checksum algorithm
		$checksum = self::parseChecksum($this->request->getHeaderLine("Upload-Checksum"));
		if ($checksum === false)
			return $this->response->withStatus(400);

		// Extension Thunder TUS Express: create the file on PATCH request
		if ($this->extExpress && $offset == 0) {
			$this->response = $this->handlePOST();
			$code = $this->response->getStatusCode();
			if ($code !== 201 && $code !== 409)
				return $this->response;
			if ($code === 409 && !file_exists($this->file . ".cachecontainer")) // Avoid overwriting completed uploads
				return $this->response;
		}
		else { // For Standard TUS
			if (!is_file($this->file))
				return $this->response->withStatus(404);
		}

		// Check if the current stored file offset is different from the proposed upload offset
		// This ensures we're getting the file block by block in the right order and nothing is missing
		if (filesize($this->file) != $offset) {
			return $this->response->withStatus(409)
			                      ->withHeader("Upload-Offset", filesize($this->file));
		}

		// Compare proposed checksum with the received data checksum
		$hashContext = hash_init($checksum->algorithm);
		hash_update_stream($hashContext, $this->stream);
		$localChecksum = base64_encode(hash_final($hashContext, true));
		if ($localChecksum !== $checksum->value)
			return $this->response->withStatus(460, "Checksum Mismatch")
			                      ->withHeader("Upload-Offset", filesize($this->file));

		rewind($this->stream);

		// Write the uploaded chunk to the file
		$file = fopen($this->file, "ab");
		stream_copy_to_stream($this->stream, $file);
		fclose($file);

		clearstatcache(true, $this->file);
		$localSize = filesize($this->file);

		// Detect when the upload is complete
		$cache = \json_decode(file_get_contents($this->file . ".cachecontainer"));
		if ($cache->length <= $localSize) {

			// Remove the cache container, we don't need it anymore
			unlink($this->file . ".cachecontainer");

			// Extension Thunder TUS CrossCheck: verify if the uploaded file is as expected or delete it
			if ($this->extCrossCheck) {
				$localChecksum = base64_encode(hash_file($cache->checksum->algorithm, $this->file, true));
				if ($localChecksum !== $cache->checksum->value) {
					unlink($this->file);

					return $this->response->withStatus(410);
				}
			}

		}

		if ($this->extCrossCheck)
			$this->response = $this->response->withHeader("Location", $this->location);

		// File uploaded successfully!
		return $this->response->withStatus(204)
		                      ->withHeader("Upload-Offset", $localSize);

	}