for (i = 1; i < MAX_PHRASE_LENGTH + 1; ++i){
        g_item_array[i] = g_array_new
            (FALSE, TRUE, sizeof(phrase_and_array_item));
    }

/*
 *  libpinyin
 *  Library to deal with pinyin.
 *
 *
 */

#include <stdio.h>
#include <glib.h>
#include "pinyin_internal.h"

void print_help(){
    printf("Usage: gen_pinyin_table -t <PHRASE_INDEX> \n"
           "-o <OUTPUTFILE> <FILE1> <FILE2> .. <FILEn>\n"
           "<OUTPUTFILE> the result output file\n"
           "<FILEi> input pinyin files\n"
           "<PHRASE_INDEX> phrase index identifier\n");
}

static gint phrase_index = 0;
static const gchar * outputfile = "temp.out";

static GOptionEntry entries[] =
    {
        {"phraseindex", 't', 0, G_OPTION_ARG_INT, &phrase_index, "phrase index", NULL},
        {"outputfile", 'o', 0, G_OPTION_ARG_FILENAME, &outputfile, "output filename", NULL},
        {NULL}
    };

using namespace pinyin;

/* map from phrase_item to GArray of chewing_and_freq_item */
GTree  * g_chewing_tree;
/* Array of GArray of phrase_and_array_item */
GArray * g_item_array[MAX_PHRASE_LENGTH + 1];

struct phrase_item{
    size_t length;
    gunichar * uniphrase;
};

struct chewing_and_freq_item{
    ChewingKeyVector keys;
    ChewingKeyRestVector key_rests;
    guint32 freq;
};

struct phrase_and_array_item{
    phrase_item phrase;                    /* the key of g_chewing_tree */
    /* Array of chewing_and_freq_item */
    GArray * chewing_and_freq_array;       /* the value of g_chewing_tree */
};

void feed_file(const char * filename);

void feed_line(const char * phrase, const char * pinyin, const guint32 freq);

gboolean store_one_item(gpointer key, gpointer value, gpointer data);

int phrase_array_compare(gconstpointer lhs, gconstpointer rhs,
                         gpointer userdata);

void gen_phrase_file(const char * outputfile, int phrase_index);

gint phrase_item_compare(gconstpointer a, gconstpointer b){
    phrase_item * itema = (phrase_item *) a;
    phrase_item * itemb = (phrase_item *) b;
    if ( itema->length != itemb->length )
        return itema->length - itemb->length;
    else
        return memcmp(itema->uniphrase, itemb->uniphrase,
                      sizeof(gunichar) * itema->length);
}

int main(int argc, char * argv[]){
    int i;

    g_chewing_tree = g_tree_new(phrase_item_compare);

    GError * error = NULL;
    GOptionContext * context;

    context = g_option_context_new("- generate pinyin table");
    g_option_context_add_main_entries(context, entries, NULL);
    if (!g_option_context_parse(context, &argc, &argv, &error)) {
        g_print("option parsing failed:%s\n", error->message);
        exit(EINVAL);
    }

    for (i = 1; i < argc; ++i) {
        feed_file(argv[i]);
    }

    printf("nnodes: %d\n", g_tree_nnodes(g_chewing_tree));

    /* store in item array */
    g_item_array[0] = NULL;

    g_tree_foreach(g_chewing_tree, store_one_item, NULL);

    /* sort item array */
    for ( int i = 1; i < MAX_PHRASE_LENGTH + 1; ++i){
        g_array_sort_with_data(g_item_array[i], phrase_array_compare , &i);
    }

    gen_phrase_file(outputfile, phrase_index);

    return 0;
}

void feed_file ( const char * filename){
    char phrase[1024], pinyin[1024];
    guint32 freq;

    FILE * infile = fopen(filename, "r");
    if ( NULL == infile ){
        fprintf(stderr, "Can't open file %s.\n", filename);
        exit(ENOENT);
    }

    while ( !feof(infile)){
        int num = fscanf(infile, "%1023s %1023s %u",
                         phrase, pinyin, &freq);

        if (3 != num)
            continue;

        if (feof(infile))
            break;

        feed_line(phrase, pinyin, freq);
    }

    fclose(infile);
}

void feed_line(const char * phrase, const char * pinyin, const guint32 freq) {
    phrase_item * item = new phrase_item;
    item->length = g_utf8_strlen(phrase, -1);

    /* FIXME: modify ">" to ">=" according to pinyin_large_table.cpp
     * where is the code which I don't want to touch. :-)
     */

    if (item->length >= MAX_PHRASE_LENGTH) {
        fprintf(stderr, "Too long phrase:%s\t%s\t%d\n", phrase, pinyin, freq);
        delete item;
        return;
    }

    item->uniphrase = g_utf8_to_ucs4(phrase, -1, NULL, NULL, NULL);

    FullPinyinParser2 parser;
    ChewingKeyVector keys = g_array_new(FALSE, FALSE, sizeof(ChewingKey));
    ChewingKeyRestVector key_rests = g_array_new
        (FALSE, FALSE, sizeof(ChewingKeyRest));

    pinyin_option_t options = PINYIN_CORRECT_ALL | USE_TONE;
    parser.parse(options, keys, key_rests, pinyin, strlen(pinyin));
    assert(keys->len == key_rests->len);

    if (keys->len != item->length) {
        fprintf(stderr, "Invalid pinyin:%s\t%s\t%d\n", phrase, pinyin, freq);
        delete item;
        return;
    }

    GArray * array = (GArray *)g_tree_lookup(g_chewing_tree, item);

    chewing_and_freq_item value_item;
    value_item.keys = keys; value_item.key_rests = key_rests;
    value_item.freq = freq;

    assert(item->length == value_item.keys->len);
    if (NULL == array) {
        array = g_array_new(FALSE, FALSE, sizeof(chewing_and_freq_item));
        g_array_append_val(array, value_item);
        g_tree_insert(g_chewing_tree, item, array);
        return;
    }

    bool found = false;
    for (size_t i = 0; i < array->len; ++i) {
        chewing_and_freq_item * cur_item =
            &g_array_index(array, chewing_and_freq_item, i);
        int result = pinyin_exact_compare2
            ((ChewingKey *) value_item.keys->data,
             (ChewingKey *) cur_item->keys->data,
             value_item.keys->len);

        if (0 == result) {
            fprintf(stderr, "Duplicate item: phrase:%s\tpinyin:%s\tfreq:%u\n",
                    phrase, pinyin, freq);
            cur_item->freq += freq;
            found = true;
        }
    }

    if (!found) {
        g_array_append_val(array, value_item);
        g_tree_insert(g_chewing_tree, item, array);
    } else {
        /* clean up */
        g_array_free(keys, TRUE);
        g_array_free(key_rests, TRUE);
    }

    delete item;
}

gboolean store_one_item(gpointer key, gpointer value, gpointer data) {
    phrase_and_array_item item;
    item.phrase = *((phrase_item *) key);
    item.chewing_and_freq_array = (GArray *) value;
    int len = item.phrase.length;
    g_array_append_val(g_item_array[len], item);
    return FALSE;
}

int phrase_array_compare(gconstpointer lhs, gconstpointer rhs,
                         gpointer userdata) {
    int phrase_length = *((int *) userdata);
    phrase_and_array_item * item_lhs = (phrase_and_array_item *) lhs;
    phrase_and_array_item * item_rhs = (phrase_and_array_item *) rhs;

    ChewingKeyVector keys_lhs = g_array_index
        (item_lhs->chewing_and_freq_array, chewing_and_freq_item, 0).keys;
    ChewingKeyVector keys_rhs = g_array_index
        (item_rhs->chewing_and_freq_array, chewing_and_freq_item, 0).keys;
    return pinyin_exact_compare2((ChewingKey *)keys_lhs->data,
                                 (ChewingKey *)keys_rhs->data, phrase_length);
}

void gen_phrase_file(const char * outputfile, int phrase_index){
    FILE * outfile = fopen(outputfile, "w");
    if (NULL == outfile ) {
        fprintf(stderr, "Can't write file %s.\n", outputfile);
        exit(ENOENT);
    }

    phrase_token_t token = 1;

    /* phrase length index */
    for (size_t i = 1; i < MAX_PHRASE_LENGTH + 1; ++i) {
        GArray * item_array = g_item_array[i];

        /* item array index */
        for (size_t m = 0; m < item_array->len; ++m) {
            phrase_and_array_item * item = &g_array_index
                (item_array, phrase_and_array_item, m);
            phrase_item phrase = item->phrase;
            GArray * chewing_and_freqs = item->chewing_and_freq_array;

            gchar * phrase_str = g_ucs4_to_utf8
                (phrase.uniphrase, phrase.length, NULL, NULL, NULL);

            /* iterate each pinyin */
            for (size_t n = 0; n < chewing_and_freqs->len; ++n) {
                chewing_and_freq_item * chewing_and_freq =
                    &g_array_index
                    (chewing_and_freqs, chewing_and_freq_item, n);

                ChewingKeyVector keys = chewing_and_freq->keys;

                GArray * pinyins = g_array_new(TRUE, FALSE, sizeof(gchar *));
                gchar * pinyin = NULL;

                size_t k;
                for (k = 0; k < keys->len; ++k) {
                    ChewingKey key = g_array_index(keys, ChewingKey, k);

                    pinyin = key.get_pinyin_string();
                    g_array_append_val(pinyins, pinyin);
                }
                gchar * pinyin_str = g_strjoinv("'", (gchar **)pinyins->data);

                for (k = 0; k < pinyins->len; ++k) {
                    g_free(g_array_index(pinyins, gchar *, k));
                }
                g_array_free(pinyins, TRUE);

                guint32 freq = chewing_and_freq->freq;

                /* avoid zero freq. */
                if (freq < 3) freq = 3;

                fprintf(outfile, "%s\t%s\t%d\t%d\n",
                        pinyin_str, phrase_str,
                        PHRASE_INDEX_MAKE_TOKEN(phrase_index, token), freq);

                g_free(pinyin_str);
            }
            g_free(phrase_str);
            token++;
        }
    }

    fclose(outfile);
}


while ( !feof(infile)){
        int num = fscanf(infile, "%1023s %1023s %u",
                         phrase, pinyin, &freq);

        if (3 != num)
            continue;

        if (feof(infile))
            break;

        feed_line(phrase, pinyin, freq);
    }

/*
 *  libpinyin
 *  Library to deal with pinyin.
 *
 *
 */

#include <stdio.h>
#include <glib.h>
#include "pinyin_internal.h"

void print_help(){
    printf("Usage: gen_pinyin_table -t <PHRASE_INDEX> \n"
           "-o <OUTPUTFILE> <FILE1> <FILE2> .. <FILEn>\n"
           "<OUTPUTFILE> the result output file\n"
           "<FILEi> input pinyin files\n"
           "<PHRASE_INDEX> phrase index identifier\n");
}

static gint phrase_index = 0;
static const gchar * outputfile = "temp.out";

static GOptionEntry entries[] =
    {
        {"phraseindex", 't', 0, G_OPTION_ARG_INT, &phrase_index, "phrase index", NULL},
        {"outputfile", 'o', 0, G_OPTION_ARG_FILENAME, &outputfile, "output filename", NULL},
        {NULL}
    };

using namespace pinyin;

/* map from phrase_item to GArray of chewing_and_freq_item */
GTree  * g_chewing_tree;
/* Array of GArray of phrase_and_array_item */
GArray * g_item_array[MAX_PHRASE_LENGTH + 1];

