/* BEGIN_HEADER */
#include "psa/crypto_se_driver.h"

#include "psa_crypto_se.h"
#include "psa_crypto_storage.h"

/** The location and lifetime used for tests that use a single driver. */
#define TEST_DRIVER_LOCATION 1
#define TEST_SE_PERSISTENT_LIFETIME                             \
    (PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(           \
         PSA_KEY_PERSISTENCE_DEFAULT, TEST_DRIVER_LOCATION))

static struct {
    uint16_t called;
    psa_key_location_t location;
    psa_status_t return_value;
} mock_init_data;

static struct {
    uint16_t called;
    psa_key_slot_number_t key_slot;
    psa_key_attributes_t attributes;
    size_t pubkey_size;
    psa_status_t return_value;
} mock_generate_data;

static struct {
    uint16_t called;
    psa_key_slot_number_t key_slot;
    psa_key_attributes_t attributes;
    size_t bits;
    size_t data_length;
    psa_status_t return_value;
} mock_import_data;

static struct {
    uint16_t called;
    psa_key_slot_number_t slot_number;
    size_t data_size;
    psa_status_t return_value;
} mock_export_data;

static struct {
    uint16_t called;
    psa_key_slot_number_t slot_number;
    size_t data_size;
    psa_status_t return_value;
} mock_export_public_data;

static struct {
    uint16_t called;
    psa_key_slot_number_t key_slot;
    psa_algorithm_t alg;
    size_t hash_length;
    size_t signature_size;
    psa_status_t return_value;
} mock_sign_data;

static struct {
    uint16_t called;
    psa_key_slot_number_t key_slot;
    psa_algorithm_t alg;
    size_t hash_length;
    size_t signature_length;
    psa_status_t return_value;
} mock_verify_data;

static struct {
    uint16_t called;
    psa_status_t return_value;
} mock_allocate_data;

static struct {
    uint16_t called;
    psa_key_slot_number_t slot_number;
    psa_status_t return_value;
} mock_destroy_data;

#define MAX_KEY_ID_FOR_TEST 10
static void psa_purge_storage(void)
{
    psa_key_id_t id;
    psa_key_location_t location;

    /* The tests may have potentially created key ids from 1 to
     * MAX_KEY_ID_FOR_TEST. In addition, run the destroy function on key id
     * 0, which file-based storage uses as a temporary file. */
    for (id = 0; id <= MAX_KEY_ID_FOR_TEST; id++) {
        psa_destroy_persistent_key(mbedtls_svc_key_id_make(1, id));
    }

    /* Purge the transaction file. */
    psa_crypto_stop_transaction();
    /* Purge driver persistent data. */
    for (location = 0; location < PSA_MAX_SE_LOCATION; location++) {
        psa_destroy_se_persistent_data(location);
    }
}

static void mock_teardown(void)
{
    memset(&mock_init_data, 0, sizeof(mock_init_data));
    memset(&mock_import_data, 0, sizeof(mock_import_data));
    memset(&mock_export_data, 0, sizeof(mock_export_data));
    memset(&mock_export_public_data, 0, sizeof(mock_export_public_data));
    memset(&mock_sign_data, 0, sizeof(mock_sign_data));
    memset(&mock_verify_data, 0, sizeof(mock_verify_data));
    memset(&mock_allocate_data, 0, sizeof(mock_allocate_data));
    memset(&mock_destroy_data, 0, sizeof(mock_destroy_data));
    memset(&mock_generate_data, 0, sizeof(mock_generate_data));
    psa_purge_storage();
}

static psa_status_t mock_init(psa_drv_se_context_t *drv_context,
                              void *persistent_data,
                              psa_key_location_t location)
{
    (void) drv_context;
    (void) persistent_data;

    mock_init_data.called++;
    mock_init_data.location = location;
    return mock_init_data.return_value;
}

