static cl_error_t egg_parse_archive_extra_field(egg_handle* handle)
{
    cl_error_t status = CL_EPARSE;

    const uint8_t* index    = NULL;
    extra_field* extraField = NULL;
    uint32_t magic          = 0;
    uint32_t size           = 0;

    if (!handle) {
        cli_errmsg("egg_parse_archive_extra_field: Invalid args!\n");
        return CL_EARG;
    }

    if (CL_SUCCESS != EGG_VALIDATE_HANDLE(handle)) {
        cli_errmsg("egg_parse_comment_headers: Invalid handle values!\n");
        status = CL_EARG;
        goto done;
    }

    index = (const uint8_t*)fmap_need_off_once(handle->map, handle->offset, sizeof(extra_field));
    if (!index) {
        cli_dbgmsg("egg_parse_archive_extra_field: File buffer too small to contain extra_field header.\n");
        goto done;
    }

    extraField = (extra_field*)index;

    cli_dbgmsg("egg_parse_archive_extra_field: extra_field->magic:    %08x (%s)\n", le32_to_host(extraField->magic), getMagicHeaderName(le32_to_host(extraField->magic)));
    cli_dbgmsg("egg_parse_archive_extra_field: extra_field->bit_flag: %02x\n", extraField->bit_flag);

    handle->offset += sizeof(extra_field);

    if (extraField->bit_flag & EXTRA_FIELD_FLAGS_SIZE_IS_4BYTES) {
        /* size is uint32_t */
        index = (const uint8_t*)fmap_need_off_once(handle->map, handle->offset, sizeof(uint32_t));
        if (!index) {
            cli_dbgmsg("egg_parse_archive_extra_field: File buffer too small to contain extra_field header.\n");
            goto done;
        }

        size = le32_to_host(*(uint32_t*)index);

        handle->offset += sizeof(uint32_t);
    } else {
        /* size is uint16_t */
        index = (const uint8_t*)fmap_need_off_once(handle->map, handle->offset, sizeof(uint16_t));
        if (!index) {
            cli_dbgmsg("egg_parse_archive_extra_field: File buffer too small to contain extra_field header.\n");
            goto done;
        }

        size = le16_to_host(*(uint16_t*)index);

        handle->offset += sizeof(uint16_t);
    }

    cli_dbgmsg("egg_parse_archive_extra_field: extra_field->size:     %u\n", size);

    magic = le32_to_host(extraField->magic);

    switch (magic) {
        case SOLID_COMPRESSION_MAGIC: {
            /*
             * Solid archive is an archive packed with a special compression method,
             * which treats several or all files within the archive as one continuous data stream.
             */
            cli_dbgmsg("egg_parse_archive_extra_field: Solid archive. Several or all files within the archive treated as one continuous data stream.\n");

            if (0 != handle->bSolid) {
                cli_warnmsg("egg_parse_archive_extra_field: Encountered more than 1 Solid extra_field!\n");
                goto done;
            }
            handle->bSolid = 1;
            break;
        }
        case SPLIT_COMPRESSION_MAGIC: {
            /*
             * Split archives are single archives split into multiple .egg volumes.
             *
             * It is the first file if previous file’s ID is 0, and is the last file
             * if next file’s ID is 0.
             *
             * Header and Extra Field shouldn’t be cut when split compressing.
             * Compressed Block Data can be saved cut.
             * If header is excluded from the split size, insert Dummy Extra Field.
             *
             * If file compression ratio not applied when split compressing, modify
             * Magic of the header into Dummy Header or Skip Header (0xFFFF0000)
             * so it can be skipped.
             */
            split_compression* split = NULL;

            if (0 != handle->bSplit) {
                cli_warnmsg("egg_parse_archive_extra_field: Encountered more than 1 Split extra_field!\n");
                goto done;
            }
            handle->bSplit = 1;
            cli_warnmsg("egg_parse_archive_extra_field: Split archive. Split archives are single archives split into multiple .egg volumes.\n");

            if (sizeof(split_compression) != size) {
                cli_dbgmsg("egg_parse_archive_extra_field: size in extra_field is different than size of split_compression (%zu != %u).\n", sizeof(split_compression), size);
            } else {
                index = (const uint8_t*)fmap_need_off_once(handle->map, handle->offset, sizeof(split_compression));
                if (!index) {
                    cli_dbgmsg("egg_parse_archive_extra_field: File buffer too small to contain split compression header.\n");
                    goto done;
                }

                split = (split_compression*)index;

                handle->splitInfo = split;

                cli_dbgmsg("egg_parse_archive_extra_field: split_compression->prev_file_id: %08x\n", le32_to_host(split->prev_file_id));
                cli_dbgmsg("egg_parse_archive_extra_field: split_compression->next_file_id: %08x\n", le32_to_host(split->next_file_id));
            }
            break;
        }
        case ENCRYPT_HEADER_MAGIC: {
            /*
             * EGG files may have a global encryption header.
             * It is unclear if this means each file is encrypted, or that additional
             * data beyond the file contents is encrypted.
             */
            if (NULL != handle->encrypt) {
                cli_warnmsg("egg_parse_archive_extra_field: Encountered more than 1 encrypt_header!\n");
                goto done;
            }

            /*
             * Fudge factor.
             * The documentation is hazy about how the encrypt header works.
             * From testing, it seems that for encrypted files, the size in the extra_field includes the size OF the extra field.
             */
            size -= sizeof(extra_field) + sizeof(uint16_t);

            index = (const uint8_t*)fmap_need_off_once(handle->map, handle->offset, size);
            if (!index) {
                cli_errmsg("egg_parse_archive_extra_field: File buffer too small to contain encryption headers.\n");
                goto done;
            }

            if (CL_SUCCESS != egg_parse_encrypt_header(index, size, &handle->encrypt)) {
                cli_errmsg("egg_parse_archive_extra_field: Failed to parse encryption headers.\n");
                goto done;
            }
            break;
        }
        default: {
            cli_dbgmsg("egg_parse_archive_extra_field: unexpected header magic:    %08x (%s)\n", magic, getMagicHeaderName(magic));
        }
    }

    handle->offset += size;

    status = CL_SUCCESS;

done:

    return status;
}