public function writeVarint(Stream $stream, $value)
    {
        // Small values do not need to be encoded
        if ($value >= 0 && $value < 0x80) {
            $this->writeByte($stream, $value);

            return;
        }

        $values = null;

        // Build an array of bytes with the encoded values
        if ($value > 0) {
            $values = [];

            while ($value > 0) {
                $values[] = 0x80 | ($value & 0x7f);
                $value    = $value >> 7;
            }
        }

        if ($values === null) {
            $values = $this->negativeEncoder->encodeVarint($value);
        }

        // Remove the MSB flag from the last byte
        $values[count($values) - 1] &= 0x7f;

        // Convert the byte sized ints to actual bytes in a string
        $values = array_merge(['C*'], $values);
        $bytes  = call_user_func_array('pack', $values);

        $this->writeBytes($stream, $bytes);
    }