static psa_status_t mock_generate(psa_drv_se_context_t *drv_context,
                                  psa_key_slot_number_t key_slot,
                                  const psa_key_attributes_t *attributes,
                                  uint8_t *pubkey,
                                  size_t pubkey_size,
                                  size_t *pubkey_length)
{
    (void) drv_context;
    (void) pubkey;
    (void) pubkey_length;

    mock_generate_data.called++;
    mock_generate_data.key_slot = key_slot;
    mock_generate_data.attributes = *attributes;
    mock_generate_data.pubkey_size = pubkey_size;

    return mock_generate_data.return_value;
}

static psa_status_t mock_import(psa_drv_se_context_t *drv_context,
                                psa_key_slot_number_t key_slot,
                                const psa_key_attributes_t *attributes,
                                const uint8_t *data,
                                size_t data_length,
                                size_t *bits)
{
    (void) drv_context;
    (void) data;

    *bits = mock_import_data.bits;

    mock_import_data.called++;
    mock_import_data.key_slot = key_slot;
    mock_import_data.attributes = *attributes;
    mock_import_data.data_length = data_length;

    return mock_import_data.return_value;
}

psa_status_t mock_export(psa_drv_se_context_t *context,
                         psa_key_slot_number_t slot_number,
                         uint8_t *p_data,
                         size_t data_size,
                         size_t *p_data_length)
{
    (void) context;
    (void) p_data;
    (void) p_data_length;

    mock_export_data.called++;
    mock_export_data.slot_number = slot_number;
    mock_export_data.data_size = data_size;

    return mock_export_data.return_value;
}

psa_status_t mock_export_public(psa_drv_se_context_t *context,
                                psa_key_slot_number_t slot_number,
                                uint8_t *p_data,
                                size_t data_size,
                                size_t *p_data_length)
{
    (void) context;
    (void) p_data;
    (void) p_data_length;

    mock_export_public_data.called++;
    mock_export_public_data.slot_number = slot_number;
    mock_export_public_data.data_size = data_size;

    return mock_export_public_data.return_value;
}

psa_status_t mock_sign(psa_drv_se_context_t *context,
                       psa_key_slot_number_t key_slot,
                       psa_algorithm_t alg,
                       const uint8_t *p_hash,
                       size_t hash_length,
                       uint8_t *p_signature,
                       size_t signature_size,
                       size_t *p_signature_length)
{
    (void) context;
    (void) p_hash;
    (void) p_signature;
    (void) p_signature_length;

    mock_sign_data.called++;
    mock_sign_data.key_slot = key_slot;
    mock_sign_data.alg = alg;
    mock_sign_data.hash_length = hash_length;
    mock_sign_data.signature_size = signature_size;

    return mock_sign_data.return_value;
}

psa_status_t mock_verify(psa_drv_se_context_t *context,
                         psa_key_slot_number_t key_slot,
                         psa_algorithm_t alg,
                         const uint8_t *p_hash,
                         size_t hash_length,
                         const uint8_t *p_signature,
                         size_t signature_length)
{
    (void) context;
    (void) p_hash;
    (void) p_signature;

    mock_verify_data.called++;
    mock_verify_data.key_slot = key_slot;
    mock_verify_data.alg = alg;
    mock_verify_data.hash_length = hash_length;
    mock_verify_data.signature_length = signature_length;

    return mock_verify_data.return_value;
}

psa_status_t mock_allocate(psa_drv_se_context_t *drv_context,
                           void *persistent_data,
                           const psa_key_attributes_t *attributes,
                           psa_key_creation_method_t method,
                           psa_key_slot_number_t *key_slot)
{
    (void) drv_context;
    (void) persistent_data;
    (void) attributes;
    (void) method;
    (void) key_slot;

    mock_allocate_data.called++;
    *key_slot = 0;

    return mock_allocate_data.return_value;
}

psa_status_t mock_destroy(psa_drv_se_context_t *context,
                          void *persistent_data,
                          psa_key_slot_number_t slot_number)
{
    (void) context;
    (void) persistent_data;

    mock_destroy_data.called++;
    mock_destroy_data.slot_number = slot_number;

    return mock_destroy_data.return_value;
}