struct phrase_item{
    size_t length;
    gunichar * uniphrase;
};

struct chewing_and_freq_item{
    ChewingKeyVector keys;
    ChewingKeyRestVector key_rests;
    guint32 freq;
};

struct phrase_and_array_item{
    phrase_item phrase;                    /* the key of g_chewing_tree */
    /* Array of chewing_and_freq_item */
    GArray * chewing_and_freq_array;       /* the value of g_chewing_tree */
};

void feed_file(const char * filename);

void feed_line(const char * phrase, const char * pinyin, const guint32 freq);

gboolean store_one_item(gpointer key, gpointer value, gpointer data);

int phrase_array_compare(gconstpointer lhs, gconstpointer rhs,
                         gpointer userdata);

void gen_phrase_file(const char * outputfile, int phrase_index);

gint phrase_item_compare(gconstpointer a, gconstpointer b){
    phrase_item * itema = (phrase_item *) a;
    phrase_item * itemb = (phrase_item *) b;
    if ( itema->length != itemb->length )
        return itema->length - itemb->length;
    else
        return memcmp(itema->uniphrase, itemb->uniphrase,
                      sizeof(gunichar) * itema->length);
}

int main(int argc, char * argv[]){
    int i;

    g_chewing_tree = g_tree_new(phrase_item_compare);

    GError * error = NULL;
    GOptionContext * context;

    context = g_option_context_new("- generate pinyin table");
    g_option_context_add_main_entries(context, entries, NULL);
    if (!g_option_context_parse(context, &argc, &argv, &error)) {
        g_print("option parsing failed:%s\n", error->message);
        exit(EINVAL);
    }

    for (i = 1; i < argc; ++i) {
        feed_file(argv[i]);
    }

    printf("nnodes: %d\n", g_tree_nnodes(g_chewing_tree));

    /* store in item array */
    g_item_array[0] = NULL;
    for (i = 1; i < MAX_PHRASE_LENGTH + 1; ++i){
        g_item_array[i] = g_array_new
            (FALSE, TRUE, sizeof(phrase_and_array_item));
    }
    g_tree_foreach(g_chewing_tree, store_one_item, NULL);

    /* sort item array */
    for ( int i = 1; i < MAX_PHRASE_LENGTH + 1; ++i){
        g_array_sort_with_data(g_item_array[i], phrase_array_compare , &i);
    }

    gen_phrase_file(outputfile, phrase_index);

    return 0;
}

void feed_file ( const char * filename){
    char phrase[1024], pinyin[1024];
    guint32 freq;

    FILE * infile = fopen(filename, "r");
    if ( NULL == infile ){
        fprintf(stderr, "Can't open file %s.\n", filename);
        exit(ENOENT);
    }

    fclose(infile);
}

void feed_line(const char * phrase, const char * pinyin, const guint32 freq) {
    phrase_item * item = new phrase_item;
    item->length = g_utf8_strlen(phrase, -1);

    /* FIXME: modify ">" to ">=" according to pinyin_large_table.cpp
     * where is the code which I don't want to touch. :-)
     */

    if (item->length >= MAX_PHRASE_LENGTH) {
        fprintf(stderr, "Too long phrase:%s\t%s\t%d\n", phrase, pinyin, freq);
        delete item;
        return;
    }

    item->uniphrase = g_utf8_to_ucs4(phrase, -1, NULL, NULL, NULL);

    FullPinyinParser2 parser;
    ChewingKeyVector keys = g_array_new(FALSE, FALSE, sizeof(ChewingKey));
    ChewingKeyRestVector key_rests = g_array_new
        (FALSE, FALSE, sizeof(ChewingKeyRest));

    pinyin_option_t options = PINYIN_CORRECT_ALL | USE_TONE;
    parser.parse(options, keys, key_rests, pinyin, strlen(pinyin));
    assert(keys->len == key_rests->len);

    if (keys->len != item->length) {
        fprintf(stderr, "Invalid pinyin:%s\t%s\t%d\n", phrase, pinyin, freq);
        delete item;
        return;
    }

    GArray * array = (GArray *)g_tree_lookup(g_chewing_tree, item);

    chewing_and_freq_item value_item;
    value_item.keys = keys; value_item.key_rests = key_rests;
    value_item.freq = freq;

    assert(item->length == value_item.keys->len);
    if (NULL == array) {
        array = g_array_new(FALSE, FALSE, sizeof(chewing_and_freq_item));
        g_array_append_val(array, value_item);
        g_tree_insert(g_chewing_tree, item, array);
        return;
    }

    bool found = false;
    for (size_t i = 0; i < array->len; ++i) {
        chewing_and_freq_item * cur_item =
            &g_array_index(array, chewing_and_freq_item, i);
        int result = pinyin_exact_compare2
            ((ChewingKey *) value_item.keys->data,
             (ChewingKey *) cur_item->keys->data,
             value_item.keys->len);

        if (0 == result) {
            fprintf(stderr, "Duplicate item: phrase:%s\tpinyin:%s\tfreq:%u\n",
                    phrase, pinyin, freq);
            cur_item->freq += freq;
            found = true;
        }
    }

    if (!found) {
        g_array_append_val(array, value_item);
        g_tree_insert(g_chewing_tree, item, array);
    } else {
        /* clean up */
        g_array_free(keys, TRUE);
        g_array_free(key_rests, TRUE);
    }

    delete item;
}

gboolean store_one_item(gpointer key, gpointer value, gpointer data) {
    phrase_and_array_item item;
    item.phrase = *((phrase_item *) key);
    item.chewing_and_freq_array = (GArray *) value;
    int len = item.phrase.length;
    g_array_append_val(g_item_array[len], item);
    return FALSE;
}

int phrase_array_compare(gconstpointer lhs, gconstpointer rhs,
                         gpointer userdata) {
    int phrase_length = *((int *) userdata);
    phrase_and_array_item * item_lhs = (phrase_and_array_item *) lhs;
    phrase_and_array_item * item_rhs = (phrase_and_array_item *) rhs;

    ChewingKeyVector keys_lhs = g_array_index
        (item_lhs->chewing_and_freq_array, chewing_and_freq_item, 0).keys;
    ChewingKeyVector keys_rhs = g_array_index
        (item_rhs->chewing_and_freq_array, chewing_and_freq_item, 0).keys;
    return pinyin_exact_compare2((ChewingKey *)keys_lhs->data,
                                 (ChewingKey *)keys_rhs->data, phrase_length);
}

void gen_phrase_file(const char * outputfile, int phrase_index){
    FILE * outfile = fopen(outputfile, "w");
    if (NULL == outfile ) {
        fprintf(stderr, "Can't write file %s.\n", outputfile);
        exit(ENOENT);
    }

    phrase_token_t token = 1;

    /* phrase length index */
    for (size_t i = 1; i < MAX_PHRASE_LENGTH + 1; ++i) {
        GArray * item_array = g_item_array[i];

        /* item array index */
        for (size_t m = 0; m < item_array->len; ++m) {
            phrase_and_array_item * item = &g_array_index
                (item_array, phrase_and_array_item, m);
            phrase_item phrase = item->phrase;
            GArray * chewing_and_freqs = item->chewing_and_freq_array;

            gchar * phrase_str = g_ucs4_to_utf8
                (phrase.uniphrase, phrase.length, NULL, NULL, NULL);

            /* iterate each pinyin */
            for (size_t n = 0; n < chewing_and_freqs->len; ++n) {
                chewing_and_freq_item * chewing_and_freq =
                    &g_array_index
                    (chewing_and_freqs, chewing_and_freq_item, n);

                ChewingKeyVector keys = chewing_and_freq->keys;

                GArray * pinyins = g_array_new(TRUE, FALSE, sizeof(gchar *));
                gchar * pinyin = NULL;

                size_t k;
                for (k = 0; k < keys->len; ++k) {
                    ChewingKey key = g_array_index(keys, ChewingKey, k);

                    pinyin = key.get_pinyin_string();
                    g_array_append_val(pinyins, pinyin);
                }
                gchar * pinyin_str = g_strjoinv("'", (gchar **)pinyins->data);

                for (k = 0; k < pinyins->len; ++k) {
                    g_free(g_array_index(pinyins, gchar *, k));
                }
                g_array_free(pinyins, TRUE);

                guint32 freq = chewing_and_freq->freq;

                /* avoid zero freq. */
                if (freq < 3) freq = 3;

                fprintf(outfile, "%s\t%s\t%d\t%d\n",
                        pinyin_str, phrase_str,
                        PHRASE_INDEX_MAKE_TOKEN(phrase_index, token), freq);

                g_free(pinyin_str);
            }
            g_free(phrase_str);
            token++;
        }
    }

    fclose(outfile);
}


/*
Bullet Continuous Collision Detection and Physics Library

*/

#include "btDefaultCollisionConfiguration.h"

#include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h"
#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
#include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h"
#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM
#include "BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h"
#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"

#include "LinearMath/btStackAlloc.h"
#include "LinearMath/btPoolAllocator.h"

btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo)
{

	void* mem = btAlignedAlloc(sizeof(btVoronoiSimplexSolver),16);
	m_simplexSolver = new (mem)btVoronoiSimplexSolver();

	if (constructionInfo.m_useEpaPenetrationAlgorithm)
	{
		mem = btAlignedAlloc(sizeof(btGjkEpaPenetrationDepthSolver),16);
		m_pdSolver = new (mem)btGjkEpaPenetrationDepthSolver;
	}else
	{
		mem = btAlignedAlloc(sizeof(btMinkowskiPenetrationDepthSolver),16);
		m_pdSolver = new (mem)btMinkowskiPenetrationDepthSolver;
	}

	//default CreationFunctions, filling the m_doubleDispatch table
	mem = btAlignedAlloc(sizeof(btConvexConvexAlgorithm::CreateFunc),16);
	m_convexConvexCreateFunc = new(mem) btConvexConvexAlgorithm::CreateFunc(m_simplexSolver,m_pdSolver);
	mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc),16);
	m_convexConcaveCreateFunc = new (mem)btConvexConcaveCollisionAlgorithm::CreateFunc;
	mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc),16);
	m_swappedConvexConcaveCreateFunc = new (mem)btConvexConcaveCollisionAlgorithm::SwappedCreateFunc;
	mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::CreateFunc),16);
	m_compoundCreateFunc = new (mem)btCompoundCollisionAlgorithm::CreateFunc;
	mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::SwappedCreateFunc),16);
	m_swappedCompoundCreateFunc = new (mem)btCompoundCollisionAlgorithm::SwappedCreateFunc;
	mem = btAlignedAlloc(sizeof(btEmptyAlgorithm::CreateFunc),16);
	m_emptyCreateFunc = new(mem) btEmptyAlgorithm::CreateFunc;

	mem = btAlignedAlloc(sizeof(btSphereSphereCollisionAlgorithm::CreateFunc),16);
	m_sphereSphereCF = new(mem) btSphereSphereCollisionAlgorithm::CreateFunc;
#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
	mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc),16);
	m_sphereBoxCF = new(mem) btSphereBoxCollisionAlgorithm::CreateFunc;
	mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc),16);
	m_boxSphereCF = new (mem)btSphereBoxCollisionAlgorithm::CreateFunc;
	m_boxSphereCF->m_swapped = true;
