private function determineHeaderLength()
    {
        $rawRead = fread($this->fp, 4);
        if ($rawRead === false || strlen($rawRead) < 4) {
            throw new RecAnalystException(
                'Unable to read the header length',
                RecAnalystException::HEADERLEN_READERROR
            );
        }
        list (, $this->headerLen) = unpack('V', $rawRead);
        if (!$this->headerLen) {
            $this->manuallyDetermineHeaderLength();
        }
        if (!$this->headerLen) {
            throw new RecAnalystException(
                'Header length is zero',
                RecAnalystException::EMPTY_HEADER
            );
        }
        // In MGL files, the header starts immediately after the header length
        // bytes. In MGX files, another int32 is stored first, possibly indicating
        // the position of possible further headers(? something for saved chapters,
        // at least, or perhaps saved & restored games).
        // The gzip-compressed header always starts with a series of bytes that
        // decodes to a really high number. So if the next 4 bytes _don't_
        // encode to a really high number, they must refer to the next header.
        $rawRead = fread($this->fp, 4);
        list (, $nextPos) = unpack('V', $rawRead);
        $hasNextPos = $nextPos === 0 || $nextPos < $this->getFileSize();

        $this->headerStart = $hasNextPos ? 8 : 4;
        $this->headerLen -= $this->headerStart;
    }