/* END_HEADER */

/* BEGIN_DEPENDENCIES
 * depends_on:MBEDTLS_PSA_CRYPTO_SE_C
 * END_DEPENDENCIES
 */

/* BEGIN_CASE */
void mock_init(int location_arg,
               int expected_register_status_arg,
               int driver_status_arg,
               int expected_psa_status_arg,
               int expected_called)
{
    psa_key_location_t location = location_arg;
    psa_status_t expected_register_status = expected_register_status_arg;
    psa_status_t driver_status = driver_status_arg;
    psa_status_t expected_psa_status = expected_psa_status_arg;
    psa_drv_se_t driver = {
        .hal_version = PSA_DRV_SE_HAL_VERSION,
        .p_init = mock_init,
    };
    int psa_crypto_init_called = 0;

    mock_init_data.return_value = driver_status;

    TEST_EQUAL(psa_register_se_driver(location, &driver),
               expected_register_status);

    psa_crypto_init_called = 1;
    TEST_EQUAL(psa_crypto_init(), expected_psa_status);

    TEST_EQUAL(mock_init_data.called, expected_called);
    if (expected_called) {
        TEST_EQUAL(mock_init_data.location, location);
    }

exit:
    if (psa_crypto_init_called) {
        PSA_DONE();
    }
    mock_teardown();
}
/* END_CASE */

/* BEGIN_CASE */
void mock_import(int mock_alloc_return_value,
                 int mock_import_return_value,
                 int bits,
                 int expected_result)
{
    psa_drv_se_t driver;
    psa_drv_se_key_management_t key_management;
    psa_key_lifetime_t lifetime = TEST_SE_PERSISTENT_LIFETIME;
    psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(lifetime);
    mbedtls_svc_key_id_t id = mbedtls_svc_key_id_make(1, 1);
    mbedtls_svc_key_id_t returned_id;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    const uint8_t key_material[3] = { 0xfa, 0xca, 0xde };

    mock_allocate_data.return_value = mock_alloc_return_value;
    mock_import_data.return_value = mock_import_return_value;
    mock_import_data.bits = bits;
    memset(&driver, 0, sizeof(driver));
    memset(&key_management, 0, sizeof(key_management));
    driver.hal_version = PSA_DRV_SE_HAL_VERSION;
    driver.key_management = &key_management;
    key_management.p_import = mock_import;
    key_management.p_destroy = mock_destroy;
    key_management.p_allocate = mock_allocate;

    PSA_ASSERT(psa_register_se_driver(location, &driver));
    PSA_ASSERT(psa_crypto_init());

    psa_set_key_id(&attributes, id);
    psa_set_key_lifetime(&attributes, lifetime);
    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT);
    psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
    TEST_ASSERT(psa_import_key(&attributes,
                               key_material, sizeof(key_material),
                               &returned_id) == expected_result);

    TEST_ASSERT(mock_allocate_data.called == 1);
    TEST_ASSERT(mock_import_data.called ==
                (mock_alloc_return_value == PSA_SUCCESS ? 1 : 0));

    if (mock_alloc_return_value == PSA_SUCCESS) {
        TEST_ASSERT(mbedtls_svc_key_id_equal(
                        mock_import_data.attributes.core.id, id));
    } else {
        TEST_ASSERT(MBEDTLS_SVC_KEY_ID_GET_KEY_ID(
                        mock_import_data.attributes.core.id) == 0);
        TEST_ASSERT(MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(
                        mock_import_data.attributes.core.id) == 0);
    }

    TEST_ASSERT(mock_import_data.attributes.core.lifetime ==
                (mock_alloc_return_value == PSA_SUCCESS ? lifetime : 0));
    TEST_ASSERT(mock_import_data.attributes.core.policy.usage ==
                (mock_alloc_return_value == PSA_SUCCESS ? PSA_KEY_USAGE_EXPORT : 0));
    TEST_ASSERT(mock_import_data.attributes.core.type ==
                (mock_alloc_return_value == PSA_SUCCESS ? PSA_KEY_TYPE_RAW_DATA : 0));

    if (expected_result == PSA_SUCCESS) {
        PSA_ASSERT(psa_destroy_key(id));
        TEST_ASSERT(mock_destroy_data.called == 1);
    }