#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM

	mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc),16);
	m_sphereTriangleCF = new (mem)btSphereTriangleCollisionAlgorithm::CreateFunc;
	mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc),16);
	m_triangleSphereCF = new (mem)btSphereTriangleCollisionAlgorithm::CreateFunc;
	m_triangleSphereCF->m_swapped = true;

	mem = btAlignedAlloc(sizeof(btBoxBoxCollisionAlgorithm::CreateFunc),16);
	m_boxBoxCF = new(mem)btBoxBoxCollisionAlgorithm::CreateFunc;

	//convex versus plane
	mem = btAlignedAlloc (sizeof(btConvexPlaneCollisionAlgorithm::CreateFunc),16);
	m_convexPlaneCF = new (mem) btConvexPlaneCollisionAlgorithm::CreateFunc;
	mem = btAlignedAlloc (sizeof(btConvexPlaneCollisionAlgorithm::CreateFunc),16);
	m_planeConvexCF = new (mem) btConvexPlaneCollisionAlgorithm::CreateFunc;
	m_planeConvexCF->m_swapped = true;

	///calculate maximum element size, big enough to fit any collision algorithm in the memory pool
	int maxSize = sizeof(btConvexConvexAlgorithm);
	int maxSize2 = sizeof(btConvexConcaveCollisionAlgorithm);
	int maxSize3 = sizeof(btCompoundCollisionAlgorithm);
	int sl = sizeof(btConvexSeparatingDistanceUtil);
	sl = sizeof(btGjkPairDetector);
	int	collisionAlgorithmMaxElementSize = btMax(maxSize,constructionInfo.m_customCollisionAlgorithmMaxElementSize);
	collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize2);
	collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize3);

	if (constructionInfo.m_stackAlloc)
	{
		m_ownsStackAllocator = false;
		this->m_stackAlloc = constructionInfo.m_stackAlloc;
	} else
	{
		m_ownsStackAllocator = true;
		void* mem = btAlignedAlloc(sizeof(btStackAlloc),16);
		m_stackAlloc = new(mem)btStackAlloc(constructionInfo.m_defaultStackAllocatorSize);
	}

	if (constructionInfo.m_persistentManifoldPool)
	{
		m_ownsPersistentManifoldPool = false;
		m_persistentManifoldPool = constructionInfo.m_persistentManifoldPool;
	} else
	{
		m_ownsPersistentManifoldPool = true;
		void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16);
		m_persistentManifoldPool = new (mem) btPoolAllocator(sizeof(btPersistentManifold),constructionInfo.m_defaultMaxPersistentManifoldPoolSize);
	}

	if (constructionInfo.m_collisionAlgorithmPool)
	{
		m_ownsCollisionAlgorithmPool = false;
		m_collisionAlgorithmPool = constructionInfo.m_collisionAlgorithmPool;
	} else
	{
		m_ownsCollisionAlgorithmPool = true;
		void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16);
		m_collisionAlgorithmPool = new(mem) btPoolAllocator(collisionAlgorithmMaxElementSize,constructionInfo.m_defaultMaxCollisionAlgorithmPoolSize);
	}

}

{
	if (m_ownsStackAllocator)
	{
		m_stackAlloc->destroy();
		m_stackAlloc->~btStackAlloc();
		btAlignedFree(m_stackAlloc);
	}
	if (m_ownsCollisionAlgorithmPool)
	{
		m_collisionAlgorithmPool->~btPoolAllocator();
		btAlignedFree(m_collisionAlgorithmPool);
	}
	if (m_ownsPersistentManifoldPool)
	{
		m_persistentManifoldPool->~btPoolAllocator();
		btAlignedFree(m_persistentManifoldPool);
	}

	m_convexConvexCreateFunc->~btCollisionAlgorithmCreateFunc();
	btAlignedFree(	m_convexConvexCreateFunc);

	m_convexConcaveCreateFunc->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_convexConcaveCreateFunc);
	m_swappedConvexConcaveCreateFunc->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_swappedConvexConcaveCreateFunc);

	m_compoundCreateFunc->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_compoundCreateFunc);

	m_swappedCompoundCreateFunc->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_swappedCompoundCreateFunc);

	m_emptyCreateFunc->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_emptyCreateFunc);

	m_sphereSphereCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_sphereSphereCF);

#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
	m_sphereBoxCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_sphereBoxCF);
	m_boxSphereCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_boxSphereCF);
#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM

	m_sphereTriangleCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_sphereTriangleCF);
	m_triangleSphereCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_triangleSphereCF);
	m_boxBoxCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_boxBoxCF);

	m_convexPlaneCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_convexPlaneCF);
	m_planeConvexCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_planeConvexCF);

	m_simplexSolver->~btVoronoiSimplexSolver();
	btAlignedFree(m_simplexSolver);

	m_pdSolver->~btConvexPenetrationDepthSolver();

	btAlignedFree(m_pdSolver);

}

btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1)
{

	if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1==SPHERE_SHAPE_PROXYTYPE))
	{
		return	m_sphereSphereCF;
	}
#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
	if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1==BOX_SHAPE_PROXYTYPE))
	{
		return	m_sphereBoxCF;
	}

	if ((proxyType0 == BOX_SHAPE_PROXYTYPE ) && (proxyType1==SPHERE_SHAPE_PROXYTYPE))
	{
		return	m_boxSphereCF;
	}
#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM

	if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE ) && (proxyType1==TRIANGLE_SHAPE_PROXYTYPE))
	{
		return	m_sphereTriangleCF;
	}

	if ((proxyType0 == TRIANGLE_SHAPE_PROXYTYPE  ) && (proxyType1==SPHERE_SHAPE_PROXYTYPE))
	{
		return	m_triangleSphereCF;
	}

	if ((proxyType0 == BOX_SHAPE_PROXYTYPE) && (proxyType1 == BOX_SHAPE_PROXYTYPE))
	{
		return m_boxBoxCF;
	}

	if (btBroadphaseProxy::isConvex(proxyType0) && (proxyType1 == STATIC_PLANE_PROXYTYPE))
	{
		return m_convexPlaneCF;
	}

	if (btBroadphaseProxy::isConvex(proxyType1) && (proxyType0 == STATIC_PLANE_PROXYTYPE))
	{
		return m_planeConvexCF;
	}

	if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConvex(proxyType1))
	{
		return m_convexConvexCreateFunc;
	}

	if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConcave(proxyType1))
	{
		return m_convexConcaveCreateFunc;
	}

	if (btBroadphaseProxy::isConvex(proxyType1) && btBroadphaseProxy::isConcave(proxyType0))
	{
		return m_swappedConvexConcaveCreateFunc;
	}

	if (btBroadphaseProxy::isCompound(proxyType0))
	{
		return m_compoundCreateFunc;
	} else
	{
		if (btBroadphaseProxy::isCompound(proxyType1))
		{
			return m_swappedCompoundCreateFunc;
		}
	}

	//failed to find an algorithm
	return m_emptyCreateFunc;
}

void btDefaultCollisionConfiguration::setConvexConvexMultipointIterations(int numPerturbationIterations, int minimumPointsPerturbationThreshold)
{
	btConvexConvexAlgorithm::CreateFunc* convexConvex = (btConvexConvexAlgorithm::CreateFunc*) m_convexConvexCreateFunc;
	convexConvex->m_numPerturbationIterations = numPerturbationIterations;
	convexConvex->m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold;
}


{
	btConvexConvexAlgorithm::CreateFunc* convexConvex = (btConvexConvexAlgorithm::CreateFunc*) m_convexConvexCreateFunc;
	convexConvex->m_numPerturbationIterations = numPerturbationIterations;
	convexConvex->m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold;
}

/*
Bullet Continuous Collision Detection and Physics Library

*/

#include "btDefaultCollisionConfiguration.h"

#include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h"
#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
#include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h"
#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM
#include "BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h"
#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"

#include "LinearMath/btStackAlloc.h"
#include "LinearMath/btPoolAllocator.h"

btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo)
{

	void* mem = btAlignedAlloc(sizeof(btVoronoiSimplexSolver),16);
	m_simplexSolver = new (mem)btVoronoiSimplexSolver();

	if (constructionInfo.m_useEpaPenetrationAlgorithm)
	{
		mem = btAlignedAlloc(sizeof(btGjkEpaPenetrationDepthSolver),16);
		m_pdSolver = new (mem)btGjkEpaPenetrationDepthSolver;
	}else
	{
		mem = btAlignedAlloc(sizeof(btMinkowskiPenetrationDepthSolver),16);
		m_pdSolver = new (mem)btMinkowskiPenetrationDepthSolver;
	}

	//default CreationFunctions, filling the m_doubleDispatch table
	mem = btAlignedAlloc(sizeof(btConvexConvexAlgorithm::CreateFunc),16);
	m_convexConvexCreateFunc = new(mem) btConvexConvexAlgorithm::CreateFunc(m_simplexSolver,m_pdSolver);
	mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc),16);
	m_convexConcaveCreateFunc = new (mem)btConvexConcaveCollisionAlgorithm::CreateFunc;
	mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc),16);
	m_swappedConvexConcaveCreateFunc = new (mem)btConvexConcaveCollisionAlgorithm::SwappedCreateFunc;
	mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::CreateFunc),16);
	m_compoundCreateFunc = new (mem)btCompoundCollisionAlgorithm::CreateFunc;
	mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::SwappedCreateFunc),16);
	m_swappedCompoundCreateFunc = new (mem)btCompoundCollisionAlgorithm::SwappedCreateFunc;
	mem = btAlignedAlloc(sizeof(btEmptyAlgorithm::CreateFunc),16);
	m_emptyCreateFunc = new(mem) btEmptyAlgorithm::CreateFunc;

	mem = btAlignedAlloc(sizeof(btSphereSphereCollisionAlgorithm::CreateFunc),16);
	m_sphereSphereCF = new(mem) btSphereSphereCollisionAlgorithm::CreateFunc;
#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
	mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc),16);
	m_sphereBoxCF = new(mem) btSphereBoxCollisionAlgorithm::CreateFunc;
	mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc),16);
	m_boxSphereCF = new (mem)btSphereBoxCollisionAlgorithm::CreateFunc;
	m_boxSphereCF->m_swapped = true;
#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM

	mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc),16);
	m_sphereTriangleCF = new (mem)btSphereTriangleCollisionAlgorithm::CreateFunc;
	mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc),16);
	m_triangleSphereCF = new (mem)btSphereTriangleCollisionAlgorithm::CreateFunc;
	m_triangleSphereCF->m_swapped = true;

	mem = btAlignedAlloc(sizeof(btBoxBoxCollisionAlgorithm::CreateFunc),16);
	m_boxBoxCF = new(mem)btBoxBoxCollisionAlgorithm::CreateFunc;

	//convex versus plane
	mem = btAlignedAlloc (sizeof(btConvexPlaneCollisionAlgorithm::CreateFunc),16);
	m_convexPlaneCF = new (mem) btConvexPlaneCollisionAlgorithm::CreateFunc;
	mem = btAlignedAlloc (sizeof(btConvexPlaneCollisionAlgorithm::CreateFunc),16);
	m_planeConvexCF = new (mem) btConvexPlaneCollisionAlgorithm::CreateFunc;
	m_planeConvexCF->m_swapped = true;

	///calculate maximum element size, big enough to fit any collision algorithm in the memory pool
	int maxSize = sizeof(btConvexConvexAlgorithm);
	int maxSize2 = sizeof(btConvexConcaveCollisionAlgorithm);
	int maxSize3 = sizeof(btCompoundCollisionAlgorithm);
	int sl = sizeof(btConvexSeparatingDistanceUtil);
	sl = sizeof(btGjkPairDetector);
	int	collisionAlgorithmMaxElementSize = btMax(maxSize,constructionInfo.m_customCollisionAlgorithmMaxElementSize);
	collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize2);
	collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize3);

	if (constructionInfo.m_stackAlloc)
	{
		m_ownsStackAllocator = false;
		this->m_stackAlloc = constructionInfo.m_stackAlloc;
	} else
	{
		m_ownsStackAllocator = true;
		void* mem = btAlignedAlloc(sizeof(btStackAlloc),16);
		m_stackAlloc = new(mem)btStackAlloc(constructionInfo.m_defaultStackAllocatorSize);
	}

	if (constructionInfo.m_persistentManifoldPool)
	{
		m_ownsPersistentManifoldPool = false;
		m_persistentManifoldPool = constructionInfo.m_persistentManifoldPool;
	} else
	{
		m_ownsPersistentManifoldPool = true;
		void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16);
		m_persistentManifoldPool = new (mem) btPoolAllocator(sizeof(btPersistentManifold),constructionInfo.m_defaultMaxPersistentManifoldPoolSize);
	}

	if (constructionInfo.m_collisionAlgorithmPool)
	{
		m_ownsCollisionAlgorithmPool = false;
		m_collisionAlgorithmPool = constructionInfo.m_collisionAlgorithmPool;
	} else
	{
		m_ownsCollisionAlgorithmPool = true;
		void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16);
		m_collisionAlgorithmPool = new(mem) btPoolAllocator(collisionAlgorithmMaxElementSize,constructionInfo.m_defaultMaxCollisionAlgorithmPoolSize);
	}

}

btDefaultCollisionConfiguration::~btDefaultCollisionConfiguration()
{
	if (m_ownsStackAllocator)
	{
		m_stackAlloc->destroy();
		m_stackAlloc->~btStackAlloc();
		btAlignedFree(m_stackAlloc);
	}
	if (m_ownsCollisionAlgorithmPool)
	{
		m_collisionAlgorithmPool->~btPoolAllocator();
		btAlignedFree(m_collisionAlgorithmPool);
	}
	if (m_ownsPersistentManifoldPool)
	{
		m_persistentManifoldPool->~btPoolAllocator();
		btAlignedFree(m_persistentManifoldPool);
	}

	m_convexConvexCreateFunc->~btCollisionAlgorithmCreateFunc();
	btAlignedFree(	m_convexConvexCreateFunc);

	m_convexConcaveCreateFunc->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_convexConcaveCreateFunc);
	m_swappedConvexConcaveCreateFunc->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_swappedConvexConcaveCreateFunc);

	m_compoundCreateFunc->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_compoundCreateFunc);

	m_swappedCompoundCreateFunc->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_swappedCompoundCreateFunc);

	m_emptyCreateFunc->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_emptyCreateFunc);

	m_sphereSphereCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_sphereSphereCF);

#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
	m_sphereBoxCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_sphereBoxCF);
	m_boxSphereCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_boxSphereCF);
#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM

	m_sphereTriangleCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_sphereTriangleCF);
	m_triangleSphereCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_triangleSphereCF);
	m_boxBoxCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_boxBoxCF);

	m_convexPlaneCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_convexPlaneCF);
	m_planeConvexCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_planeConvexCF);

	m_simplexSolver->~btVoronoiSimplexSolver();
	btAlignedFree(m_simplexSolver);

	m_pdSolver->~btConvexPenetrationDepthSolver();

	btAlignedFree(m_pdSolver);

}

btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1)
{

	if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1==SPHERE_SHAPE_PROXYTYPE))
	{
		return	m_sphereSphereCF;
	}
#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
	if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1==BOX_SHAPE_PROXYTYPE))
	{
		return	m_sphereBoxCF;
	}

	if ((proxyType0 == BOX_SHAPE_PROXYTYPE ) && (proxyType1==SPHERE_SHAPE_PROXYTYPE))
	{
		return	m_boxSphereCF;
	}
#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM

	if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE ) && (proxyType1==TRIANGLE_SHAPE_PROXYTYPE))
	{
		return	m_sphereTriangleCF;
	}

	if ((proxyType0 == TRIANGLE_SHAPE_PROXYTYPE  ) && (proxyType1==SPHERE_SHAPE_PROXYTYPE))
	{
		return	m_triangleSphereCF;
	}

	if ((proxyType0 == BOX_SHAPE_PROXYTYPE) && (proxyType1 == BOX_SHAPE_PROXYTYPE))
	{
		return m_boxBoxCF;
	}

	if (btBroadphaseProxy::isConvex(proxyType0) && (proxyType1 == STATIC_PLANE_PROXYTYPE))
	{
		return m_convexPlaneCF;
	}

	if (btBroadphaseProxy::isConvex(proxyType1) && (proxyType0 == STATIC_PLANE_PROXYTYPE))
	{
		return m_planeConvexCF;
	}

	if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConvex(proxyType1))
	{
		return m_convexConvexCreateFunc;
	}

	if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConcave(proxyType1))
	{
		return m_convexConcaveCreateFunc;
	}

	if (btBroadphaseProxy::isConvex(proxyType1) && btBroadphaseProxy::isConcave(proxyType0))
	{
		return m_swappedConvexConcaveCreateFunc;
	}

	if (btBroadphaseProxy::isCompound(proxyType0))
	{
		return m_compoundCreateFunc;
	} else
	{
		if (btBroadphaseProxy::isCompound(proxyType1))
		{
			return m_swappedCompoundCreateFunc;
		}
	}

	//failed to find an algorithm
	return m_emptyCreateFunc;
}

void btDefaultCollisionConfiguration::setConvexConvexMultipointIterations(int numPerturbationIterations, int minimumPointsPerturbationThreshold)


/*
Bullet Continuous Collision Detection and Physics Library

*/

#include "btDefaultCollisionConfiguration.h"

#include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h"
#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
#include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h"
#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM
#include "BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h"
#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"

#include "LinearMath/btStackAlloc.h"
#include "LinearMath/btPoolAllocator.h"

btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo)
{

	void* mem = btAlignedAlloc(sizeof(btVoronoiSimplexSolver),16);
	m_simplexSolver = new (mem)btVoronoiSimplexSolver();

	if (constructionInfo.m_useEpaPenetrationAlgorithm)
	{
		mem = btAlignedAlloc(sizeof(btGjkEpaPenetrationDepthSolver),16);
		m_pdSolver = new (mem)btGjkEpaPenetrationDepthSolver;
	}else
	{
		mem = btAlignedAlloc(sizeof(btMinkowskiPenetrationDepthSolver),16);
		m_pdSolver = new (mem)btMinkowskiPenetrationDepthSolver;
	}

	//default CreationFunctions, filling the m_doubleDispatch table
	mem = btAlignedAlloc(sizeof(btConvexConvexAlgorithm::CreateFunc),16);
	m_convexConvexCreateFunc = new(mem) btConvexConvexAlgorithm::CreateFunc(m_simplexSolver,m_pdSolver);
	mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc),16);
	m_convexConcaveCreateFunc = new (mem)btConvexConcaveCollisionAlgorithm::CreateFunc;
	mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc),16);
	m_swappedConvexConcaveCreateFunc = new (mem)btConvexConcaveCollisionAlgorithm::SwappedCreateFunc;
	mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::CreateFunc),16);
	m_compoundCreateFunc = new (mem)btCompoundCollisionAlgorithm::CreateFunc;
	mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::SwappedCreateFunc),16);
	m_swappedCompoundCreateFunc = new (mem)btCompoundCollisionAlgorithm::SwappedCreateFunc;
	mem = btAlignedAlloc(sizeof(btEmptyAlgorithm::CreateFunc),16);
	m_emptyCreateFunc = new(mem) btEmptyAlgorithm::CreateFunc;

	mem = btAlignedAlloc(sizeof(btSphereSphereCollisionAlgorithm::CreateFunc),16);
	m_sphereSphereCF = new(mem)

#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
	mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc),16);
	m_sphereBoxCF = new(mem) btSphereBoxCollisionAlgorithm::CreateFunc;
	mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc),16);
	m_boxSphereCF = new (mem)btSphereBoxCollisionAlgorithm::CreateFunc;
	m_boxSphereCF->m_swapped = true;
#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM

	mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc),16);
	m_sphereTriangleCF = new (mem)btSphereTriangleCollisionAlgorithm::CreateFunc;
	mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc),16);
	m_triangleSphereCF = new (mem)btSphereTriangleCollisionAlgorithm::CreateFunc;
	m_triangleSphereCF->m_swapped = true;

	mem = btAlignedAlloc(sizeof(btBoxBoxCollisionAlgorithm::CreateFunc),16);
	m_boxBoxCF = new(mem)btBoxBoxCollisionAlgorithm::CreateFunc;

	//convex versus plane
	mem = btAlignedAlloc (sizeof(btConvexPlaneCollisionAlgorithm::CreateFunc),16);
	m_convexPlaneCF = new (mem) btConvexPlaneCollisionAlgorithm::CreateFunc;
	mem = btAlignedAlloc (sizeof(btConvexPlaneCollisionAlgorithm::CreateFunc),16);
	m_planeConvexCF = new (mem) btConvexPlaneCollisionAlgorithm::CreateFunc;
	m_planeConvexCF->m_swapped = true;

	///calculate maximum element size, big enough to fit any collision algorithm in the memory pool
	int maxSize = sizeof(btConvexConvexAlgorithm);
	int maxSize2 = sizeof(btConvexConcaveCollisionAlgorithm);
	int maxSize3 = sizeof(btCompoundCollisionAlgorithm);
	int sl = sizeof(btConvexSeparatingDistanceUtil);
	sl = sizeof(btGjkPairDetector);
	int	collisionAlgorithmMaxElementSize = btMax(maxSize,constructionInfo.m_customCollisionAlgorithmMaxElementSize);
	collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize2);
	collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize3);

	if (constructionInfo.m_stackAlloc)
	{
		m_ownsStackAllocator = false;
		this->m_stackAlloc = constructionInfo.m_stackAlloc;
	} else
	{
		m_ownsStackAllocator = true;
		void* mem = btAlignedAlloc(sizeof(btStackAlloc),16);
		m_stackAlloc = new(mem)btStackAlloc(constructionInfo.m_defaultStackAllocatorSize);
	}

	if (constructionInfo.m_persistentManifoldPool)
	{
		m_ownsPersistentManifoldPool = false;
		m_persistentManifoldPool = constructionInfo.m_persistentManifoldPool;
	} else
	{
		m_ownsPersistentManifoldPool = true;
		void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16);
		m_persistentManifoldPool = new (mem) btPoolAllocator(sizeof(btPersistentManifold),constructionInfo.m_defaultMaxPersistentManifoldPoolSize);
	}

	if (constructionInfo.m_collisionAlgorithmPool)
	{
		m_ownsCollisionAlgorithmPool = false;
		m_collisionAlgorithmPool = constructionInfo.m_collisionAlgorithmPool;
	} else
	{
		m_ownsCollisionAlgorithmPool = true;
		void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16);
		m_collisionAlgorithmPool = new(mem) btPoolAllocator(collisionAlgorithmMaxElementSize,constructionInfo.m_defaultMaxCollisionAlgorithmPoolSize);
	}

}