exit:
    PSA_DONE();
    mock_teardown();
}
/* END_CASE */

/* BEGIN_CASE */
void mock_export(int mock_export_return_value, int expected_result)
{
    psa_drv_se_t driver;
    psa_drv_se_key_management_t key_management;
    psa_key_lifetime_t lifetime = TEST_SE_PERSISTENT_LIFETIME;
    psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(lifetime);
    mbedtls_svc_key_id_t id = mbedtls_svc_key_id_make(1, 1);
    mbedtls_svc_key_id_t returned_id;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    const uint8_t key_material[3] = { 0xfa, 0xca, 0xde };
    uint8_t exported[sizeof(key_material)];
    size_t exported_length;

    mock_export_data.return_value = mock_export_return_value;
    memset(&driver, 0, sizeof(driver));
    memset(&key_management, 0, sizeof(key_management));
    driver.hal_version = PSA_DRV_SE_HAL_VERSION;
    driver.key_management = &key_management;
    driver.p_init = mock_init;
    key_management.p_import = mock_import;
    key_management.p_export = mock_export;
    key_management.p_destroy = mock_destroy;
    key_management.p_allocate = mock_allocate;

    PSA_ASSERT(psa_register_se_driver(location, &driver));
    PSA_ASSERT(psa_crypto_init());

    psa_set_key_id(&attributes, id);
    psa_set_key_lifetime(&attributes, lifetime);
    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT);
    psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
    PSA_ASSERT(psa_import_key(&attributes,
                              key_material, sizeof(key_material),
                              &returned_id));

    TEST_ASSERT(psa_export_key(id,
                               exported, sizeof(exported),
                               &exported_length) == expected_result);

    TEST_ASSERT(mock_export_data.called == 1);

    PSA_ASSERT(psa_destroy_key(id));

    TEST_ASSERT(mock_destroy_data.called == 1);

exit:
    PSA_DONE();
    mock_teardown();
}
/* END_CASE */

/* BEGIN_CASE */
void mock_generate(int mock_alloc_return_value,
                   int mock_generate_return_value,
                   int expected_result)
{
    psa_drv_se_t driver;
    psa_drv_se_key_management_t key_management;
    psa_key_lifetime_t lifetime = TEST_SE_PERSISTENT_LIFETIME;
    psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(lifetime);
    mbedtls_svc_key_id_t id = mbedtls_svc_key_id_make(1, 1);
    mbedtls_svc_key_id_t returned_id;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;

    mock_allocate_data.return_value = mock_alloc_return_value;
    mock_generate_data.return_value = mock_generate_return_value;
    memset(&driver, 0, sizeof(driver));
    memset(&key_management, 0, sizeof(key_management));
    driver.hal_version = PSA_DRV_SE_HAL_VERSION;
    driver.key_management = &key_management;
    key_management.p_generate = mock_generate;
    key_management.p_destroy = mock_destroy;
    key_management.p_allocate = mock_allocate;

    PSA_ASSERT(psa_register_se_driver(location, &driver));
    PSA_ASSERT(psa_crypto_init());

    psa_set_key_id(&attributes, id);
    psa_set_key_lifetime(&attributes, lifetime);
    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT);
    psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);
    psa_set_key_bits(&attributes, 8);
    TEST_ASSERT(psa_generate_key(&attributes, &returned_id) == expected_result);
    TEST_ASSERT(mock_allocate_data.called == 1);
    TEST_ASSERT(mock_generate_data.called ==
                (mock_alloc_return_value == PSA_SUCCESS ? 1 : 0));

    if (mock_alloc_return_value == PSA_SUCCESS) {
        TEST_ASSERT(mbedtls_svc_key_id_equal(
                        mock_generate_data.attributes.core.id, id));
    } else {
        TEST_ASSERT(MBEDTLS_SVC_KEY_ID_GET_KEY_ID(
                        mock_generate_data.attributes.core.id) == 0);
        TEST_ASSERT(MBEDTLS_SVC_KEY_ID_GET_OWNER_ID(
                        mock_generate_data.attributes.core.id) == 0);
    }

    TEST_ASSERT(mock_generate_data.attributes.core.lifetime ==
                (mock_alloc_return_value == PSA_SUCCESS ? lifetime : 0));
    TEST_ASSERT(mock_generate_data.attributes.core.policy.usage ==
                (mock_alloc_return_value == PSA_SUCCESS ? PSA_KEY_USAGE_EXPORT : 0));
    TEST_ASSERT(mock_generate_data.attributes.core.type ==
                (mock_alloc_return_value == PSA_SUCCESS ? PSA_KEY_TYPE_RAW_DATA : 0));

    if (expected_result == PSA_SUCCESS) {
        PSA_ASSERT(psa_destroy_key(id));
        TEST_ASSERT(mock_destroy_data.called == 1);
    }