btDefaultCollisionConfiguration::~btDefaultCollisionConfiguration()
{
	if (m_ownsStackAllocator)
	{
		m_stackAlloc->destroy();
		m_stackAlloc->~btStackAlloc();
		btAlignedFree(m_stackAlloc);
	}
	if (m_ownsCollisionAlgorithmPool)
	{
		m_collisionAlgorithmPool->~btPoolAllocator();
		btAlignedFree(m_collisionAlgorithmPool);
	}
	if (m_ownsPersistentManifoldPool)
	{
		m_persistentManifoldPool->~btPoolAllocator();
		btAlignedFree(m_persistentManifoldPool);
	}

	m_convexConvexCreateFunc->~btCollisionAlgorithmCreateFunc();
	btAlignedFree(	m_convexConvexCreateFunc);

	m_convexConcaveCreateFunc->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_convexConcaveCreateFunc);
	m_swappedConvexConcaveCreateFunc->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_swappedConvexConcaveCreateFunc);

	m_compoundCreateFunc->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_compoundCreateFunc);

	m_swappedCompoundCreateFunc->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_swappedCompoundCreateFunc);

	m_emptyCreateFunc->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_emptyCreateFunc);

	m_sphereSphereCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_sphereSphereCF);

#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
	m_sphereBoxCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_sphereBoxCF);
	m_boxSphereCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_boxSphereCF);
#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM

	m_sphereTriangleCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_sphereTriangleCF);
	m_triangleSphereCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_triangleSphereCF);
	m_boxBoxCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_boxBoxCF);

	m_convexPlaneCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_convexPlaneCF);
	m_planeConvexCF->~btCollisionAlgorithmCreateFunc();
	btAlignedFree( m_planeConvexCF);

	m_simplexSolver->~btVoronoiSimplexSolver();
	btAlignedFree(m_simplexSolver);

	m_pdSolver->~btConvexPenetrationDepthSolver();

	btAlignedFree(m_pdSolver);

}

btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1)
{

	if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1==SPHERE_SHAPE_PROXYTYPE))
	{
		return	m_sphereSphereCF;
	}
#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
	if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1==BOX_SHAPE_PROXYTYPE))
	{
		return	m_sphereBoxCF;
	}

	if ((proxyType0 == BOX_SHAPE_PROXYTYPE ) && (proxyType1==SPHERE_SHAPE_PROXYTYPE))
	{
		return	m_boxSphereCF;
	}
#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM

	if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE ) && (proxyType1==TRIANGLE_SHAPE_PROXYTYPE))
	{
		return	m_sphereTriangleCF;
	}

	if ((proxyType0 == TRIANGLE_SHAPE_PROXYTYPE  ) && (proxyType1==SPHERE_SHAPE_PROXYTYPE))
	{
		return	m_triangleSphereCF;
	}

	if ((proxyType0 == BOX_SHAPE_PROXYTYPE) && (proxyType1 == BOX_SHAPE_PROXYTYPE))
	{
		return m_boxBoxCF;
	}

	if (btBroadphaseProxy::isConvex(proxyType0) && (proxyType1 == STATIC_PLANE_PROXYTYPE))
	{
		return m_convexPlaneCF;
	}

	if (btBroadphaseProxy::isConvex(proxyType1) && (proxyType0 == STATIC_PLANE_PROXYTYPE))
	{
		return m_planeConvexCF;
	}

	if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConvex(proxyType1))
	{
		return m_convexConvexCreateFunc;
	}

	if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConcave(proxyType1))
	{
		return m_convexConcaveCreateFunc;
	}

	if (btBroadphaseProxy::isConvex(proxyType1) && btBroadphaseProxy::isConcave(proxyType0))
	{
		return m_swappedConvexConcaveCreateFunc;
	}

	if (btBroadphaseProxy::isCompound(proxyType0))
	{
		return m_compoundCreateFunc;
	} else
	{
		if (btBroadphaseProxy::isCompound(proxyType1))
		{
			return m_swappedCompoundCreateFunc;
		}
	}

	//failed to find an algorithm
	return m_emptyCreateFunc;
}

void btDefaultCollisionConfiguration::setConvexConvexMultipointIterations(int numPerturbationIterations, int minimumPointsPerturbationThreshold)
{
	btConvexConvexAlgorithm::CreateFunc* convexConvex = (btConvexConvexAlgorithm::CreateFunc*) m_convexConvexCreateFunc;
	convexConvex->m_numPerturbationIterations = numPerturbationIterations;
	convexConvex->m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold;
}


/*
 *
 *  This file is part of crtmpserver.
 */

#include "protocols/httpbuff/httpbufferprotocol.h"
#include "protocols/protocolfactory.h"
#include "protocols/http/outboundhttpprotocol.h"
#include "clientcontext.h"
#include "protocols/tcpprotocol.h"
using namespace app_applestreamingclient;

HTTPBufferProtocol::HTTPBufferProtocol()
: GenericProtocol(PT_HTTP_BUFF) {
	_lastTimestamp = 0;
	_lastAmount = 0;
	_isEncrypted = false;
}

HTTPBufferProtocol::~HTTPBufferProtocol() {
}

{
	return type == PT_OUTBOUND_HTTP;
}

bool HTTPBufferProtocol::AllowNearProtocol(uint64_t type) {
	_isEncrypted = (type == PT_INBOUND_AES);
	return true;
}

bool HTTPBufferProtocol::SignalInputData(int32_t recvAmount) {
	NYIR;
}

bool HTTPBufferProtocol::SignalInputData(IOBuffer &buffer) {
	//1. Get the context
	ClientContext *pContext = GetContext();
	if (pContext == NULL) {
		FATAL("Unable to get context");
		return false;
	}

	//2. Compute the speed
	double currentTimestamp = 0;
	GETCLOCKS(currentTimestamp);

	if (_lastTimestamp != 0) {
		double instantTime = currentTimestamp - _lastTimestamp;
		double instantAmount = ((TCPProtocol *) GetFarEndpoint())->GetDecodedBytesCount() - _lastAmount;

		pContext->SignalSpeedDetected(instantAmount, instantTime / CLOCKS_PER_SECOND);
	}

	_lastAmount = ((TCPProtocol *) GetFarEndpoint())->GetDecodedBytesCount();
	GETCLOCKS(_lastTimestamp);

	if (_isEncrypted) {
		if (!GetNearProtocol()->SignalInputData(buffer)) {
			FATAL("Unable to signal upper protocols");
			return false;
		}
	} else {
		ClientContext *pContext = GetContext();
		if (pContext == NULL) {
			FATAL("Unable to get context");
			return false;
		}

		if (!pContext->SignalAVDataAvailable(buffer)) {
			FATAL("Unable to signal ts A/V data available");
			return false;
		}
	}

	//10. Signal the context about this finished chunk
	if (TransferCompleted()) {
		EnqueueForDelete();
		ClientContext *pContext = GetContext();
		if (pContext == NULL) {
			FATAL("Unable to get context");
			return false;
		}

		if (!pContext->SignalTSChunkComplete(GetNearProtocol()->GetId())) {
			FATAL("Unable to signal ts chunk complete");
			return false;
		}
	}

	return true;
}

bool HTTPBufferProtocol::TransferCompleted() {
	return ((OutboundHTTPProtocol *) GetFarProtocol())->TransferCompleted();
}


/*
 *
 *  This file is part of crtmpserver.
 */

#include "protocols/httpbuff/httpbufferprotocol.h"
#include "protocols/protocolfactory.h"
#include "protocols/http/outboundhttpprotocol.h"
#include "clientcontext.h"
#include "protocols/tcpprotocol.h"
using namespace app_applestreamingclient;

HTTPBufferProtocol::HTTPBufferProtocol()
: GenericProtocol(PT_HTTP_BUFF) {
	_lastTimestamp = 0;
	_lastAmount = 0;
	_isEncrypted = false;
}

HTTPBufferProtocol::~HTTPBufferProtocol()

bool HTTPBufferProtocol::AllowFarProtocol(uint64_t type) {
	return type == PT_OUTBOUND_HTTP;
}

bool HTTPBufferProtocol::AllowNearProtocol(uint64_t type) {
	_isEncrypted = (type == PT_INBOUND_AES);
	return true;
}

bool HTTPBufferProtocol::SignalInputData(int32_t recvAmount) {
	NYIR;
}

bool HTTPBufferProtocol::SignalInputData(IOBuffer &buffer) {
	//1. Get the context
	ClientContext *pContext = GetContext();
	if (pContext == NULL) {
		FATAL("Unable to get context");
		return false;
	}

	//2. Compute the speed
	double currentTimestamp = 0;
	GETCLOCKS(currentTimestamp);

	if (_lastTimestamp != 0) {
		double instantTime = currentTimestamp - _lastTimestamp;
		double instantAmount = ((TCPProtocol *) GetFarEndpoint())->GetDecodedBytesCount() - _lastAmount;

		pContext->SignalSpeedDetected(instantAmount, instantTime / CLOCKS_PER_SECOND);
	}

	_lastAmount = ((TCPProtocol *) GetFarEndpoint())->GetDecodedBytesCount();
	GETCLOCKS(_lastTimestamp);

	if (_isEncrypted) {
		if (!GetNearProtocol()->SignalInputData(buffer)) {
			FATAL("Unable to signal upper protocols");
			return false;
		}
	} else {
		ClientContext *pContext = GetContext();
		if (pContext == NULL) {
			FATAL("Unable to get context");
			return false;
		}

		if (!pContext->SignalAVDataAvailable(buffer)) {
			FATAL("Unable to signal ts A/V data available");
			return false;
		}
	}

	//10. Signal the context about this finished chunk
	if (TransferCompleted()) {
		EnqueueForDelete();
		ClientContext *pContext = GetContext();
		if (pContext == NULL) {
			FATAL("Unable to get context");
			return false;
		}

		if (!pContext->SignalTSChunkComplete(GetNearProtocol()->GetId())) {
			FATAL("Unable to signal ts chunk complete");
			return false;
		}
	}

	return true;
}

bool HTTPBufferProtocol::TransferCompleted() {
	return ((OutboundHTTPProtocol *) GetFarProtocol())->TransferCompleted();
}


/*
 *
 *  This file is part of crtmpserver.
 */

#include "protocols/httpbuff/httpbufferprotocol.h"
#include "protocols/protocolfactory.h"
#include "protocols/http/outboundhttpprotocol.h"
#include "clientcontext.h"
#include "protocols/tcpprotocol.h"
using namespace app_applestreamingclient;

HTTPBufferProtocol::HTTPBufferProtocol()
: GenericProtocol(PT_HTTP_BUFF) {
	_las

	_lastAmount = 0;
	_isEncrypted = false;
}

HTTPBufferProtocol::~HTTPBufferProtocol() {
}

bool HTTPBufferProtocol::AllowFarProtocol(uint64_t type) {
	return type == PT_OUTBOUND_HTTP;
}

bool HTTPBufferProtocol::AllowNearProtocol(uint64_t type) {
	_isEncrypted = (type == PT_INBOUND_AES);
	return true;
}

bool HTTPBufferProtocol::SignalInputData(int32_t recvAmount) {
	NYIR;
}

bool HTTPBufferProtocol::SignalInputData(IOBuffer &buffer) {
	//1. Get the context
	ClientContext *pContext = GetContext();
	if (pContext == NULL) {
		FATAL("Unable to get context");
		return false;
	}

	//2. Compute the speed
	double currentTimestamp = 0;
	GETCLOCKS(currentTimestamp);

	if (_lastTimestamp != 0) {
		double instantTime = currentTimestamp - _lastTimestamp;
		double instantAmount = ((TCPProtocol *) GetFarEndpoint())->GetDecodedBytesCount() - _lastAmount;

		pContext->SignalSpeedDetected(instantAmount, instantTime / CLOCKS_PER_SECOND);
	}

	_lastAmount = ((TCPProtocol *) GetFarEndpoint())->GetDecodedBytesCount();
	GETCLOCKS(_lastTimestamp);

	if (_isEncrypted) {
		if (!GetNearProtocol()->SignalInputData(buffer)) {
			FATAL("Unable to signal upper protocols");
			return false;
		}
	} else {
		ClientContext *pContext = GetContext();
		if (pContext == NULL) {
			FATAL("Unable to get context");
			return false;
		}

		if (!pContext->SignalAVDataAvailable(buffer)) {
			FATAL("Unable to signal ts A/V data available");
			return false;
		}
	}

	//10. Signal the context about this finished chunk
	if (TransferCompleted()) {
		EnqueueForDelete();
		ClientContext *pContext = GetContext();
		if (pContext == NULL) {
			FATAL("Unable to get context");
			return false;
		}

		if (!pContext->SignalTSChunkComplete(GetNearProtocol()->GetId())) {
			FATAL("Unable to signal ts chunk complete");
			return false;
		}
	}

	return true;
}

bool HTTPBufferProtocol::TransferCompleted() {
	return ((OutboundHTTPProtocol *) GetFarProtocol())->TransferCompleted();
}


/*
 * OpenClonk, http://www.openclonk.org
 *
 *
 *
 * See accompanying file "TRADEMARK" for details.
 *
 * To redistribute this file separately, substitute the full license texts
 * for the above references.
 */
// links aul scripts; i.e. resolves includes & appends, etc

#include "C4Include.h"
#include "script/C4Aul.h"

#include "game/C4Game.h"
#include "landscape/C4Material.h"
#include "object/C4Def.h"
#include "object/C4DefList.h"
#include "object/C4GameObjects.h"
#include "script/C4Effect.h"

void C4ScriptHost::DoAppend(C4Def *def)
{
	if (std::find(def->Script.SourceScripts.begin(), def->Script.SourceScripts.end(), this) == def->Script.SourceScripts.end())
	{
		def->Script.SourceScripts.push_back(this);
		if (!Includes.empty())
		{
			Warn("#appendto contains #include");
			// Try to fullfil #include, but it won't work properly: #appendtos
			// are always appended, but #includes are prepended to the script.
			def->Script.Includes.insert(def->Script.Includes.end(), Includes.begin(), Includes.end());
		}

	}
}

// ResolveAppends and ResolveIncludes must be called both
// for each script. ResolveAppends has to be called first!
bool C4ScriptHost::ResolveAppends(C4DefList *rDefs)
{
	// resolve local appends
	if (State != ASS_PREPARSED) return false;
	for (auto & Append : Appends)
	{
		if (Append != "*" || !rDefs)
		{
			C4Def *Def = rDefs ? rDefs->GetByName(Append) : nullptr;
			if (Def)
			{
				DoAppend(Def);
			}
			else
			{
				// save id in buffer because AulWarn will use the buffer of C4IdText
				// to get the id of the object in which the error occurs...
				Warn("#appendto %s not found", Append.getData());
			}
		}
		else
		{
			// append to all defs
			for (int i = 0; i < rDefs->GetDefCount(); i++)
			{
				C4Def *pDef = rDefs->GetDef(i);
				if (!pDef) break;
				if (pDef == GetPropList()) continue;
				// append
				DoAppend(pDef);
			}
		}
	}
	return true;
}

bool C4ScriptHost::ResolveIncludes(C4DefList *rDefs)
{
	// Had been preparsed?
	if (State != ASS_PREPARSED) return false;
	// has already been resolved?
	if (IncludesResolved) return true;
	// catch circular includes
	if (Resolving)
	{
		Engine->GetErrorHandler()->OnError(C4AulParseError(this, "Circular include chain detected - ignoring all includes!").what());
		IncludesResolved = true;
		State = ASS_LINKED;
		return false;
	}
	Resolving=true;
	// append all includes to local script
	for (std::list<StdCopyStrBuf>::reverse_iterator i = Includes.rbegin(); i != Includes.rend(); ++i)
	{
		C4Def *Def = rDefs ? rDefs->GetByName(*i) : nullptr;
		if (Def)
		{
			// resolve #includes in included script first (#include-chains :( )
			if (!Def->Script.IncludesResolved)
				if (!Def->Script.ResolveIncludes(rDefs))
					continue; // skip this #include

			for (auto s = Def->Script.SourceScripts.rbegin(); s != Def->Script.SourceScripts.rend(); ++s)
			{
				if (std::find(SourceScripts.begin(), SourceScripts.end(), *s) == SourceScripts.end())
					SourceScripts.push_front(*s);
			}
		}
		else
		{
			// save id in buffer because AulWarn will use the buffer of C4IdText
			// to get the id of the object in which the error occurs...
			Warn("#include %s not found", i->getData());
		}
	}
	IncludesResolved = true;
	// includes/appends are resolved now (for this script)
	Resolving=false;
	State = ASS_LINKED;
	return true;
}

{
	C4PropList * p = GetPropList();
	if (p)
	{
		p->C4PropList::Clear();
		p->SetProperty(P_Prototype, C4VPropList(Engine->GetPropList()));
	}

	// Delete cyclic references of owned proplists
	DeleteOwnedPropLists();

	// includes will have to be re-resolved now
	IncludesResolved = false;

	if (State > ASS_PREPARSED) State = ASS_PREPARSED;
}

void C4AulScriptEngine::UnLink()
{
	warnCnt = errCnt = lineCnt = 0;

	// Make everything writeable
	GetPropList()->ThawRecursively();
	for (C4ScriptHost *s = Child0; s; s = s->Next)
		s->GetPropList()->ThawRecursively();

	// unlink scripts
	for (C4ScriptHost *s = Child0; s; s = s->Next)
		s->UnLink();
	// Do not clear global variables and constants, because they are registered by the
	// preparser or other parts. Note that keeping those fields means that you cannot delete a global
	// variable or constant at runtime by removing it from the script.
}

void C4AulScriptEngine::Link(C4DefList *rDefs)
{
	try
	{
		// resolve appends
		for (C4ScriptHost *s = Child0; s; s = s->Next)
			s->ResolveAppends(rDefs);

		// resolve includes
		for (C4ScriptHost *s = Child0; s; s = s->Next)
			s->ResolveIncludes(rDefs);

		// parse the scripts to byte code
		for (C4ScriptHost *s = Child0; s; s = s->Next)
			s->Parse();

		if (rDefs)
		{
			rDefs->SortByPriority();
			rDefs->CallEveryDefinition();
		}

		// Done modifying the proplists now
		for (C4ScriptHost *s = Child0; s; s = s->Next)
			s->GetPropList()->FreezeAndMakeStaticRecursively(&s->ownedPropLists);

		GetPropList()->FreezeAndMakeStaticRecursively(&OwnedPropLists);
	}
	catch (C4AulError &err)
	{
		ErrorHandler->OnError(err.what());
	}

	// Set name list for globals (FIXME: is this necessary?)
	ScriptEngine.GlobalNamed.SetNameList(&ScriptEngine.GlobalNamedNames);
}

void C4AulScriptEngine::ReLink(C4DefList *rDefs)
{
	// unlink scripts
	UnLink();

	// unlink defs
	if (rDefs) rDefs->ResetIncludeDependencies();

	// re-link
	Link(rDefs);

	// display state
	LogF("C4AulScriptEngine linked - %d line%s, %d warning%s, %d error%s",
		lineCnt, (lineCnt != 1 ? "s" : ""), warnCnt, (warnCnt != 1 ? "s" : ""), errCnt, (errCnt != 1 ? "s" : ""));

	// adjust global effects
	if (pGlobalEffects) pGlobalEffects->ReAssignAllCallbackFunctions();
	if (GameScript.pScenarioEffects) GameScript.pScenarioEffects->ReAssignAllCallbackFunctions();
}

bool C4AulScriptEngine::ReloadScript(const char *szScript, const char *szLanguage)
{
	C4ScriptHost * s;
	for (s = Child0; s; s = s->Next)
		if (s->ReloadScript(szScript, szLanguage))
			break;
	return !!s;
}


{
	C4PropList * p = GetPropList();
	if (p)
	{
		p->C4PropList::Clear();
		p->SetProperty(P_Prototype, C4VPropList(Engine->GetPropList()));
	}

	// Delete cyclic references of owned proplists
	DeleteOwnedPropLists();

	// includes will have to be re-resolved now
	IncludesResolved = false;

	if (State > ASS_PREPARSED) State = ASS_PREPARSED;
}

/*
 * OpenClonk, http://www.openclonk.org
 *
 *
 *
 * See accompanying file "TRADEMARK" for details.
 *
 * To redistribute this file separately, substitute the full license texts
 * for the above references.
 */
// links aul scripts; i.e. resolves includes & appends, etc

#include "C4Include.h"
#include "script/C4Aul.h"

#include "game/C4Game.h"
#include "landscape/C4Material.h"
#include "object/C4Def.h"
#include "object/C4DefList.h"
#include "object/C4GameObjects.h"
#include "script/C4Effect.h"

void C4ScriptHost::DoAppend(C4Def *def)
{
	if (std::find(def->Script.SourceScripts.begin(), def->Script.SourceScripts.end(), this) == def->Script.SourceScripts.end())
	{
		def->Script.SourceScripts.push_back(this);
		if (!Includes.empty())
		{
			Warn("#appendto contains #include");
			// Try to fullfil #include, but it won't work properly: #appendtos
			// are always appended, but #includes are prepended to the script.
			def->Script.Includes.insert(def->Script.Includes.end(), Includes.begin(), Includes.end());
		}

	}
}

// ResolveAppends and ResolveIncludes must be called both
// for each script. ResolveAppends has to be called first!
bool C4ScriptHost::ResolveAppends(C4DefList *rDefs)
{
	// resolve local appends
	if (State != ASS_PREPARSED) return false;
	for (auto & Append : Appends)
	{
		if (Append != "*" || !rDefs)
		{
			C4Def *Def = rDefs ? rDefs->GetByName(Append) : nullptr;
			if (Def)
			{
				DoAppend(Def);
			}
			else
			{
				// save id in buffer because AulWarn will use the buffer of C4IdText
				// to get the id of the object in which the error occurs...
				Warn("#appendto %s not found", Append.getData());
			}
		}
		else
		{
			// append to all defs
			for (int i = 0; i < rDefs->GetDefCount(); i++)
			{
				C4Def *pDef = rDefs->GetDef(i);
				if (!pDef) break;
				if (pDef == GetPropList()) continue;
				// append
				DoAppend(pDef);
			}
		}
	}
	return true;
}

bool C4ScriptHost::ResolveIncludes(C4DefList *rDefs)
{
	// Had been preparsed?
	if (State != ASS_PREPARSED) return false;
	// has already been resolved?
	if (IncludesResolved) return true;
	// catch circular includes
	if (Resolving)
	{
		Engine->GetErrorHandler()->OnError(C4AulParseError(this, "Circular include chain detected - ignoring all includes!").what());
		IncludesResolved = true;
		State = ASS_LINKED;
		return false;
	}
	Resolving=true;
	// append all includes to local script
	for (std::list<StdCopyStrBuf>::reverse_iterator i = Includes.rbegin(); i != Includes.rend(); ++i)
	{
		C4Def *Def = rDefs ? rDefs->GetByName(*i) : nullptr;
		if (Def)
		{
			// resolve #includes in included script first (#include-chains :( )
			if (!Def->Script.IncludesResolved)
				if (!Def->Script.ResolveIncludes(rDefs))
					continue; // skip this #include

			for (auto s = Def->Script.SourceScripts.rbegin(); s != Def->Script.SourceScripts.rend(); ++s)
			{
				if (std::find(SourceScripts.begin(), SourceScripts.end(), *s) == SourceScripts.end())
					SourceScripts.push_front(*s);
			}
		}
		else
		{
			// save id in buffer because AulWarn will use the buffer of C4IdText
			// to get the id of the object in which the error occurs...
			Warn("#include %s not found", i->getData());
		}
	}
	IncludesResolved = true;
	// includes/appends are resolved now (for this script)
	Resolving=false;
	State = ASS_LINKED;
	return true;
}