exit:
    PSA_DONE();
    mock_teardown();
}
/* END_CASE */

/* BEGIN_CASE */
void mock_export_public(int mock_export_public_return_value,
                        int expected_result)
{
    psa_drv_se_t driver;
    psa_drv_se_key_management_t key_management;
    psa_key_lifetime_t lifetime = TEST_SE_PERSISTENT_LIFETIME;
    psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(lifetime);
    mbedtls_svc_key_id_t id = mbedtls_svc_key_id_make(1, 1);
    mbedtls_svc_key_id_t returned_id;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    const uint8_t key_material[3] = { 0xfa, 0xca, 0xde };
    uint8_t exported[sizeof(key_material)];
    size_t exported_length;

    mock_export_public_data.return_value = mock_export_public_return_value;
    memset(&driver, 0, sizeof(driver));
    memset(&key_management, 0, sizeof(key_management));
    driver.hal_version = PSA_DRV_SE_HAL_VERSION;
    driver.key_management = &key_management;
    key_management.p_import = mock_import;
    key_management.p_export_public = mock_export_public;
    key_management.p_destroy = mock_destroy;
    key_management.p_allocate = mock_allocate;

    PSA_ASSERT(psa_register_se_driver(location, &driver));
    PSA_ASSERT(psa_crypto_init());

    psa_set_key_id(&attributes, id);
    psa_set_key_lifetime(&attributes, lifetime);
    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_EXPORT);
    psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_PUBLIC_KEY);

    PSA_ASSERT(psa_import_key(&attributes,
                              key_material, sizeof(key_material),
                              &returned_id));

    TEST_ASSERT(psa_export_public_key(id, exported, sizeof(exported),
                                      &exported_length) == expected_result);
    TEST_ASSERT(mock_export_public_data.called == 1);

    PSA_ASSERT(psa_destroy_key(id));
    TEST_ASSERT(mock_destroy_data.called == 1);

exit:
    PSA_DONE();
    mock_teardown();
}
/* END_CASE */