void C4ScriptHost::UnLink()

void C4AulScriptEngine::UnLink()
{
	warnCnt = errCnt = lineCnt = 0;

	// Make everything writeable
	GetPropList()->ThawRecursively();
	for (C4ScriptHost *s = Child0; s; s = s->Next)
		s->GetPropList()->ThawRecursively();

	// unlink scripts
	for (C4ScriptHost *s = Child0; s; s = s->Next)
		s->UnLink();
	// Do not clear global variables and constants, because they are registered by the
	// preparser or other parts. Note that keeping those fields means that you cannot delete a global
	// variable or constant at runtime by removing it from the script.
}

void C4AulScriptEngine::Link(C4DefList *rDefs)
{
	try
	{
		// resolve appends
		for (C4ScriptHost *s = Child0; s; s = s->Next)
			s->ResolveAppends(rDefs);

		// resolve includes
		for (C4ScriptHost *s = Child0; s; s = s->Next)
			s->ResolveIncludes(rDefs);

		// parse the scripts to byte code
		for (C4ScriptHost *s = Child0; s; s = s->Next)
			s->Parse();

		if (rDefs)
		{
			rDefs->SortByPriority();
			rDefs->CallEveryDefinition();
		}

		// Done modifying the proplists now
		for (C4ScriptHost *s = Child0; s; s = s->Next)
			s->GetPropList()->FreezeAndMakeStaticRecursively(&s->ownedPropLists);

		GetPropList()->FreezeAndMakeStaticRecursively(&OwnedPropLists);
	}
	catch (C4AulError &err)
	{
		ErrorHandler->OnError(err.what());
	}

	// Set name list for globals (FIXME: is this necessary?)
	ScriptEngine.GlobalNamed.SetNameList(&ScriptEngine.GlobalNamedNames);
}

void C4AulScriptEngine::ReLink(C4DefList *rDefs)
{
	// unlink scripts
	UnLink();

	// unlink defs
	if (rDefs) rDefs->ResetIncludeDependencies();

	// re-link
	Link(rDefs);

	// display state
	LogF("C4AulScriptEngine linked - %d line%s, %d warning%s, %d error%s",
		lineCnt, (lineCnt != 1 ? "s" : ""), warnCnt, (warnCnt != 1 ? "s" : ""), errCnt, (errCnt != 1 ? "s" : ""));

	// adjust global effects
	if (pGlobalEffects) pGlobalEffects->ReAssignAllCallbackFunctions();
	if (GameScript.pScenarioEffects) GameScript.pScenarioEffects->ReAssignAllCallbackFunctions();
}

bool C4AulScriptEngine::ReloadScript(const char *szScript, const char *szLanguage)
{
	C4ScriptHost * s;
	for (s = Child0; s; s = s->Next)
		if (s->ReloadScript(szScript, szLanguage))
			break;
	return !!s;
}


/*
 * OpenClonk, http://www.openclonk.org
 *
 *
 *
 * See accompanying file "TRADEMARK" for details.
 *
 * To redistribute this file separately, substitute the full license texts
 * for the above references.
 */
// links aul scripts; i.e. resolves includes & appends, etc

#include "C4Include.h"
#include "script/C4Aul.h"

#include "game/C4Game.h"
#include "landscape/C4Material.h"
#include "object/C4Def.h"
#include "object/C4DefList.h"
#include "object/C4GameObjects.h"
#include "script/C4Effect.h"

void C4ScriptHost::DoAppend(C4Def *def)
{
	if (std::find(def->Script.SourceScripts.begin(), def->Script.SourceScripts.end(), this) == def->Script.SourceScripts.end())
	{
		def->Script.SourceScripts.push_back(this);
		if (!Includes.empty())
		{
			Warn("#appendto contains #include");
			// Try to fullfil #include, but it won't work properly: #appendtos
			// are always appended, but #includes are prepended to the script.
			def->Script.Includes.insert(def->Script.Includes.end(), Includes.begin(), Includes.end());
		}

	}
}

// ResolveAppends and ResolveIncludes must be called both
// for each script. ResolveAppends has to be called first!
bool C4ScriptHost::ResolveAppends(C4DefList *rDefs)
{
	// resolve local appends
	if (State != ASS_PREPARSED) return false;
	for (auto & Append : Appends)
	{
		if (Append != "*" || !rDefs)
		{
			C4Def *Def = rDefs ? rDefs->GetByName(Append) : nullptr;
			if (Def)
			{
				DoAppend(Def);
			}
			else
			{
				// save id in buffer because AulWarn will use the buffer of C4IdText
				// to get the id of the object in which the error occurs...
				Warn("#appendto %s not found", Append.getData());
			}
		}
		else
		{
			// append to all defs
			for (int i = 0; i < rDefs->GetDefCount(); i++)
			{
				C4Def *pDef = rDefs->GetDef(i);
				if (!pDef) break;
				if (pDef == GetPropList()) continue;
				// append
				DoAppend(pDef);
			}
		}
	}
	return true;
}

bool C4ScriptHost::ResolveIncludes(C4DefList *rDefs)
{
	// Had been preparsed?
	if (State != ASS_PREPARSED) return false;
	// has already been resolved?
	if (IncludesResolved) return true;
	// catch circular includes
	if (Resolving)
	{
		Engine->GetErrorHandler()->OnError(C4AulParseError(this, "Circular include chain detected - ignoring all includes!").what());
		IncludesResolved = true;
		State = ASS_LINKED;
		return false;
	}
	Resolving=true;
	// append all includes to local script
	for (std::list<StdCopyStrBuf>::reverse_iterator i = Includes.rbegin(); i != Includes.rend(); ++i)
	{
		C4Def *Def = rDefs ? rDefs->GetByName(*i) : nullptr;
		if (Def)
		{
			// resolve #includes in included script first (#include-chains :( )
			if (!Def->Script.IncludesResolved)
				if (!Def->Script.ResolveIncludes(rDefs))
					continue; // skip this #include

			for (auto s = Def->Script.SourceScripts.rbegin(); s != Def->Script.SourceScripts.rend(); ++s)
			{
				if (std::find(SourceScripts.begin(), SourceScripts.end(), *s) == SourceScripts.end())
					SourceScripts.push_front(*s);
			}
		}
		else
		{
			// save id in buffer because AulWarn will use the buffer of C4IdText
			// to get the id of the object in which the error occurs...
			Warn("#include %s not found", i->getData());
		}
	}
	IncludesResolved = true;
	// includes/appends are resolved now (for this script)
	Resolving=false;
	Stat

	return true;
}

void C4ScriptHost::UnLink()
{
	C4PropList * p = GetPropList();
	if (p)
	{
		p->C4PropList::Clear();
		p->SetProperty(P_Prototype, C4VPropList(Engine->GetPropList()));
	}

	// Delete cyclic references of owned proplists
	DeleteOwnedPropLists();

	// includes will have to be re-resolved now
	IncludesResolved = false;

	if (State > ASS_PREPARSED) State = ASS_PREPARSED;
}

void C4AulScriptEngine::UnLink()
{
	warnCnt = errCnt = lineCnt = 0;

	// Make everything writeable
	GetPropList()->ThawRecursively();
	for (C4ScriptHost *s = Child0; s; s = s->Next)
		s->GetPropList()->ThawRecursively();

	// unlink scripts
	for (C4ScriptHost *s = Child0; s; s = s->Next)
		s->UnLink();
	// Do not clear global variables and constants, because they are registered by the
	// preparser or other parts. Note that keeping those fields means that you cannot delete a global
	// variable or constant at runtime by removing it from the script.
}

void C4AulScriptEngine::Link(C4DefList *rDefs)
{
	try
	{
		// resolve appends
		for (C4ScriptHost *s = Child0; s; s = s->Next)
			s->ResolveAppends(rDefs);

		// resolve includes
		for (C4ScriptHost *s = Child0; s; s = s->Next)
			s->ResolveIncludes(rDefs);

		// parse the scripts to byte code
		for (C4ScriptHost *s = Child0; s; s = s->Next)
			s->Parse();

		if (rDefs)
		{
			rDefs->SortByPriority();
			rDefs->CallEveryDefinition();
		}

		// Done modifying the proplists now
		for (C4ScriptHost *s = Child0; s; s = s->Next)
			s->GetPropList()->FreezeAndMakeStaticRecursively(&s->ownedPropLists);

		GetPropList()->FreezeAndMakeStaticRecursively(&OwnedPropLists);
	}
	catch (C4AulError &err)
	{
		ErrorHandler->OnError(err.what());
	}

	// Set name list for globals (FIXME: is this necessary?)
	ScriptEngine.GlobalNamed.SetNameList(&ScriptEngine.GlobalNamedNames);
}

void C4AulScriptEngine::ReLink(C4DefList *rDefs)
{
	// unlink scripts
	UnLink();

	// unlink defs
	if (rDefs) rDefs->ResetIncludeDependencies();

	// re-link
	Link(rDefs);

	// display state
	LogF("C4AulScriptEngine linked - %d line%s, %d warning%s, %d error%s",
		lineCnt, (lineCnt != 1 ? "s" : ""), warnCnt, (warnCnt != 1 ? "s" : ""), errCnt, (errCnt != 1 ? "s" : ""));

	// adjust global effects
	if (pGlobalEffects) pGlobalEffects->ReAssignAllCallbackFunctions();
	if (GameScript.pScenarioEffects) GameScript.pScenarioEffects->ReAssignAllCallbackFunctions();
}

bool C4AulScriptEngine::ReloadScript(const char *szScript, const char *szLanguage)
{
	C4ScriptHost * s;
	for (s = Child0; s; s = s->Next)
		if (s->ReloadScript(szScript, szLanguage))
			break;
	return !!s;
}


for (C4ScriptHost *s = Child0; s; s = s->Next)
		s->UnLink();

/*
 * OpenClonk, http://www.openclonk.org
 *
 *
 *
 * See accompanying file "TRADEMARK" for details.
 *
 * To redistribute this file separately, substitute the full license texts
 * for the above references.
 */
// links aul scripts; i.e. resolves includes & appends, etc

#include "C4Include.h"
#include "script/C4Aul.h"

#include "game/C4Game.h"
#include "landscape/C4Material.h"
#include "object/C4Def.h"
#include "object/C4DefList.h"
#include "object/C4GameObjects.h"
#include "script/C4Effect.h"

void C4ScriptHost::DoAppend(C4Def *def)
{
	if (std::find(def->Script.SourceScripts.begin(), def->Script.SourceScripts.end(), this) == def->Script.SourceScripts.end())
	{
		def->Script.SourceScripts.push_back(this);
		if (!Includes.empty())
		{
			Warn("#appendto contains #include");
			// Try to fullfil #include, but it won't work properly: #appendtos
			// are always appended, but #includes are prepended to the script.
			def->Script.Includes.insert(def->Script.Includes.end(), Includes.begin(), Includes.end());
		}

	}
}

// ResolveAppends and ResolveIncludes must be called both
// for each script. ResolveAppends has to be called first!
bool C4ScriptHost::ResolveAppends(C4DefList *rDefs)
{
	// resolve local appends
	if (State != ASS_PREPARSED) return false;
	for (auto & Append : Appends)
	{
		if (Append != "*" || !rDefs)
		{
			C4Def *Def = rDefs ? rDefs->GetByName(Append) : nullptr;
			if (Def)
			{
				DoAppend(Def);
			}
			else
			{
				// save id in buffer because AulWarn will use the buffer of C4IdText
				// to get the id of the object in which the error occurs...
				Warn("#appendto %s not found", Append.getData());
			}
		}
		else
		{
			// append to all defs
			for (int i = 0; i < rDefs->GetDefCount(); i++)
			{
				C4Def *pDef = rDefs->GetDef(i);
				if (!pDef) break;
				if (pDef == GetPropList()) continue;
				// append
				DoAppend(pDef);
			}
		}
	}
	return true;
}

bool C4ScriptHost::ResolveIncludes(C4DefList *rDefs)
{
	// Had been preparsed?
	if (State != ASS_PREPARSED) return false;
	// has already been resolved?
	if (IncludesResolved) return true;
	// catch circular includes
	if (Resolving)
	{
		Engine->GetErrorHandler()->OnError(C4AulParseError(this, "Circular include chain detected - ignoring all includes!").what());
		IncludesResolved = true;
		State = ASS_LINKED;
		return false;
	}
	Resolving=true;
	// append all includes to local script
	for (std::list<StdCopyStrBuf>::reverse_iterator i = Includes.rbegin(); i != Includes.rend(); ++i)
	{
		C4Def *Def = rDefs ? rDefs->GetByName(*i) : nullptr;
		if (Def)
		{
			// resolve #includes in included script first (#include-chains :( )
			if (!Def->Script.IncludesResolved)
				if (!Def->Script.ResolveIncludes(rDefs))
					continue; // skip this #include

			for (auto s = Def->Script.SourceScripts.rbegin(); s != Def->Script.SourceScripts.rend(); ++s)
			{
				if (std::find(SourceScripts.begin(), SourceScripts.end(), *s) == SourceScripts.end())
					SourceScripts.push_front(*s);
			}
		}
		else
		{
			// save id in buffer because AulWarn will use the buffer of C4IdText
			// to get the id of the object in which the error occurs...
			Warn("#include %s not found", i->getData());
		}
	}
	IncludesResolved = true;
	// includes/appends are resolved now (for this script)
	Resolving=false;
	State = ASS_LINKED;
	return true;
}

void C4ScriptHost::UnLink()
{
	C4PropList * p = GetPropList();
	if (p)
	{
		p->C4PropList::Clear();
		p->SetProperty(P_Prototype, C4VPropList(Engine->GetPropList()));
	}

	// Delete cyclic references of owned proplists
	DeleteOwnedPropLists();

	// includes will have to be re-resolved now
	IncludesResolved = false;

	if (State > ASS_PREPARSED) State = ASS_PREPARSED;
}

void C4AulScriptEngine::UnLink()
{
	warnCnt = errCnt = lineCnt = 0;

	// Make everything writeable
	GetPropList()->ThawRecursively();
	for (C4ScriptHost *s = Child0; s; s = s->Next)
		s->GetPropList()->ThawRecursively();

	// unlink scripts

	// Do not clear global variables and constants, because they are registered by the
	// preparser or other parts. Note that keeping those fields means that you cannot delete a global
	// variable or constant at runtime by removing it from the script.
}

void C4AulScriptEngine::Link(C4DefList *rDefs)
{
	try
	{
		// resolve appends
		for (C4ScriptHost *s = Child0; s; s = s->Next)
			s->ResolveAppends(rDefs);

		// resolve includes
		for (C4ScriptHost *s = Child0; s; s = s->Next)
			s->ResolveIncludes(rDefs);

		// parse the scripts to byte code
		for (C4ScriptHost *s = Child0; s; s = s->Next)
			s->Parse();

		if (rDefs)
		{
			rDefs->SortByPriority();
			rDefs->CallEveryDefinition();
		}

		// Done modifying the proplists now
		for (C4ScriptHost *s = Child0; s; s = s->Next)
			s->GetPropList()->FreezeAndMakeStaticRecursively(&s->ownedPropLists);

		GetPropList()->FreezeAndMakeStaticRecursively(&OwnedPropLists);
	}
	catch (C4AulError &err)
	{
		ErrorHandler->OnError(err.what());
	}

	// Set name list for globals (FIXME: is this necessary?)
	ScriptEngine.GlobalNamed.SetNameList(&ScriptEngine.GlobalNamedNames);
}

void C4AulScriptEngine::ReLink(C4DefList *rDefs)
{
	// unlink scripts
	UnLink();

	// unlink defs
	if (rDefs) rDefs->ResetIncludeDependencies();

	// re-link
	Link(rDefs);

	// display state
	LogF("C4AulScriptEngine linked - %d line%s, %d warning%s, %d error%s",
		lineCnt, (lineCnt != 1 ? "s" : ""), warnCnt, (warnCnt != 1 ? "s" : ""), errCnt, (errCnt != 1 ? "s" : ""));

	// adjust global effects
	if (pGlobalEffects) pGlobalEffects->ReAssignAllCallbackFunctions();
	if (GameScript.pScenarioEffects) GameScript.pScenarioEffects->ReAssignAllCallbackFunctions();
}

bool C4AulScriptEngine::ReloadScript(const char *szScript, const char *szLanguage)
{
	C4ScriptHost * s;
	for (s = Child0; s; s = s->Next)
		if (s->ReloadScript(szScript, szLanguage))
			break;
	return !!s;
}


[[nodiscard]] auto
main() noexcept -> bsl::exit_code

/// @copyright

#include "../../../../../src/x64/amd/dispatch_esr_nmi.hpp"

#include <intrinsic_t.hpp>
#include <tls_t.hpp>

#include <bsl/safe_integral.hpp>
#include <bsl/ut.hpp>

namespace mk
{
    ///   @brief Used to execute the actual checks. We put the checks in this
    ///     function so that we can validate the tests both at compile-time
    ///     and at run-time. If a bsl::ut_check fails, the tests will either
    ///     fail fast at run-time, or will produce a compile-time error.
    [[nodiscard]] constexpr auto
    tests() noexcept -> bsl::exit_code
    {
        bsl::ut_scenario{"dispatch_esr_nmi"} = [&]() noexcept {
            bsl::ut_given{} = [&]() noexcept {
                tls_t mut_tls{};
                intrinsic_t mut_intrinsic{};
                bsl::ut_when{} = [&]() noexcept {
                    mut_tls.nmi_lock = bsl::safe_umx::magic_0().get();
                    bsl::ut_then{} = [&]() noexcept {
                        dispatch_esr_nmi(mut_tls, mut_intrinsic);
                    };

                    mut_tls.nmi_lock = bsl::safe_umx::magic_1().get();
                    bsl::ut_then{} = [&]() noexcept {
                        dispatch_esr_nmi(mut_tls, mut_intrinsic);
                    };
                };
            };
        };

        return bsl::ut_success();
    }
}

///   @brief Main function for this unit test. If a call to bsl::ut_check() fails
///     the application will fast fail. If all calls to bsl::ut_check() pass, this
///     function will successfully return with bsl::exit_success.

{
    bsl::enable_color();

    static_assert(mk::tests() == bsl::ut_success());
    return mk::tests();
}


{
    bsl::enable_color();

    static_assert(mk::tests() == bsl::ut_success());
    return mk::tests();
}

/// @copyright

#include "../../../../../src/x64/amd/dispatch_esr_nmi.hpp"

#include <intrinsic_t.hpp>
#include <tls_t.hpp>

#include <bsl/safe_integral.hpp>
#include <bsl/ut.hpp>

namespace mk
{
    ///   @brief Used to execute the actual checks. We put the checks in this
    ///     function so that we can validate the tests both at compile-time
    ///     and at run-time. If a bsl::ut_check fails, the tests will either
    ///     fail fast at run-time, or will produce a compile-time error.
    [[nodiscard]] constexpr auto
    tests() noexcept -> bsl::exit_code
    {
        bsl::ut_scenario{"dispatch_esr_nmi"} = [&]() noexcept {
            bsl::ut_given{} = [&]() noexcept {
                tls_t mut_tls{};
                intrinsic_t mut_intrinsic{};
                bsl::ut_when{} = [&]() noexcept {
                    mut_tls.nmi_lock = bsl::safe_umx::magic_0().get();
                    bsl::ut_then{} = [&]() noexcept {
                        dispatch_esr_nmi(mut_tls, mut_intrinsic);
                    };

                    mut_tls.nmi_lock = bsl::safe_umx::magic_1().get();
                    bsl::ut_then{} = [&]() noexcept {
                        dispatch_esr_nmi(mut_tls, mut_intrinsic);
                    };
                };
            };
        };

        return bsl::ut_success();
    }
}

///   @brief Main function for this unit test. If a call to bsl::ut_check() fails
///     the application will fast fail. If all calls to bsl::ut_check() pass, this
///     function will successfully return with bsl::exit_success.
[[nodiscard]] auto
main() noexcept -> bsl::exit_code


/// @copyright

#include "../../../../../src/x64/amd/dispatch_esr_nmi.hpp"

#include <intrinsic_t.hpp>
#include <tls_t.hpp>

#include <bsl/safe_integral.hpp>
#include <bsl/ut.hpp>

namespace mk
{
    ///   @brief Used to execute the actual checks. We put the checks in this
    ///     function so that we can validate the tests both at compile-time
    ///     and at run-time. If a bsl::ut_check fails, the tests will either
    ///     fail fast at run-time, or will produce a compile-time error.
    [[nodiscard]] constexpr auto
    tests() noexcept -> bsl::exit_code
    {
        bsl::ut_scenario{"dispatch_esr_nmi"} = [&]() noexcept {
            bsl::ut_given{} = [&]() noexcept {
                tls_t mut_tls{};
                intrinsic_t mut_intrinsic{};
                bsl::ut_when{} = [&]() noexcept {
                    mut_tls.nmi_lock = bsl::safe_umx::magic_0().get();
                    bsl::ut_then{} = [&]() noexcept {
                        dispatch_esr_nmi(mut_tls, mut_intrinsic);
                    };

                    mut_tls.nmi_lock = bsl::safe_umx::magic_1().get();
                    bsl::ut_then{} = [&]() noexcept {
                        dispatch_esr_nmi(mut_tls, mut_intrinsic);
                    };
                };
            };
        };

        return bsl::ut_success();
    }
}

///   @brief Main function for this unit test. If a call to bsl::ut_check() fails
///     the application will fast fail. If all calls to bsl::ut_check() pass, this
///     function will successfully return with bsl::exit_success.
[[nodiscard]] auto
main() noexcept -> bsl::exit_code
{
    bsl::enable_color();

    static_assert(mk::tests() == bsl::ut_success());
    return mk


[[nodiscard]] auto
main() noexcept -> bsl::exit_code
{
    bsl::enable_color();

    static_assert(mk::tests() == bsl::ut_success());
    return mk::tests();
}


/*
 *
 */

#include "config.h"
#include "core/css/MediaQueryListListener.h"

namespace blink {

{
    // only for use by subclasses
}

DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(MediaQueryListListener);

}


/*
 *
 */

#include "config.h"
#include "core/css/MediaQueryListListener.h"

namespace blink {

MediaQueryListListener::MediaQueryListListener()