/* BEGIN_CASE */
void mock_sign(int mock_sign_return_value, int expected_result)
{
    psa_drv_se_t driver;
    psa_drv_se_key_management_t key_management;
    psa_drv_se_asymmetric_t asymmetric;
    psa_key_lifetime_t lifetime = TEST_SE_PERSISTENT_LIFETIME;
    psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(lifetime);
    mbedtls_svc_key_id_t id = mbedtls_svc_key_id_make(1, 1);
    mbedtls_svc_key_id_t returned_id;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    const uint8_t key_material[3] = { 0xfa, 0xca, 0xde };
    psa_algorithm_t algorithm = PSA_ALG_ECDSA(PSA_ALG_SHA_256);
    const uint8_t hash[1] = { 'H' };
    uint8_t signature[1] = { 'S' };
    size_t signature_length;

    mock_sign_data.return_value = mock_sign_return_value;
    memset(&driver, 0, sizeof(driver));
    memset(&key_management, 0, sizeof(key_management));
    memset(&asymmetric, 0, sizeof(asymmetric));

    driver.hal_version = PSA_DRV_SE_HAL_VERSION;

    driver.key_management = &key_management;
    key_management.p_import = mock_import;
    key_management.p_destroy = mock_destroy;
    key_management.p_allocate = mock_allocate;

    driver.asymmetric = &asymmetric;
    asymmetric.p_sign = mock_sign;

    PSA_ASSERT(psa_register_se_driver(location, &driver));
    PSA_ASSERT(psa_crypto_init());

    psa_set_key_id(&attributes, id);
    psa_set_key_lifetime(&attributes, lifetime);
    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH);
    psa_set_key_algorithm(&attributes, algorithm);
    psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);

    PSA_ASSERT(psa_import_key(&attributes,
                              key_material, sizeof(key_material),
                              &returned_id));

    TEST_ASSERT(psa_sign_hash(id, algorithm,
                              hash, sizeof(hash),
                              signature, sizeof(signature),
                              &signature_length)
                == expected_result);
    TEST_ASSERT(mock_sign_data.called == 1);

    PSA_ASSERT(psa_destroy_key(id));
    TEST_ASSERT(mock_destroy_data.called == 1);

exit:
    PSA_DONE();
    mock_teardown();
}
/* END_CASE */

/* BEGIN_CASE */
void mock_verify(int mock_verify_return_value, int expected_result)
{
    psa_drv_se_t driver;
    psa_drv_se_key_management_t key_management;
    psa_drv_se_asymmetric_t asymmetric;
    psa_key_lifetime_t lifetime = TEST_SE_PERSISTENT_LIFETIME;
    psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(lifetime);
    mbedtls_svc_key_id_t id = mbedtls_svc_key_id_make(1, 1);
    mbedtls_svc_key_id_t returned_id;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    const uint8_t key_material[3] = { 0xfa, 0xca, 0xde };
    psa_algorithm_t algorithm = PSA_ALG_ECDSA(PSA_ALG_SHA_256);
    const uint8_t hash[1] = { 'H' };
    const uint8_t signature[1] = { 'S' };

    mock_verify_data.return_value = mock_verify_return_value;
    memset(&driver, 0, sizeof(driver));
    memset(&key_management, 0, sizeof(key_management));
    memset(&asymmetric, 0, sizeof(asymmetric));

    driver.hal_version = PSA_DRV_SE_HAL_VERSION;

    driver.key_management = &key_management;
    key_management.p_import = mock_import;
    key_management.p_destroy = mock_destroy;
    key_management.p_allocate = mock_allocate;

    driver.asymmetric = &asymmetric;
    asymmetric.p_verify = mock_verify;

    PSA_ASSERT(psa_register_se_driver(location, &driver));
    PSA_ASSERT(psa_crypto_init());

    psa_set_key_id(&attributes, id);
    psa_set_key_lifetime(&attributes, lifetime);
    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH);
    psa_set_key_algorithm(&attributes, algorithm);
    psa_set_key_type(&attributes, PSA_KEY_TYPE_RAW_DATA);

    PSA_ASSERT(psa_import_key(&attributes,
                              key_material, sizeof(key_material),
                              &returned_id));

    TEST_ASSERT(psa_verify_hash(id, algorithm,
                                hash, sizeof(hash),
                                signature, sizeof(signature))
                == expected_result);
    TEST_ASSERT(mock_verify_data.called == 1);

    PSA_ASSERT(psa_destroy_key(id));
    TEST_ASSERT(mock_destroy_data.called == 1);

exit:
    PSA_DONE();
    mock_teardown();
}
/* END_CASE */
