text:
#include <stdlib.h>
#include <jni.h>
#include <string.h>
#include <vector>
#include <sstream>
#include <fstream>

#include "GS_compss.h"
#include "param_metadata.h"
#include "BindingDataManager.h"

using namespace std;
const int NUM_FIELDS = 6;

JNIEnv *m_env;
jobject jobjIT;
jclass clsITimpl;
JavaVM * m_jvm;

pthread_mutex_t mtx;

jobject appId;

jmethodID midAppDir;                /* ID of the getApplicationDirectory method in the es.bsc.compss.api.impl.COMPSsRuntimeImpl class */
jmethodID midExecute;               /* ID of the executeTask method in the es.bsc.compss.api.impl.COMPSsRuntimeImpl class */
jmethodID midExecuteNew;            /* ID of the executeTask method in the es.bsc.compss.api.impl.COMPSsRuntimeImpl class */
jmethodID midRegisterCE;            /* ID of the RegisterCE method in the es.bsc.compss.api.impl.COMPSsRuntimeImpl class */
jmethodID midEmitEvent;             /* ID of the EmitEvent method in the es.bsc.compss.api.impl.COMPSsRuntimeImpl class */
jmethodID midCancelApplicationTasks; /* ID of the CancelApplicationTasks method in the es.bsc.compss.api.impl.COMPSsRuntimeImpl class */

jmethodID midOpenFile;              /* ID of the openFile method in the es.bsc.compss.api.impl.COMPSsRuntimeImpl class */
jmethodID midCloseFile;             /* ID of the closeFile method in the es.bsc.compss.api.impl.COMPSsRuntimeImpl class */
jmethodID midDeleteFile;            /* ID of the deleteFile method in the es.bsc.compss.api.impl.COMPSsRuntimeImpl class */
jmethodID midGetFile;               /* ID of the getFile method in the es.bsc.compss.api.impl.COMPSsRuntimeImpl class */

jmethodID midBarrier; 		        /* ID of the barrier method in the es.bsc.compss.api.impl.COMPSsRuntimeImpl class */
jmethodID midBarrierNew;            /* ID of the barrier method in the es.bsc.compss.api.impl.COMPSsRuntimeImpl class */
jmethodID midBarrierGroup;            /* ID of the barrierGroup method in the es.bsc.compss.api.impl.COMPSsRuntimeImpl class */
jmethodID midOpenTaskGroup;         /* ID of the openTaskGroup method in the es.bsc.compss.api.impl.COMPSsRuntimeImpl class */
jmethodID midCloseTaskGroup;        /* ID of the closeTaskGroup method in the es.bsc.compss.api.impl.COMPSsRuntimeImpl class */

jmethodID midgetBindingObject;		/* ID of the getBindingObject method in the es.bsc.compss.api.impl.COMPSsRuntimeImpl class  */
jmethodID midDeleteBindingObject; 	/* ID of the deleteBindingObject method in the es.bsc.compss.api.impl.COMPSsRuntimeImpl class  */

jobject jobjParDirIN; 		        /* Instance of the es.bsc.compss.types.annotations.parameter.Direction class */
jobject jobjParDirOUT; 		        /* Instance of the es.bsc.compss.types.annotations.parameter.Direction class */
jobject jobjParDirINOUT; 	        /* Instance of the es.bsc.compss.types.annotations.parameter.Direction class */
jobject jobjParDirCONCURRENT; 		/* Instance of the es.bsc.compss.types.annotations.parameter.Direction class */
jobject jobjParDirCOMMUTATIVE; 		/* Instance of the es.bsc.compss.types.annotations.parameter.Direction class */

jobject jobjParStreamSTDIN;         /* Instance of the es.bsc.compss.types.annotations.parameter.StdIOStream class */
jobject jobjParStreamSTDOUT;        /* Instance of the es.bsc.compss.types.annotations.parameter.StdIOStream class */
jobject jobjParStreamSTDERR;        /* Instance of the es.bsc.compss.types.annotations.parameter.StdIOStream class */
jobject jobjParStreamUNSPECIFIED;   /* Instance of the es.bsc.compss.types.annotations.parameter.StdIOStream class */

jstring jobjParPrefixEMPTY;         /* Instance of the es.bsc.compss.types.annotations.Constants.PREFIX_EMPTY */

jclass clsObject;         /* java.lang.Object class */
jmethodID midObjCon;      /* ID of the java.lang.Object class constructor method */

jclass clsString;         /* java.lang.String class */
jmethodID midStrCon;      /* ID of the java.lang.String class constructor method */

jclass clsCharacter;      /* java.lang.Character class */
jmethodID midCharCon;     /* ID of the java.lang.Character class constructor method */

jclass clsBoolean;        /* java.lang.Boolean class */
jmethodID midBoolCon;     /* ID of the java.lang.clsBoolean class constructor method */

jclass clsShort;          /* java.lang.Short class */
jmethodID midShortCon;    /* ID of the java.lang.Short class constructor method */

jclass clsInteger;        /* java.lang.Integer class */
jmethodID midIntCon;      /* ID of the java.lang.Integer class constructor method */

jclass clsLong;           /* java.lang.Long class */
jmethodID midLongCon;     /* ID of the java.lang.Long class constructor method */

jclass clsFloat;          /* java.lang.Float class */
jmethodID midFloatCon;    /* ID of the java.lang.Float class constructor method */

jclass clsDouble;         /* java.lang.Double class */
jmethodID midDoubleCon;   /* ID of the java.lang.Double class constructor method */

void init_basic_jni_types() {
    // Parameter classes
    debug_printf ("[BINDING-COMMONS]  -  @Init JNI Types\n");

    jclass clsLocal = m_env->FindClass("java/lang/Object");
    check_and_treat_exception(m_env, "Looking for object class");
    clsObject = (jclass)m_env->NewGlobalRef(clsLocal);
    check_and_treat_exception(m_env, "Looking for object class");

    midObjCon = m_env->GetMethodID(clsObject, "<init>", "()V");
    check_and_treat_exception(m_env, "Looking for object constructor");
    clsLocal = m_env->FindClass("java/lang/String");
    check_and_treat_exception(m_env, "Looking for string class");
    clsString = (jclass)m_env->NewGlobalRef(clsLocal);
    check_and_treat_exception(m_env, "Looking for string class");
    midStrCon = m_env->GetMethodID(clsString, "<init>", "(Ljava/lang/String;)V");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        exit(1);
    }
    clsLocal = m_env->FindClass("java/lang/Character");
    check_and_treat_exception(m_env, "Looking for string class");
    clsCharacter = (jclass)m_env->NewGlobalRef(clsLocal);
    check_and_treat_exception(m_env, "Looking for string class");

    midCharCon = m_env->GetMethodID(clsCharacter, "<init>", "(C)V");
    check_and_treat_exception(m_env, "Looking for string constructor");

    clsLocal = m_env->FindClass("java/lang/Boolean");
    check_and_treat_exception(m_env, "Looking for boolean class");
    clsBoolean = (jclass)m_env->NewGlobalRef(clsLocal);
    check_and_treat_exception(m_env, "Looking for boolean class");

    midBoolCon = m_env->GetMethodID(clsBoolean, "<init>", "(Z)V");
    check_and_treat_exception(m_env, "Looking for boolean class");

    clsLocal = m_env->FindClass("java/lang/Short");
    check_and_treat_exception(m_env, "Looking for boolean class");
    clsShort = (jclass)m_env->NewGlobalRef(clsLocal);
    check_and_treat_exception(m_env, "Looking for boolean class");

    midShortCon = m_env->GetMethodID(clsShort, "<init>", "(S)V");
    check_and_treat_exception(m_env, "Looking for boolean constructor");

    clsLocal = m_env->FindClass("java/lang/Integer");
    check_and_treat_exception(m_env, "Looking for Integer class");
    clsInteger = (jclass)m_env->NewGlobalRef(clsLocal);
    check_and_treat_exception(m_env, "Looking for Integer class");

    midIntCon = m_env->GetMethodID(clsInteger, "<init>", "(I)V");
    check_and_treat_exception(m_env, "Looking for Integer constructor");

    clsLocal = m_env->FindClass("java/lang/Long");
    check_and_treat_exception(m_env, "Looking for Long class");
    clsLong = (jclass)m_env->NewGlobalRef(clsLocal);
    check_and_treat_exception(m_env, "Looking for Long class");

    midLongCon = m_env->GetMethodID(clsLong, "<init>", "(J)V");
    check_and_treat_exception(m_env, "Looking for Long constructor");

    clsLocal = m_env->FindClass("java/lang/Float");
    check_and_treat_exception(m_env, "Looking for Float Class");
    clsFloat = (jclass)m_env->NewGlobalRef(clsLocal);
    check_and_treat_exception(m_env, "Looking for Float Class");

    midFloatCon = m_env->GetMethodID(clsFloat, "<init>", "(F)V");
    check_and_treat_exception(m_env, "Looking for Float Constructor");

    clsLocal = m_env->FindClass("java/lang/Double");
    check_and_treat_exception(m_env, "Looking for Double Class");
    clsDouble = (jclass)m_env->NewGlobalRef(clsLocal);
    check_and_treat_exception(m_env, "Looking for Double Class");

    midDoubleCon = m_env->GetMethodID(clsDouble, "<init>", "(D)V");
    check_and_treat_exception(m_env, "Looking for Double Constructor");

    debug_printf ("[BINDING_COMMONS]  -  @Init DONE\n");
}

void init_master_jni_types() {
    jclass clsParDir; 		    /* es.bsc.compss.types.annotations.parameter.Direction class */
    jmethodID midParDirCon; 	/* ID of the es.bsc.compss.types.annotations.parameter.Direction class constructor method */
    jclass clsParStream;        /* es.bsc.compss.types.annotations.parameter.StdIOStream class */
    jmethodID midParStreamCon;  /* es.bsc.compss.types.annotations.parameter.StdIOStream class constructor method */

    debug_printf ("[BINDING-COMMONS]  -  @Init JNI Methods\n");

    // getApplicationDirectory method
    midAppDir = m_env->GetMethodID(clsITimpl, "getApplicationDirectory", "()Ljava/lang/String;");
    check_and_treat_exception(m_env, "Looking for getApplicationDirectory method");

    // executeTask method - C binding
    midExecute = m_env->GetMethodID(clsITimpl, "executeTask", "(Ljava/lang/Long;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;ZZLjava/lang/Integer;I[Ljava/lang/Object;)I");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        exit(1);
    }

    // executeTask method - Python binding
    midExecuteNew = m_env->GetMethodID(clsITimpl, "executeTask", "(Ljava/lang/Long;Ljava/lang/String;Ljava/lang/String;IZIZZZLjava/lang/Integer;I[Ljava/lang/Object;)I");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        exit(1);
    }

    // barrier method
    midBarrier = m_env->GetMethodID(clsITimpl, "barrier", "(Ljava/lang/Long;)V");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        exit(1);
    }

    // barrier method (with no more tasks flag)
    midBarrierNew = m_env->GetMethodID(clsITimpl, "barrier", "(Ljava/lang/Long;Z)V");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        exit(1);
    }

    // barrierGroup method
    midBarrierGroup = m_env->GetMethodID(clsITimpl, "barrierGroup", "(Ljava/lang/Long;Ljava/lang/String;)V");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        exit(1);
    }

    // openTaskGroup method
    midOpenTaskGroup = m_env->GetMethodID(clsITimpl, "openTaskGroup", "(Ljava/lang/String;ZLjava/lang/Long;)V");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        exit(1);
    }

    // closeTaskGroup method
    midCloseTaskGroup = m_env->GetMethodID(clsITimpl, "closeTaskGroup", "(Ljava/lang/String;Ljava/lang/Long;)V");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        exit(1);
    }

    // EmitEvent method
    midEmitEvent = m_env->GetMethodID(clsITimpl, "emitEvent", "(IJ)V");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        exit(1);
    }

    // CancelApplicationTasks method
    midCancelApplicationTasks = m_env->GetMethodID(clsITimpl, "cancelApplicationTasks", "(Ljava/lang/Long;)V");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        exit(1);
    }

    // RegisterCE method
    midRegisterCE = m_env->GetMethodID(clsITimpl, "registerCoreElement", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        exit(1);
    }

    // openFile method
    midOpenFile = m_env->GetMethodID(clsITimpl, "openFile", "(Ljava/lang/String;Les/bsc/compss/types/annotations/parameter/Direction;)Ljava/lang/String;");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        exit(1);
    }

    // closeFile method
    midCloseFile = m_env->GetMethodID(clsITimpl, "closeFile", "(Ljava/lang/String;Les/bsc/compss/types/annotations/parameter/Direction;)V");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        exit(1);
    }

    // deleteFile method
    midDeleteFile = m_env->GetMethodID(clsITimpl, "deleteFile", "(Ljava/lang/String;Z)Z");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        exit(1);
    }

    // getFile method
    midGetFile = m_env->GetMethodID(clsITimpl, "getFile", "(Ljava/lang/Long;Ljava/lang/String;)V");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        exit(1);
    }

    // deleteFile method
    midDeleteBindingObject = m_env->GetMethodID(clsITimpl, "deleteBindingObject", "(Ljava/lang/String;)Z");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        exit(1);
    }
    // openFile method
    midgetBindingObject = m_env->GetMethodID(clsITimpl, "getBindingObject", "(Ljava/lang/String;)Ljava/lang/String;");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        exit(1);
    }

    // PARAMETER DIRECTIONS

    debug_printf ("[BINDING_COMMONS]  -  @Init JNI Direction Types\n");

    clsParDir = m_env->FindClass("es/bsc/compss/types/annotations/parameter/Direction");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        exit(1);
    }
    midParDirCon = m_env->GetStaticMethodID(clsParDir, "valueOf", "(Ljava/lang/String;)Les/bsc/compss/types/annotations/parameter/Direction;");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        exit(1);
    }

    jobject objLocal = m_env->CallStaticObjectMethod(clsParDir, midParDirCon, m_env->NewStringUTF("IN"));
    check_and_treat_exception(m_env, "Error getting Direction.IN object");
    jobjParDirIN = (jobject)m_env->NewGlobalRef(objLocal);
    check_and_treat_exception(m_env, "Error getting Direction.IN object");

    objLocal =  m_env->CallStaticObjectMethod(clsParDir, midParDirCon, m_env->NewStringUTF("OUT"));
    check_and_treat_exception(m_env, "Error getting Direction.OUT object");
    jobjParDirOUT = (jobject)m_env->NewGlobalRef(objLocal);
    check_and_treat_exception(m_env, "Error getting Direction.OUT object");

    objLocal = m_env->CallStaticObjectMethod(clsParDir, midParDirCon, m_env->NewStringUTF("INOUT"));
    check_and_treat_exception(m_env, "Error getting Direction.INOUT object");
    jobjParDirINOUT = (jobject)m_env->NewGlobalRef(objLocal);
    check_and_treat_exception(m_env, "Error getting Direction.INOUT object");

    objLocal =  m_env->CallStaticObjectMethod(clsParDir, midParDirCon, m_env->NewStringUTF("CONCURRENT"));
    check_and_treat_exception(m_env, "Error getting Direction.CONCURRENT object");
    jobjParDirCONCURRENT = (jobject)m_env->NewGlobalRef(objLocal);
    check_and_treat_exception(m_env, "Error getting Direction.CONCURRENT object");

    objLocal =  m_env->CallStaticObjectMethod(clsParDir, midParDirCon, m_env->NewStringUTF("COMMUTATIVE"));
    check_and_treat_exception(m_env, "Error getting Direction.COMMUTATIVE object");
    jobjParDirCOMMUTATIVE = (jobject)m_env->NewGlobalRef(objLocal);
    check_and_treat_exception(m_env, "Error getting Direction.COMMUTATIVE object");

    // Parameter streams

    debug_printf ("[BINDING_COMMONS]  -  @Init JNI Stream Types\n");

    clsParStream = m_env->FindClass("es/bsc/compss/types/annotations/parameter/StdIOStream");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        exit(1);
    }
    midParStreamCon = m_env->GetStaticMethodID(clsParStream, "valueOf", "(Ljava/lang/String;)Les/bsc/compss/types/annotations/parameter/StdIOStream;");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        exit(1);
    }
    objLocal = m_env->CallStaticObjectMethod(clsParStream, midParStreamCon, m_env->NewStringUTF("STDIN"));
    check_and_treat_exception(m_env, "Error getting StdIOStream.STDIN object");
    jobjParStreamSTDIN = (jobject)m_env->NewGlobalRef(objLocal);
    check_and_treat_exception(m_env, "Error getting StdIOStream.STDIN object");

    objLocal = m_env->CallStaticObjectMethod(clsParStream, midParStreamCon, m_env->NewStringUTF("STDOUT"));
    check_and_treat_exception(m_env, "Error getting StdIOStream.STDOUT object");
    jobjParStreamSTDOUT = (jobject)m_env->NewGlobalRef(objLocal);
    check_and_treat_exception(m_env, "Error getting StdIOStream.STDOUT object");

    objLocal = m_env->CallStaticObjectMethod(clsParStream, midParStreamCon, m_env->NewStringUTF("STDERR"));
    check_and_treat_exception(m_env, "Error getting StdIOStream.STDERR object");
    jobjParStreamSTDERR = (jobject)m_env->NewGlobalRef(objLocal);
    check_and_treat_exception(m_env, "Error getting StdIOStream.STDERR object");

    objLocal = m_env->CallStaticObjectMethod(clsParStream, midParStreamCon, m_env->NewStringUTF("UNSPECIFIED"));
    check_and_treat_exception(m_env, "Error getting StdIOStream.UNSPECIFIED object");
    jobjParStreamUNSPECIFIED = (jobject)m_env->NewGlobalRef(objLocal);
    check_and_treat_exception(m_env, "Error getting StdIOStream.UNSPECIFIED object");

    // Parameter prefix empty
    jstring objStr = m_env->NewStringUTF("null");
    check_and_treat_exception(m_env, "Error getting null string object");
    jobjParPrefixEMPTY = (jstring)m_env->NewGlobalRef(objStr);
    check_and_treat_exception(m_env, "Error getting null string object");

    init_basic_jni_types();

    debug_printf ("[BINDING_COMMONS]  -  @Master JNI Init DONE\n");
}

int release_lock() {
    return pthread_mutex_unlock(&mtx);
}

int get_lock() {
    return pthread_mutex_lock(&mtx);
}

void process_param(void **params, int i, jobjectArray jobjOBJArr) {

    debug_printf("[BINDING_COMMONS]  -  @process_param\n");
    // params     is of the form: value type direction stream prefix name
    // jobjOBJArr is of the form: value type direction stream prefix name
    // This means that the ith parameters occupies the fields in the interval [NF * k, NK * k + 5]
    int pv = NUM_FIELDS * i + 0,
        pt = NUM_FIELDS * i + 1,
        pd = NUM_FIELDS * i + 2,
        ps = NUM_FIELDS * i + 3,
        pp = NUM_FIELDS * i + 4,
        pn = NUM_FIELDS * i + 5;

    void *parVal        =           params[pv];
    int parType         = *(int*)   params[pt];
    int parDirect       = *(int*)   params[pd];
    int parIOStream     = *(int*)   params[ps];
    void *parPrefix     =           params[pp];
    void *parName       =           params[pn];

    jclass clsParType = NULL; /* es.bsc.compss.types.annotations.parameter.DataType class */
    clsParType = m_env->FindClass("es/bsc/compss/types/annotations/parameter/DataType");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        release_lock();
        exit(1);
    }

    jmethodID midParTypeCon = NULL; /* ID of the es.bsc.compss.api.COMPSsRuntime$DataType class constructor method */
    midParTypeCon = m_env->GetStaticMethodID(clsParType, "valueOf", "(Ljava/lang/String;)Les/bsc/compss/types/annotations/parameter/DataType;");
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        release_lock();
        exit(1);
    }

    jobject jobjParType = NULL;
    jobject jobjParVal = NULL;

    debug_printf ("[BINDING-COMMONS]  -  @process_param  -  ENUM DATA_TYPE: %d\n", (enum datatype) parType);

    switch ( (enum datatype) parType) {
    case char_dt:
    case wchar_dt:
        jobjParVal = m_env->NewObject(clsCharacter, midCharCon, (jchar)*(char*)parVal);
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }

        debug_printf ("[BINDING-COMMONS]  -  @process_param  -  Char: %c\n", *(char*)parVal);

        jobjParType = m_env->CallStaticObjectMethod(clsParType, midParTypeCon, m_env->NewStringUTF("CHAR_T"));
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }
        break;
    case boolean_dt:
        jobjParVal = m_env->NewObject(clsBoolean, midBoolCon, (jboolean)*(int*)parVal);
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }

        debug_printf ("[BINDING-COMMONS]  -  @process_param  -  Bool: %d\n", *(int*)parVal);

        jobjParType = m_env->CallStaticObjectMethod(clsParType, midParTypeCon, m_env->NewStringUTF("BOOLEAN_T"));
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }
        break;
    case short_dt:
        jobjParVal = m_env->NewObject(clsShort, midShortCon, (jshort)*(short*)parVal);
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }

        debug_printf ("[BINDING-COMMONS]  -  @process_param  -  Short: %hu\n", *(short*)parVal);

        jobjParType = m_env->CallStaticObjectMethod(clsParType, midParTypeCon, m_env->NewStringUTF("SHORT_T"));
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }
        break;
    case int_dt:
        jobjParVal = m_env->NewObject(clsInteger, midIntCon, (jint)*(int*)parVal);
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }

        debug_printf ("[BINDING-COMMONS]  -  @process_param  -  Int: %d\n", *(int*)parVal);

        jobjParType = m_env->CallStaticObjectMethod(clsParType, midParTypeCon, m_env->NewStringUTF("INT_T"));
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }
        break;
    case long_dt:
        jobjParVal = m_env->NewObject(clsLong, midLongCon, (jlong)*(long*)parVal);
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }

        debug_printf ("[BINDING-COMMONS]  -  @process_param  -  Long: %ld\n", *(long*)parVal);

        jobjParType = m_env->CallStaticObjectMethod(clsParType, midParTypeCon, m_env->NewStringUTF("LONG_T"));
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }
        break;
    case longlong_dt:
    case float_dt:
        jobjParVal = m_env->NewObject(clsFloat, midFloatCon, (jfloat)*(float*)parVal);
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }

        debug_printf ("[BINDING-COMMONS]  -  @process_param  -  Float: %f\n", *(float*)parVal);

        jobjParType = m_env->CallStaticObjectMethod(clsParType, midParTypeCon, m_env->NewStringUTF("FLOAT_T"));
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }
        break;
    case double_dt:
        jobjParVal = m_env->NewObject(clsDouble, midDoubleCon, (jdouble)*(double*)parVal);
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }

        debug_printf ("[BINDING-COMMONS]  -  @process_param  -  Double: %f\n", *(double*)parVal);

        jobjParType = m_env->CallStaticObjectMethod(clsParType, midParTypeCon, m_env->NewStringUTF("DOUBLE_T"));
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }
        break;
    case file_dt:
        jobjParVal = m_env->NewStringUTF(*(char **)parVal);
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }

        debug_printf ("[BINDING-COMMONS]  -  @process_param  -  File: %s\n", *(char **)parVal);

        jobjParType = m_env->CallStaticObjectMethod(clsParType, midParTypeCon, m_env->NewStringUTF("FILE_T"));
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }
        break;
    case external_stream_dt:
        jobjParVal = m_env->NewStringUTF(*(char **)parVal);
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }

        debug_printf ("[BINDING-COMMONS]  -  @process_param  -  External Stream: %s\n", *(char **)parVal);

        jobjParType = m_env->CallStaticObjectMethod(clsParType, midParTypeCon, m_env->NewStringUTF("EXTERNAL_STREAM_T"));
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }
        break;
    case external_psco_dt:
        jobjParVal = m_env->NewStringUTF(*(char **)parVal);
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }
        debug_printf ("[BINDING-COMMONS]  -  @process_param  -  Persistent: %s\n", *(char **)parVal);

        jobjParType = m_env->CallStaticObjectMethod(clsParType, midParTypeCon, m_env->NewStringUTF("EXTERNAL_PSCO_T"));
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }
        break;
    case string_dt:
        jobjParVal = m_env->NewStringUTF(*(char **)parVal);
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }

        debug_printf ("[BINDING-COMMONS]  -  @process_param  -  String: %s\n", *(char **)parVal);

        jobjParType = m_env->CallStaticObjectMethod(clsParType, midParTypeCon, m_env->NewStringUTF("STRING_T"));
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }
        break;
    case binding_object_dt:
        jobjParVal = m_env->NewStringUTF(*(char **)parVal);
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }

        debug_printf ("[BINDING-COMMONS]  -  @process_param  -  BindingObject: %s\n", *(char **)parVal);

        jobjParType = m_env->CallStaticObjectMethod(clsParType, midParTypeCon, m_env->NewStringUTF("BINDING_OBJECT_T"));
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }
        break;
    case collection_dt:
        jobjParVal = m_env -> NewStringUTF(*(char **)parVal);
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }
        debug_printf ("[BINDING-COMMONS]  -  @process_param  -  Collection: %s\n", *(char **)parVal);

        jobjParType = m_env->CallStaticObjectMethod(clsParType, midParTypeCon, m_env->NewStringUTF("COLLECTION_T"));
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            exit(1);
        }
        break;
    case void_dt:
    case any_dt:
    case null_dt:
    default:
        debug_printf ("[BINDING-COMMONS]  -  @process_param  -  The type of the parameter %s is not registered\n", *(char **)parName);
        break;
    }

    // Sets the parameter value and type
    m_env->SetObjectArrayElement(jobjOBJArr, pv, jobjParVal);
    m_env->SetObjectArrayElement(jobjOBJArr, pt, jobjParType);

    // Add param direction
    debug_printf ("[BINDING-COMMONS]  -  @process_param  -  ENUM DIRECTION: %d\n", (enum direction) parDirect);
    switch ((enum direction) parDirect) {
    case in_dir:
        m_env->SetObjectArrayElement(jobjOBJArr, pd, jobjParDirIN);
        break;
    case out_dir:
        m_env->SetObjectArrayElement(jobjOBJArr, pd, jobjParDirOUT);
        break;
    case inout_dir:
        m_env->SetObjectArrayElement(jobjOBJArr, pd, jobjParDirINOUT);
        break;
    case concurrent_dir:
        m_env->SetObjectArrayElement(jobjOBJArr, pd, jobjParDirCONCURRENT);
        break;
    case commutative_dir:
        m_env->SetObjectArrayElement(jobjOBJArr, pd, jobjParDirCOMMUTATIVE);
        break;
    default:
        break;
    }

    // Add param stream
    debug_printf ("[BINDING-COMMONS]  -  @process_param  -  ENUM STD IO STREAM: %d\n", (enum io_stream) parIOStream);
    switch ((enum io_stream) parIOStream) {
    case STD_IN:
        m_env->SetObjectArrayElement(jobjOBJArr, ps, jobjParStreamSTDIN);
        break;
    case STD_OUT:
        m_env->SetObjectArrayElement(jobjOBJArr, ps, jobjParStreamSTDOUT);
        break;
    case STD_ERR:
        m_env->SetObjectArrayElement(jobjOBJArr, ps, jobjParStreamSTDERR);
        break;
    default:
        m_env->SetObjectArrayElement(jobjOBJArr, ps, jobjParStreamUNSPECIFIED);
        break;
    }

    // Add param prefix
    debug_printf ("[BINDING-COMMONS]  -  @process_param  -  PREFIX: %s\n", *(char**)parPrefix);
    jstring jobjParPrefix = m_env->NewStringUTF(*(char**)parPrefix);
    m_env->SetObjectArrayElement(jobjOBJArr, pp, jobjParPrefix);
    //env->SetObjectArrayElement(jobjOBJArr, pp, jobjParPrefixEMPTY);

    debug_printf ("[BINDING-COMMONS]  -  @process_param  -  NAME: %s\n", *(char**)parName);
    jstring jobjParName = m_env->NewStringUTF(*(char**)parName);
    m_env->SetObjectArrayElement(jobjOBJArr, pn, jobjParName);
}

// Given a COMPSsException, get its containing message
static void getReceivedException(JNIEnv* env, jthrowable exception, char** buf)
{
    int success = 0;
    jclass exceptionClazz = env->GetObjectClass((jobject)exception);
    jclass classClazz = env->GetObjectClass((jobject)exceptionClazz);
    jmethodID classGetNameMethod = env->GetMethodID(classClazz, "getName", "()Ljava/lang/String;");
    jstring classNameStr = (jstring)env->CallObjectMethod(exceptionClazz, classGetNameMethod);
    if (strcmp(env->GetStringUTFChars(classNameStr ,0), "es.bsc.compss.worker.COMPSsException") != 0) {
        env->ExceptionClear();
    } else {
        const char* classNameChars = env->GetStringUTFChars(classNameStr, NULL);
        if (classNameChars != NULL) {
            jmethodID throwableGetMessageMethod = env->GetMethodID(exceptionClazz, "getMessage", "()Ljava/lang/String;");
            jstring messageStr = (jstring)env->CallObjectMethod(exception, throwableGetMessageMethod);
            if (messageStr != NULL) {
                const char* messageChars = env->GetStringUTFChars( messageStr, NULL);
                if (messageChars != NULL) {
                    *buf = strdup(messageChars);
                    env->ReleaseStringUTFChars(messageStr, messageChars);
                    env->ExceptionClear();
                } else {
                    env->ExceptionClear();
                }
                env->DeleteLocalRef(messageStr);
            }
            env->ReleaseStringUTFChars(classNameStr, classNameChars);
            env->DeleteLocalRef(classNameStr);
        }
        env->DeleteLocalRef(classClazz);
        env->DeleteLocalRef(exceptionClazz);
    }
}

// ******************************
// API functions
// ******************************

void GS_On(AbstractCache *absCache) {
    init_data_manager(absCache);
    GS_On();
}

void GS_On() {
    debug_printf ("[BINDING-COMMONS]  -  @GS_On\n");
    pthread_mutex_init(&mtx,NULL);
    clsITimpl = NULL;
    jmethodID midITImplConst = NULL;
    jmethodID midStartIT = NULL;

    init_env_vars();
    debug_printf ("[BINDING-COMMONS]  -  @GS_On  -  Creating the JVM\n");
    m_env = create_vm(&m_jvm);
    if (m_env == NULL) {
        printf ("[BINDING-COMMONS]  -  @GS_On  -  Error creating the JVM\n");
        exit(1);
    }
    // Obtaining Runtime Class
    jclass clsLocal = m_env->FindClass("es/bsc/compss/api/impl/COMPSsRuntimeImpl");
    check_and_treat_exception(m_env, "Error looking for the COMPSsRuntimeImpl class");
    clsITimpl = (jclass)m_env->NewGlobalRef(clsLocal);
    check_and_treat_exception(m_env, "Error looking for the COMPSsRuntimeImpl class");

    if (clsITimpl != NULL) {
        // Get constructor ID for COMPSsRuntimeImpl
        midITImplConst = m_env->GetMethodID(clsITimpl, "<init>", "()V");
        check_and_treat_exception(m_env, "Error looking for the init method");

        // Get startIT method ID
        midStartIT = m_env->GetMethodID(clsITimpl, "startIT", "()V");
        check_and_treat_exception(m_env,"Error looking for the startIT method");
    } else {
        printf("[BINDING-COMMONS]  -  @GS_On  -  Unable to find the runtime class\n");
        exit(1);
    }

    /************************************************************************/
    /* Now we will call the functions using the their method IDs            */
    /************************************************************************/

    if (midITImplConst != NULL) {
        if (clsITimpl != NULL && midITImplConst != NULL) {
            // Creating the Object of IT.
            debug_printf ("[BINDING-COMMONS]  -  @GS_On  -  Creating runtime object\n");
            jobject objLocal = m_env->NewObject(clsITimpl, midITImplConst);
            check_and_treat_exception(m_env,"Error creating runtime object");
            jobjIT = (jobject)m_env->NewGlobalRef(objLocal);
            check_and_treat_exception(m_env,"Error creating runtime object");
        } else {
            printf("[BINDING-COMMONS]  -  @GS_On  -  Unable to find the runtime constructor or runtime class\n");
            exit(1);
        }

        if (jobjIT != NULL && midStartIT != NULL) {
            debug_printf ("[BINDING-COMMONS]  -  @GS_On  -  Calling runtime start\n");
            m_env->CallVoidMethod(jobjIT, midStartIT); //Calling the method and passing IT Object as parameter
            check_and_treat_exception(m_env,"Error calling start runtime");
        } else {
            printf("[BINDING-COMMONS]  -  @GS_On  -  Unable to find the start method\n");
            exit(1);
        }
    } else {
        printf("[BINDING-COMMONS]  -  @GS_On  -  Unable to find the runtime constructor\n");
        exit(1);
    }

    init_master_jni_types();

    jobject objLocal = m_env->NewObject(clsLong, midLongCon, (jlong) 0);
    check_and_treat_exception(m_env,"Error creating appId object");
    appId = (jobject)m_env->NewGlobalRef(objLocal);
    check_and_treat_exception(m_env,"Error creating appId object");
}

void GS_Off(int exit_code) {
    debug_printf("[BINDING-COMMONS]  -  @GS_Off\n");

    jmethodID midStopIT = NULL;
    jmethodID midNoMoreTasksIT = NULL;

    check_and_attach(m_jvm, m_env);

    midNoMoreTasksIT = m_env->GetMethodID(clsITimpl, "noMoreTasks", "(Ljava/lang/Long;)V");
    if (m_env->ExceptionOccurred()) {
        debug_printf("[BINDING-COMMONS]  -  @Off  -  Error: Exception loading noMoreTasks method.\n");
        m_env->ExceptionDescribe();
        exit(1);
    }

    midStopIT = m_env->GetMethodID(clsITimpl, "stopIT", "(Z)V");
    if (m_env->ExceptionOccurred()) {
        debug_printf("[BINDING-COMMONS]  -  @Off  -  Error: Exception loading stop.\n");
        m_env->ExceptionDescribe();
        exit(1);
    }
    //if (exit_code == 0){
        debug_printf("[BINDING-COMMONS]  -  @Off - Waiting to end tasks\n");
        m_env->CallVoidMethod(jobjIT, midNoMoreTasksIT, appId, "TRUE");
        if (m_env->ExceptionOccurred()) {
            debug_printf("[BINDING-COMMONS]  -  @GS_ExecuteTask  -  Error: Exception received when calling noMoreTasks.\n");
            m_env->ExceptionDescribe();
            exit(1);
        }
    //}
    debug_printf("[BINDING-COMMONS]  -  @Off - Stopping runtime\n");
    m_env->CallVoidMethod(jobjIT, midStopIT, "TRUE"); //Calling the method and passing IT Object as parameter
    if (m_env->ExceptionOccurred()) {
        debug_printf("[BINDING-COMMONS]  -  @Off  -  Error: Exception received when calling stop runtime.\n");
        m_env->ExceptionDescribe();
        exit(1);
    }
    debug_printf("[BINDING-COMMONS]  -  @Off - Removing JVM\n");
    destroy_vm(m_jvm);  // Release jvm resources -- Does not work properly --> JNI bug: not releasing properly the resources, so it is not possible to recreate de JVM.
    // delete jvm;    // free(): invalid pointer: 0x00007fbc11ba8020 ***
    m_jvm = NULL;
    debug_printf("[BINDING-COMMONS]  -  @Off - End\n");
    pthread_mutex_destroy(&mtx);
}

void GS_Cancel_Application_Tasks(long _appId) {
    debug_printf ("[BINDING-COMMONS]  -  @GS_Cancel_Application_Tasks\n");

    get_lock();
    JNIEnv* local_env = m_env;
    int isAttached = check_and_attach(m_jvm, local_env);
    release_lock();

    local_env->CallVoidMethod(jobjIT, midCancelApplicationTasks, appId);

    if (local_env->ExceptionOccurred()) {
        debug_printf("[BINDING-COMMONS]  -  @GS_CancelApplicationTasks  -  Error: Exception received when calling cancelApplicationTasks.\n");
        local_env->ExceptionDescribe();
        exit(1);
    }

    if (isAttached == 1) {
        m_jvm->DetachCurrentThread();

    }
    debug_printf ("[BINDING-COMMONS]  -  @GS_Cancel_Application_Tasks  -  Tasks cancelled\n");

}

void GS_Get_AppDir(char **buf) {
    debug_printf ("[BINDING-COMMONS]  -  @GS_Get_AppDir - Getting application directory.\n");

    const char *cstr;
    jstring jstr = NULL;
    jboolean isCopy;

    get_lock();

    int isAttached = check_and_attach(m_jvm, m_env);

    jstr = (jstring)m_env->CallObjectMethod(jobjIT, midAppDir);
    if (m_env->ExceptionOccurred()) {
        debug_printf("[BINDING-COMMONS]  -  @GS_Get_AppDir  -  Error: Exception received when calling getAppDir.\n");
        m_env->ExceptionDescribe();
        release_lock();
        exit(1);
    }

    cstr = m_env->GetStringUTFChars(jstr, &isCopy);
    *buf = strdup(cstr);
    m_env->ReleaseStringUTFChars(jstr, cstr);
    if (isAttached == 1) {
        m_jvm->DetachCurrentThread();
    }
    release_lock();
    debug_printf("[BINDING-COMMONS]  -  @GS_Get_AppDir  -  directory name: %s\n", *buf);
}

void GS_ExecuteTask(long _appId, char *class_name, char *on_failure, int time_out, char *method_name, int priority, int has_target, int num_returns, int num_params, void **params) {

    jobjectArray jobjOBJArr; /* array of Objects to be passed to executeTask */

    debug_printf ("[BINDING-COMMONS]  -  @GS_ExecuteTask - Processing task execution in bindings-common. \n");
    //Default values
    bool _priority = false;
    if (priority != 0) _priority = true;

    bool _has_target = false;
    if (has_target != 0) _has_target = true;

    get_lock();

    int isAttached = check_and_attach(m_jvm, m_env);

    jobject num_returns_integer = m_env->NewObject(clsInteger, midIntCon, num_returns);
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        release_lock();
        exit(1);
    }

    jobjOBJArr = (jobjectArray)m_env->NewObjectArray(num_params * NUM_FIELDS, clsObject, m_env->NewObject(clsObject,midObjCon));

    for (int i = 0; i < num_params; i++) {
        debug_printf("[BINDING-COMMONS]  -  @GS_ExecuteTask  -  Processing parameter %d\n", i);
        process_param(params, i, jobjOBJArr);
    }

    m_env->CallVoidMethod(jobjIT, midExecute, appId, m_env->NewStringUTF(class_name), m_env->NewStringUTF(on_failure), time_out, m_env->NewStringUTF(method_name), _priority, _has_target, num_returns_integer, num_params, jobjOBJArr);
    if (m_env->ExceptionOccurred()) {
        debug_printf("[BINDING-COMMONS]  -  @GS_ExecuteTask  -  Error: Exception received when calling executeTask.\n");
        m_env->ExceptionDescribe();
        release_lock();
        exit(1);
    }
    if (isAttached==1) {
        m_jvm->DetachCurrentThread();
    }
    release_lock();
}

void GS_ExecuteTaskNew(long _appId, char *signature, char *on_failure, int time_out, int priority, int num_nodes, int replicated, int distributed,
                       int has_target, int num_returns, int num_params, void **params) {

    jobjectArray jobjOBJArr; /* array of Objects to be passed to executeTask */

    debug_printf ("[BINDING-COMMONS]  -  @GS_ExecuteTaskNew - Processing task execution in bindings-common. \n");

    bool _priority = false;
    if (priority != 0) _priority = true;

    bool _replicated = false;
    if (replicated != 0) _replicated = true;

    bool _distributed = false;
    if (distributed != 0) _distributed = true;

    bool _has_target = false;
    if (has_target != 0) _has_target = true;

    get_lock();

    int isAttached = check_and_attach(m_jvm, m_env);

    // Convert num_returns from int to integer
    jobject num_returns_integer = m_env->NewObject(clsInteger, midIntCon, num_returns);
    if (m_env->ExceptionOccurred()) {
        m_env->ExceptionDescribe();
        release_lock();
        exit(1);
    }

    // Create array of parameters
    jobjOBJArr = (jobjectArray)m_env->NewObjectArray(num_params * NUM_FIELDS, clsObject, m_env->NewObject(clsObject, midObjCon));

    for (int i = 0; i < num_params; i++) {
        debug_printf("[BINDING-COMMONS]  -  @GS_ExecuteTaskNew  -  Processing parameter %d\n", i);
        process_param(params, i, jobjOBJArr);
    }

    // Call to JNI execute task method
    m_env->CallVoidMethod(jobjIT,
                          midExecuteNew,
                          appId,
                          m_env->NewStringUTF(signature),
                          m_env->NewStringUTF(on_failure),
                          time_out,
                          _priority,
                          num_nodes,
                          _replicated,
                          _distributed,
                          _has_target,
                          num_returns_integer,
                          num_params,
                          jobjOBJArr);
    if (m_env->ExceptionOccurred()) {
        debug_printf("[BINDING-COMMONS]  -  @GS_ExecuteTaskNew  -  Error: Exception received when calling executeTaskNew.\n");
        m_env->ExceptionDescribe();
        release_lock();
        exit(1);
    }
    if (isAttached==1) {
        m_jvm->DetachCurrentThread();
    }
    release_lock();
}

void GS_RegisterCE(char *CESignature, char *ImplSignature, char *ImplConstraints, char *ImplType, int num_params, char **ImplTypeArgs) {
    get_lock();
	int isAttached = check_and_attach(m_jvm, m_env);

    debug_printf ("[BINDING-COMMONS]  -  @GS_RegisterCE - Registering Core element.\n");
    //debug_printf ("[BINDING-COMMONS]  -  @GS_RegisterCE - CESignature:     %s\n", CESignature);
    //debug_printf ("[BINDING-COMMONS]  -  @GS_RegisterCE - ImplSignature:   %s\n", ImplSignature);
    //debug_printf ("[BINDING-COMMONS]  -  @GS_RegisterCE - ImplConstraints: %s\n", ImplConstraints);
    //debug_printf ("[BINDING-COMMONS]  -  @GS_RegisterCE - ImplType:        %s\n", ImplType);
    //debug_printf ("[BINDING-COMMONS]  -  @GS_RegisterCE - num_params:      %d\n", num_params);

    jobjectArray implArgs; //  array of Objects to be passed to register core element
    implArgs = (jobjectArray)m_env->NewObjectArray(num_params, clsString, m_env->NewStringUTF(""));
    for (int i = 0; i < num_params; i++) {
        //debug_printf("[BINDING-COMMONS]  -  @GS_RegisterCE  -    Processing pos %d\n", i);
        jstring tmp = m_env->NewStringUTF(ImplTypeArgs[i]);
        m_env->SetObjectArrayElement(implArgs, i, tmp);
    }
    m_env->CallVoidMethod(jobjIT, midRegisterCE, m_env->NewStringUTF(CESignature),
                          m_env->NewStringUTF(ImplSignature),
                          m_env->NewStringUTF(ImplConstraints),
                          m_env->NewStringUTF(ImplType),
                          implArgs);
    if (m_env->ExceptionOccurred()) {
        debug_printf("[BINDING-COMMONS]  -  @GS_RegisterCE  -  Error: Exception received when calling registerCE.\n");
        m_env->ExceptionDescribe();
        release_lock();
        GS_Off(1);
        exit(1);
    }
    if (isAttached==1) {
        m_jvm->DetachCurrentThread();
    }
    release_lock();
    debug_printf("[BINDING-COMMONS]  -  @GS_RegisterCE  -  Task registered: %s\n", CESignature);
}

void GS_Open_File(char *file_name, int mode, char **buf) {

    const char *cstr;
    jstring jstr = NULL;
    jboolean isCopy;

    get_lock();
    JNIEnv* local_env = m_env;
    int isAttached = check_and_attach(m_jvm, local_env);
    debug_printf("[BINDING-COMMONS]  -  @GS_Open_File  -  Calling runtime OpenFile method  for %s and mode %d ...\n", file_name, mode);
    jstring filename_str = local_env->NewStringUTF(file_name);
    check_and_treat_exception(local_env, "Error getting String UTF");
    release_lock();

    switch ((enum direction) mode) {
    case in_dir:
        jstr = (jstring)local_env->CallObjectMethod(jobjIT, midOpenFile, filename_str, jobjParDirIN);
        break;
    case out_dir:
        jstr = (jstring)local_env->CallObjectMethod(jobjIT, midOpenFile, filename_str, jobjParDirOUT);
        break;
    case inout_dir:
        jstr = (jstring)local_env->CallObjectMethod(jobjIT, midOpenFile, filename_str, jobjParDirINOUT);
        break;
    case concurrent_dir:
        jstr = (jstring)local_env->CallObjectMethod(jobjIT, midOpenFile, filename_str, jobjParDirCONCURRENT);
        break;
    case commutative_dir:
        jstr = (jstring)local_env->CallObjectMethod(jobjIT, midOpenFile, filename_str, jobjParDirCOMMUTATIVE);
        break;
    default:
        break;
    }
    check_and_treat_exception(local_env, "Error calling runtime openFile");
    local_env->DeleteLocalRef(filename_str);

    cstr = local_env->GetStringUTFChars(jstr, &isCopy);
    check_and_treat_exception(local_env, "Error getting String UTF");

    *buf = strdup(cstr);
    local_env->ReleaseStringUTFChars(jstr, cstr);
    local_env->DeleteLocalRef(jstr);

    if (isAttached==1) {
        m_jvm->DetachCurrentThread();
    }
    debug_printf("[BINDING-COMMONS]  -  @GS_Open_File  -  COMPSs filename: %s\n", *buf);
}

void GS_Close_File(char *file_name, int mode) {
	get_lock();
    int isAttached = check_and_attach(m_jvm, m_env);
    debug_printf("[BINDING-COMMONS]  -  @GS_Close_File  -  Calling runtime closeFile method...\n");
    switch ((enum direction) mode) {
    case in_dir:
        m_env->CallVoidMethod(jobjIT, midCloseFile, m_env->NewStringUTF(file_name), jobjParDirIN);
        break;
    case out_dir:
        m_env->CallVoidMethod(jobjIT, midCloseFile, m_env->NewStringUTF(file_name), jobjParDirOUT);
        break;
    case inout_dir:
        m_env->CallVoidMethod(jobjIT, midCloseFile, m_env->NewStringUTF(file_name), jobjParDirINOUT);
        break;
    case concurrent_dir:
        m_env->CallVoidMethod(jobjIT, midCloseFile, m_env->NewStringUTF(file_name), jobjParDirCONCURRENT);
        break;
    case commutative_dir:
        m_env->CallVoidMethod(jobjIT, midCloseFile, m_env->NewStringUTF(file_name), jobjParDirCOMMUTATIVE);
        break;
    default:
        break;
    }
    check_and_treat_exception(m_env, "Error calling runtime closeFile");
    if (isAttached==1) {
        m_jvm->DetachCurrentThread();
    }
    release_lock();
    debug_printf("[BINDING-COMMONS]  -  @GS_Close_File  -  COMPSs filename: %s\n", file_name);
}

void GS_Delete_File(char *file_name, int wait) {

	get_lock();
    int isAttached = check_and_attach(m_jvm, m_env);

    bool _wait = false;
    if (wait != 0) _wait = true;

    jboolean res = m_env->CallBooleanMethod(jobjIT, midDeleteFile, m_env->NewStringUTF(file_name), _wait);
    if (m_env->ExceptionOccurred()) {
        debug_printf("[BINDING-COMMONS]  -  @GS_Delete_File  -  Error: Exception received when calling deleteFile.\n");
        m_env->ExceptionDescribe();
        release_lock();
        GS_Off(1);
        exit(1);
    }
    //*buf = (int*)&res;
    if (isAttached==1) {
        m_jvm->DetachCurrentThread();
    }
    release_lock();
    debug_printf("[BINDING-COMMONS]  -  @GS_Delete_File  -  COMPSs filename: %s\n", file_name);
}

void GS_Get_File(long _appId, char *file_name) {

    get_lock();
    JNIEnv* local_env = m_env;
    int isAttached = check_and_attach(m_jvm, local_env);
    release_lock();

    local_env->CallVoidMethod(jobjIT, midGetFile, appId, m_env->NewStringUTF(file_name));
    if (local_env->ExceptionOccurred()) {
        local_env->ExceptionDescribe();
        exit(1);
    }
    if (isAttached==1) {
        m_jvm->DetachCurrentThread();
    }

    debug_printf("[BINDING-COMMONS]  -  @GS_Get_File  -  COMPSs filename: %s\n", file_name);
}

void GS_Get_Object(char *file_name, char**buf) {

	const char *cstr;
    jstring jstr = NULL;
    jboolean isCopy;
    get_lock();
    JNIEnv* local_env = m_env;
    int isAttached = check_and_attach(m_jvm, local_env);
    release_lock();
    jstr = (jstring)local_env->CallObjectMethod(jobjIT, midgetBindingObject, local_env->NewStringUTF(file_name));

    if (local_env->ExceptionOccurred()) {
        debug_printf("[BINDING-COMMONS]  -  @GS_Get_Object  -  Error: Exception received when calling getObject.\n");
        local_env->ExceptionDescribe();
        release_lock();
        exit(1);
    }

    cstr = local_env->GetStringUTFChars(jstr, &isCopy);
    *buf = strdup(cstr);
    local_env->ReleaseStringUTFChars(jstr, cstr);
    if (isAttached==1) {
        m_jvm->DetachCurrentThread();
    }
    debug_printf("[BINDING-COMMONS]  -  @GS_Get_Object  -  COMPSs data id: %s\n", *buf);

}

void GS_Delete_Object(char *file_name, int **buf) {
	get_lock();

	int isAttached = check_and_attach(m_jvm, m_env);

    jboolean res = m_env->CallBooleanMethod(jobjIT, midDeleteBindingObject, m_env->NewStringUTF(file_name));
    if (m_env->ExceptionOccurred()) {
        debug_printf("[BINDING-COMMONS]  -  @GS_Delete_Binding_Object  -  Error: Exception received when calling deleteObject.\n");
        m_env->ExceptionDescribe();
        release_lock();
        exit(1);
    }
    *buf = (int*)&res;
    if (isAttached==1) {
        m_jvm->DetachCurrentThread();
    }
    release_lock();
    debug_printf("[BINDING-COMMONS]  -  @GS_Delete_Binding_Object  -  COMPSs obj: %s\n", file_name);
}

void GS_Barrier(long _appId) {
	debug_printf("[BINDING-COMMONS]  -  @GS_Barrier  -  Waiting tasks for APP id: %lu\n", appId);
    get_lock();
    JNIEnv* local_env = m_env;
    int isAttached = check_and_attach(m_jvm, local_env);
	release_lock();

	local_env->CallVoidMethod(jobjIT, midBarrier, appId);

    if (local_env->ExceptionOccurred()) {
        local_env->ExceptionDescribe();
        exit(1);
    }

    if (isAttached==1) {
        m_jvm->DetachCurrentThread();
    }
    debug_printf("[BINDING-COMMONS]  -  @GS_Barrier  -  APP id: %lu\n", appId);
}

void GS_BarrierNew(long _appId, int noMoreTasks) {
	get_lock();
	JNIEnv* local_env = m_env;
	int isAttached = check_and_attach(m_jvm, local_env);

    bool _noMoreTasks = false;
    if (noMoreTasks != 0) _noMoreTasks = true;

    debug_printf("[   BINDING]  -  @GS_Barrier  -  Waiting tasks for APP id: %lu\n", appId);
    debug_printf("[   BINDING]  -  @GS_Barrier  -  noMoreTasks: %s\n", _noMoreTasks ? "true":"false");
    release_lock();

    local_env->CallVoidMethod(jobjIT, midBarrierNew, appId, _noMoreTasks);

    if (local_env->ExceptionOccurred()) {
        local_env->ExceptionDescribe();
        GS_Off(1);
        exit(1);
    }

    if (isAttached==1) {
        m_jvm->DetachCurrentThread();
    }
    debug_printf("[BINDING-COMMONS]  -  @GS_Barrier  -  APP id: %lu\n", appId);
}

void GS_BarrierGroup(long _appId, char *group_name, char **exception_message) {
    jstring jstr = NULL;
    get_lock();
    JNIEnv* local_env = m_env;
    int isAttached = check_and_attach(m_jvm, local_env);
    release_lock();
    local_env->CallVoidMethod(jobjIT, midBarrierGroup, appId, local_env->NewStringUTF(group_name));
    jthrowable exception = local_env->ExceptionOccurred();
    if (exception) {
        local_env->ExceptionDescribe();
        getReceivedException(local_env, exception, exception_message);
    }
    if (isAttached==1) {
        m_jvm->DetachCurrentThread();
    }
    debug_printf("[BINDING-COMMONS]  -  @GS_BarrierGroup  -  COMPSs group name: %s\n", group_name);
}

void GS_OpenTaskGroup(char *group_name, int implicitBarrier, long _appId){
    jstring jstr = NULL;
    get_lock();
    JNIEnv* local_env = m_env;
    int isAttached = check_and_attach(m_jvm, local_env);
    bool _implicitBarrier = false;
    if (implicitBarrier != 0) _implicitBarrier = true;
    release_lock();
    local_env->CallVoidMethod(jobjIT, midOpenTaskGroup, local_env->NewStringUTF(group_name), _implicitBarrier, appId);

    if (local_env->ExceptionOccurred()) {
        local_env->ExceptionDescribe();
        exit(1);
    }
    if (isAttached==1) {
        m_jvm->DetachCurrentThread();
    }
    debug_printf("[BINDING-COMMONS]  -  @GS_OpenTaskGroup  -  COMPSs group name: %s\n", group_name);
    debug_printf("[BINDING-COMMONS]  -  @GS_OpenTaskGroup  -  implicit barrier: %s\n", _implicitBarrier ? "true":"false");
}

void GS_CloseTaskGroup(char *group_name, long _appId){
    jstring jstr = NULL;
    get_lock();
    JNIEnv* local_env = m_env;
    int isAttached = check_and_attach(m_jvm, local_env);
    release_lock();
    local_env->CallVoidMethod(jobjIT, midCloseTaskGroup, local_env->NewStringUTF(group_name), appId);

    if (local_env->ExceptionOccurred()) {
        local_env->ExceptionDescribe();
        GS_Off(1);
        exit(1);
    }
    if (isAttached==1) {
        m_jvm->DetachCurrentThread();
    }
    debug_printf("[BINDING-COMMONS]  -  @GS_CloseTaskGroup  -  COMPSs group name: %s\n", group_name);
}

void GS_EmitEvent(int type, long id) {
	get_lock();
	int isAttached = check_and_attach(m_jvm, m_env);

    if ( (type < 0 ) or (id < 0) ) {
        debug_printf ("[BINDING-COMMONS]  -  @GS_EmitEvent  -  Error: event type and ID must be positive integers, but found: type: %u, ID: %lu\n", type, id);
        release_lock();
        GS_Off(1);
        exit(1);
    } else {
        debug_printf ("[BINDING-COMMONS]  -  @GS_EmitEvent  -  Type: %u, ID: %lu\n", type, id);
        m_env->CallVoidMethod(jobjIT, midEmitEvent, type, id);
        if (m_env->ExceptionOccurred()) {
            m_env->ExceptionDescribe();
            release_lock();
            GS_Off(1);
            exit(1);
        }
    }

    if (isAttached==1) {
        m_jvm->DetachCurrentThread();
    }
    release_lock();
}


text:
\setcounter{footnote}{0}

1. Once upon a time there was a certain person called Eh-Hk'eh (ɛ̀-qhɛ̀).

2. Day after day he would fish out his pecker\footnote{Since Lahu has only a single word for the sexual organs (\textbf{nī} `penis', \textbf{cha} `vagina') it is a problem choosing among the myriad English synonyms to find the ones that works best in a given context. I here choose to translate \textbf{nī} as `pecker', both because it fits the jocular mood of the narrative, and because it suggests a connection with the episode of the \textit{bird} later in the story.} and trap insects\footnote{It is not clear what aspect of the Trickster's organ was so dangerously attractive to insects.} with it.

3. When a fly would come within reach he would cover it up under his clothes [to
trap it].\footnote{\textbf{šôʔ-bɛ} (V) lit. ``press-cover''; `cover an exposed part with one's clothing'.}

4. Once it happened to be a honeybee.

5. When the honeybee happened along, he tried to cover it up under his clothes,
and it stung him.

6. When he got stung, because where he tried to cover it up and where it stung
him was the same place, he cursed it, saying, ``This bee is a wretched foul bee!''
\footnote{\textbf{lù...kɨ̂} is an elaborate couplet (\textbf{lù} `be ruined', \textbf{kɨ̂} `be rotten', occurring in a large number of similar expressions, e.g. \textbf{yâ-lù-yâ-kɨ̂} `little brat' (\textbf{yâ} `child'); \textbf{chɔ-lù-chɔ-kɨ̂} `miserable person'.}

7. So after that he whipped out his pecker again and managed to catch some insects
[with it], then he went and set them free in a place where chickens were being
fed.

8. Right away the chickens pecked at [the trapped bugs] and nibbled at them.\footnote{The painfulness of this experience for the Trickster is emphasized by \textbf{šē} (Pv) `regretful state of affairs'.}

9. When the chickens pecked and nibbled at him he sobbed bitterly, that guy.

10. So they gave him one chicken [as compensation].

11. After he got the chicken he then went to a place where pigs were fed, and proceeded
\footnote{`Proceeded' is an attempt to translate \textbf{qɔ̀ʔ} (vV) `go on and do something else'. See sense \#5 of \textbf{qɔ̀ʔ} in DL:259.} to let it [the chicken] go free.

12. So then the pigs bit it to death.

13. When they bit it to death, he sobbed bitterly.

14. Since he was sobbing so much, they proceeded to give him a pig---they [just
gave it] to him.

15. So leading the pig, he went and set it free in somebody's cattle-pen.

16. When he set it free in there, the cattle kicked it the hell\footnote{`The hell' translates \textbf{g̈ɔ̀} (vV) `vivid/violent action'.} to death.

17. So then he sat down there and sobbed with all his might.

18. Since he was crying [so much] they gave him a cow.

19. Leading this cow, this time he went and set it free in an elephant corral.

20. So then the elephant(s) killed that cow of his.

21. Whereupon he sat down there and cried his eyes out.

22. Since he was crying [so much] they finally gave him an elephant.

23. Then, leading this elephant he went and let it go free in a potter's workshop.

24. His elephant stepped on the pots and shattered them.\footnote{\textbf{nâʔ-khô} `shatter by stepping on'}

25. Since it had trampled his pots to pieces, the other guy [the potter] \{took/got\}
his elephant.

26. So then he sat down there and wept bitterly.

27. While he was crying, a bird came and called out to him.

28. What that bird was calling was \textbf{kru-g̈âʔ kru-g̈âʔ}.\footnote{This imitative sequence kr- does not occur in any other Lahu word. This binome is also used as a noun, to signify a species of dove-like bird. See DL:362.}

29. So then he let fly with a potsherd, and he got it.

30. He caught it, plucked it and roasted it, and it was very fat.

31. Since it was so fat, he smeared the fat onto his pecker.

32. As soon as he had smeared it on, his pecker began to sing.

33. It sang \textbf{kru-g̈âʔ kru-g̈âʔ}, and no matter what he did it didn't
get better.\footnote{I.e., he couldn't stop his penis from chirping.}

34. But then, when he scorched [his penis] with the [hot] potsherd, he was cured.

35. So then he took along some of that bird-fat and went to a place where a princess
was doing some weaving.

36. Then after he had smeared some of that bird-fat onto her stool\footnote{The raconteur leaves out any mention of the princess sitting down on her weaving-stool, but that is taken for granted.}, her pussy
began to sing.

37. When her pussy sang, it just sang \textbf{kru-g̈âʔ kru-g̈âʔ}.

38. So then they sought all the physicians in the city to have them cure her.

39. [But] no matter who treated her, she did not get better.

40. Whoever it was who treated her, she was not cured.

41. Finally they said to ɛ̀-qhɛ̀, ``Oh, if you can cure this woman, take her
for your wife!

42. ``And furthermore, if you can cure her, you will be given half of the kingdom,''
they said to him.

43. So then ɛ̀-qhɛ̀ went and scorched [her] with that hot potsherd, and she
was cured.

44. She was cured, so he got the princess, and also got control of half the country.

redpajama_set_name: RedPajamaGithub


text:
/*
 * Creates all the demo application tasks, then starts the scheduler.  The WEB
 * documentation provides more details of the standard demo application tasks.
 * In addition to the standard demo tasks, the following tasks and tests are
 * defined and/or created within this file:
 *
 * "Fast Interrupt Test" - A high frequency periodic interrupt is generated
 * using a free running timer to demonstrate the use of the
 * configKERNEL_INTERRUPT_PRIORITY configuration constant.  The interrupt
 * service routine measures the number of processor clocks that occur between
 * each interrupt - and in so doing measures the jitter in the interrupt timing.
 * The maximum measured jitter time is latched in the ulMaxJitter variable, and
 * displayed on the LCD by the 'Check' task as described below.  The
 * fast interrupt is configured and handled in the timertest.c source file.
 *
 * "LCD" task - the LCD task is a 'gatekeeper' task.  It is the only task that
 * is permitted to access the display directly.  Other tasks wishing to write a
 * message to the LCD send the message on a queue to the LCD task instead of
 * accessing the LCD themselves.  The LCD task just blocks on the queue waiting
 * for messages - waking and displaying the messages as they arrive.  Messages
 * can either be a text string to display, or an instruction to update MEMS
 * input.  The MEMS input is used to display a ball that can be moved around
 * LCD by tilting the STM32 Primer.  45% is taken as the neutral position.
 *
 * "Check" task -  This only executes every five seconds but has the highest
 * priority so is guaranteed to get processor time.  Its main function is to
 * check that all the standard demo tasks are still operational.  Should any
 * unexpected behaviour within a demo task be discovered the 'check' task will
 * write an error to the LCD (via the LCD task).  If all the demo tasks are
 * executing with their expected behaviour then the check task writes PASS
 * along with the max jitter time to the LCD (again via the LCD task), as
 * described above.
 *
 * Tick Hook - A tick hook is provided just for demonstration purposes.  In
 * this case it is used to periodically send an instruction to updated the
 * MEMS input to the LCD task.
 *
 */

/* CircleOS includes.  Some of the CircleOS peripheral functionality is
utilised, although CircleOS itself is not used. */
#include "circle.h"

/* Standard includes. */
#include <string.h>

/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"

/* Demo app includes. */
#include "BlockQ.h"
#include "blocktim.h"
#include "GenQTest.h"
#include "partest.h"
#include "QPeek.h"

/* The bitmap used to display the FreeRTOS.org logo is stored in 16bit format
and therefore takes up a large proportion of the Flash space.  Setting this
parameter to 0 excludes the bitmap from the build, freeing up Flash space for
extra code. */
#define mainINCLUDE_BITMAP 					0

#if mainINCLUDE_BITMAP == 1
	#include "bitmap.h"
#endif

/* Task priorities. */
#define mainQUEUE_POLL_PRIORITY				( tskIDLE_PRIORITY + 2 )
#define mainCHECK_TASK_PRIORITY				( tskIDLE_PRIORITY + 3 )
#define mainBLOCK_Q_PRIORITY				( tskIDLE_PRIORITY + 2 )
#define mainGEN_Q_PRIORITY					( tskIDLE_PRIORITY + 0 )
#define mainFLASH_TASK_PRIORITY				( tskIDLE_PRIORITY + 2 )

/* Splash screen related constants. */
#define mainBITMAP_Y 						( 38 )
#define mainBITMAP_X						( 18 )
#define mainURL_Y							( 8 )
#define mainURL_X							( 78 )
#define mainSPLASH_SCREEN_DELAY		( 2000 / portTICK_PERIOD_MS )

/* Text drawing related constants. */
#define mainLCD_CHAR_HEIGHT			( 13 )
#define mainLCD_MAX_Y				( 110 )

/* The maximum number of message that can be waiting for display at any one
time. */
#define mainLCD_QUEUE_SIZE					( 3 )

/* The check task uses the sprintf function so requires a little more stack. */
#define mainCHECK_TASK_STACK_SIZE			( configMINIMAL_STACK_SIZE + 50 )

/* The LCD task calls some of the CircleOS functions (for MEMS and LCD access),
these can require a larger stack. */
#define configLCD_TASK_STACK_SIZE			( configMINIMAL_STACK_SIZE + 50 )

/* Dimensions the buffer into which the jitter time is written. */
#define mainMAX_MSG_LEN						25

/* The time between cycles of the 'check' task. */
#define mainCHECK_DELAY						( ( TickType_t ) 5000 / portTICK_PERIOD_MS )

/* The period at which the MEMS input should be updated. */
#define mainMEMS_DELAY						( ( TickType_t ) 100 / portTICK_PERIOD_MS )

/* The rate at which the flash task toggles the LED. */
#define mainFLASH_DELAY						( ( TickType_t ) 1000 / portTICK_PERIOD_MS )

/* The number of nano seconds between each processor clock. */
#define mainNS_PER_CLOCK ( ( unsigned long ) ( ( 1.0 / ( double ) configCPU_CLOCK_HZ ) * 1000000000.0 ) )

/* The two types of message that can be sent to the LCD task. */
#define mainUPDATE_BALL_MESSAGE				( 0 )
#define mainWRITE_STRING_MESSAGE			( 1 )

/* Type of the message sent to the LCD task. */
typedef struct
{
	portBASE_TYPE xMessageType;
	signed char *pcMessage;
} xLCDMessage;

/*-----------------------------------------------------------*/

/*
 * Configure the clocks, GPIO and other peripherals as required by the demo.
 */
static void prvSetupHardware( void );

/*
 * The LCD is written two by more than one task so is controlled by a
 * 'gatekeeper' task.  This is the only task that is actually permitted to
 * access the LCD directly.  Other tasks wanting to display a message send
 * the message to the gatekeeper.
 */
static void prvLCDTask( void *pvParameters );

/*
 * Checks the status of all the demo tasks then prints a message to the
 * display.  The message will be either PASS - and include in brackets the
 * maximum measured jitter time (as described at the to of the file), or a
 * message that describes which of the standard demo tasks an error has been
 * discovered in.
 *
 * Messages are not written directly to the terminal, but passed to prvLCDTask
 * via a queue.
 *
 * The check task also receives instructions to update the MEMS input, which
 * in turn can also lead to the LCD being updated.
 */
static void prvCheckTask( void *pvParameters );

/*
 * Configures the timers and interrupts for the fast interrupt test as
 * described at the top of this file.
 */
extern void vSetupTimerTest( void );

/*
 * A cut down version of sprintf() used to percent the HUGE GCC library
 * equivalent from being included in the binary image.
 */
extern int sprintf(char *out, const char *format, ...);

/*
 * Simple toggle the LED periodically for timing verification.
 */
static void prvFlashTask( void *pvParameters );

/*-----------------------------------------------------------*/

/* The queue used to send messages to the LCD task. */
QueueHandle_t xLCDQueue;

/*-----------------------------------------------------------*/

int main( void )
{
	#ifdef DEBUG
		debug();
	#endif

	prvSetupHardware();

	/* Create the queue used by the LCD task.  Messages for display on the LCD
	are received via this queue. */
	xLCDQueue = xQueueCreate( mainLCD_QUEUE_SIZE, sizeof( xLCDMessage ) );

	/* Start the standard demo tasks. */
	vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
    vCreateBlockTimeTasks();
	vStartGenericQueueTasks( mainGEN_Q_PRIORITY );
	vStartQueuePeekTasks();
	vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY );

	/* Start the tasks defined within this file/specific to this demo. */
    xTaskCreate( prvCheckTask, "Check", mainCHECK_TASK_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL );
	xTaskCreate( prvLCDTask, "LCD", configLCD_TASK_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );
	xTaskCreate( prvFlashTask, "Flash", configMINIMAL_STACK_SIZE, NULL, mainFLASH_TASK_PRIORITY, NULL );

	/* Configure the timers used by the fast interrupt timer test. */
	vSetupTimerTest();

	/* Start the scheduler. */
	vTaskStartScheduler();

	/* Will only get here if there was not enough heap space to create the
	idle task. */
	return 0;
}
/*-----------------------------------------------------------*/

void prvLCDTask( void *pvParameters )
{
xLCDMessage xMessage;
char cY = mainLCD_CHAR_HEIGHT;
const char * const pcString = "www.FreeRTOS.org";
const char * const pcBlankLine = "                  ";

	DRAW_Init();

	#if mainINCLUDE_BITMAP == 1
		DRAW_SetImage( pucImage, mainBITMAP_Y, mainBITMAP_X, bmpBITMAP_HEIGHT, bmpBITMAP_WIDTH );
	#endif

	LCD_SetScreenOrientation( V9 );
	DRAW_DisplayString( mainURL_Y, mainURL_X, pcString, strlen( pcString ) );
	vTaskDelay( mainSPLASH_SCREEN_DELAY );
	LCD_FillRect( 0, 0, CHIP_SCREEN_WIDTH, CHIP_SCREEN_HEIGHT, RGB_WHITE );

	for( ;; )
	{
		/* Wait for a message to arrive that requires displaying. */
		while( xQueueReceive( xLCDQueue, &xMessage, portMAX_DELAY ) != pdPASS );

		/* Check the message type. */
		if( xMessage.xMessageType == mainUPDATE_BALL_MESSAGE )
		{
			/* Read the MEMS and update the ball display on the LCD if required. */
			MEMS_Handler();
			POINTER_Handler();
		}
		else
		{
			/* A text string was sent.  First blank off the old text string, then
			draw the new text on the next line down. */
			DRAW_DisplayString( 0, cY, pcBlankLine, strlen( pcBlankLine ) );

			cY -= mainLCD_CHAR_HEIGHT;
			if( cY <= ( mainLCD_CHAR_HEIGHT - 1 ) )
			{
				/* Wrap the line onto which we are going to write the text. */
				cY = mainLCD_MAX_Y;
			}

			/* Display the message. */
			DRAW_DisplayString( 0, cY, xMessage.pcMessage, strlen( xMessage.pcMessage ) );
		}
	}
}
/*-----------------------------------------------------------*/

static void prvCheckTask( void *pvParameters )
{
TickType_t xLastExecutionTime;
xLCDMessage xMessage;
static signed char cPassMessage[ mainMAX_MSG_LEN ];
extern unsigned short usMaxJitter;

	/* Initialise the xLastExecutionTime variable on task entry. */
	xLastExecutionTime = xTaskGetTickCount();

	/* Setup the message we are going to send to the LCD task. */
	xMessage.xMessageType = mainWRITE_STRING_MESSAGE;
	xMessage.pcMessage = cPassMessage;

    for( ;; )
	{
		/* Perform this check every mainCHECK_DELAY milliseconds. */
		vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY );

		/* Has an error been found in any task?   If so then point the text
		we are going to send to the LCD task to an error message instead of
		the PASS message. */
		if( xAreGenericQueueTasksStillRunning() != pdTRUE )
		{
			xMessage.pcMessage = "ERROR IN GEN Q";
		}
        if( xAreBlockingQueuesStillRunning() != pdTRUE )
		{
			xMessage.pcMessage = "ERROR IN BLOCK Q";
		}
		else if( xAreBlockTimeTestTasksStillRunning() != pdTRUE )
		{
			xMessage.pcMessage = "ERROR IN BLOCK TIME";
		}
        else if( xArePollingQueuesStillRunning() != pdTRUE )
        {
            xMessage.pcMessage = "ERROR IN POLL Q";
        }
		else if( xAreQueuePeekTasksStillRunning() != pdTRUE )
		{
			xMessage.pcMessage = "ERROR IN PEEK Q";
		}
		else
		{
			/* No errors were found in any task, so send a pass message
			with the max measured jitter time also included (as per the
			fast interrupt test described at the top of this file and on
			the online documentation page for this demo application). */
			sprintf( ( char * ) cPassMessage, "PASS [%uns]", ( ( unsigned long ) usMaxJitter ) * mainNS_PER_CLOCK );
		}

		/* Send the message to the LCD gatekeeper for display. */
		xQueueSend( xLCDQueue, &xMessage, portMAX_DELAY );
	}
}
/*-----------------------------------------------------------*/

void vApplicationTickHook( void )
{
static unsigned long ulCallCount;
static const xLCDMessage xMemsMessage = { mainUPDATE_BALL_MESSAGE, NULL };
static portBASE_TYPE xHigherPriorityTaskWoken;

	/* Periodically send a message to the LCD task telling it to update
	the MEMS input, and then if necessary the LCD. */
	ulCallCount++;
	if( ulCallCount >= mainMEMS_DELAY )
	{
		ulCallCount = 0;
		xHigherPriorityTaskWoken = pdFALSE;
		xQueueSendFromISR( xLCDQueue, &xMemsMessage, &xHigherPriorityTaskWoken );
	}
}
/*-----------------------------------------------------------*/

static void prvSetupHardware( void )
{
	/* Start with the clocks in their expected state. */
	RCC_DeInit();

	/* Enable HSE (high speed external clock). */
	RCC_HSEConfig( RCC_HSE_ON );

	/* Wait till HSE is ready. */
	while( RCC_GetFlagStatus( RCC_FLAG_HSERDY ) == RESET )
	{
	}

	/* 2 wait states required on the flash. */
	*( ( unsigned long * ) 0x40022000 ) = 0x02;

	/* HCLK = SYSCLK */
	RCC_HCLKConfig( RCC_SYSCLK_Div1 );

	/* PCLK2 = HCLK */
	RCC_PCLK2Config( RCC_HCLK_Div1 );

	/* PCLK1 = HCLK/2 */
	RCC_PCLK1Config( RCC_HCLK_Div2 );

	/* PLLCLK = 12MHz * 6 = 72 MHz. */
	RCC_PLLConfig( RCC_PLLSource_HSE_Div1, RCC_PLLMul_6 );

	/* Enable PLL. */
	RCC_PLLCmd( ENABLE );

	/* Wait till PLL is ready. */
	while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
	{
	}

	/* Select PLL as system clock source. */
	RCC_SYSCLKConfig( RCC_SYSCLKSource_PLLCLK );

	/* Wait till PLL is used as system clock source. */
	while( RCC_GetSYSCLKSource() != 0x08 )
	{
	}

	/* Enable GPIOA, GPIOB, GPIOC, GPIOD, GPIOE and AFIO clocks */
	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC
							| RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE );

	/* SPI2 Periph clock enable */
	RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI2, ENABLE );

	/* Set the Vector Table base address at 0x08000000 */
	NVIC_SetVectorTable( NVIC_VectTab_FLASH, 0x0 );

	NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );

	/* Configure HCLK clock as SysTick clock source. */
	SysTick_CLKSourceConfig( SysTick_CLKSource_HCLK );

	/* Misc initialisation, including some of the CircleOS features.  Note
	that CircleOS itself is not used. */
	vParTestInitialise();
	MEMS_Init();
	POINTER_Init();
	POINTER_SetMode( POINTER_RESTORE_LESS );
}
/*-----------------------------------------------------------*/

static void prvFlashTask( void *pvParameters )
{
TickType_t xLastExecutionTime;

	/* Initialise the xLastExecutionTime variable on task entry. */
	xLastExecutionTime = xTaskGetTickCount();

    for( ;; )
	{
		/* Simple toggle the LED periodically.  This just provides some timing
		verification. */
		vTaskDelayUntil( &xLastExecutionTime, mainFLASH_DELAY );
		vParTestToggleLED( 0 );
	}
}
/*-----------------------------------------------------------*/

void starting_delay( unsigned long ul )
{
	vTaskDelay( ( TickType_t ) ul );
}


text:
package fr.univ_lille.cristal.emeraude.chasqui.porting

import java.awt._
import java.awt.event.{ActionEvent, ActionListener}
import java.util.concurrent.TimeUnit
import javax.swing.{JFrame, JPanel, SwingUtilities, Timer}

import akka.actor.Actor
import akka.util.Timeout

import scala.collection.mutable
import scala.util.{Failure, Success}

/**
  * Created by guille on 24/04/17.
  */
class SynapsesWeightGraphActor(outputs: Seq[TypedNeuron],
                               numberToIgnoreLeft: Int = 0,
                               caseWidth: Int = 8,
                               caseHeight: Int = 8,
                               refreshRate: Int = 1000 / 24,
                               viewPanel: JPanel = null,
                               rowWidth:Int) extends Actor {

  import context._
  implicit val timeout = Timeout(60, TimeUnit.SECONDS)

  private val views = mutable.Map[TypedNeuron, SynapsesWeight2DPixel]()
  var frame: Container = viewPanel

  SwingUtilities.invokeAndWait(() => {
    if (frame == null) {
      frame = new JFrame()
      frame.setLayout(new FlowLayout)
    }

    outputs.foreach ( neuron => {
      val aSynapseWeight2DPixel = new SynapsesWeight2DPixel(rowWidth, caseWidth, caseHeight)
      views.+= (neuron -> aSynapseWeight2DPixel)
      frame.add(aSynapseWeight2DPixel)
    })

    frame.setVisible(true)
    frame.setSize(new Dimension(800, 1000))
  }
  )

  private val delay = refreshRate / outputs.size
  private var currentN = 0
  private val taskPerformer = new ActionListener() {
    override def actionPerformed(actionEvent:  ActionEvent): Unit = {
      update(currentN)
      currentN = (currentN + 1) % outputs.size
    }
  }
  val timer = new Timer(delay, taskPerformer)
  timer.start()

  def update(n: Int): Unit = {
    views.toSeq(n) match {
      case (path, view) =>
        val weightsF = path.getIngoingConnectionWeights()
        weightsF onComplete {
          case Success(weights) => {
            view.updateValue(weights.take(weights.size - numberToIgnoreLeft))
            SwingUtilities.invokeLater(() => {
              view.repaint()
              frame.revalidate()
            })
          }
          case Failure(t) => println("Error while fetching neuron synapses")
        }
      case other => throw new Exception("Unknown " + other)
    }
  }

  def receive = {
    case m => println("[SynapsesWeightGraphActor] Unknown message " + m)
  }
}

class SynapsesWeight2DPixel(layerWidth: Int = 0, caseWidth: Int = 1, caseHeight: Int = 1) extends JPanel {
  var hasValidValues = false
  var isInited = false
  private var colorMap = Array.ofDim[Int](1, 1)

  def updateValue(values: Seq[Double]) : Unit = {
    hasValidValues = true
    val width = math.min(layerWidth, values.size)
    val height = Math.ceil(values.size.asInstanceOf[Float] / layerWidth).asInstanceOf[Int]
    colorMap = Array.ofDim[Int](width, height)

    val min_v = if (values.isEmpty) 0 else values.min
    val max_v = if (values.isEmpty) 1.0 else values.max

    values.zipWithIndex.foreach { case (value, index) =>
      val color = if (value < 0) {
        val v = ((value / math.min(-1.0f, min_v)) * 255f).toInt
        (v << 16) + (v << 8) + v
      }
      else {
        val v = value / math.max(1.0f, max_v)
        val rc = (math.max(0f, -2f * v * v + 4f * v - 1f) * 255f).toInt
        val bc = (math.max(0f, -2f * v * v + 1) * 255f).toInt
        val gc = (math.max(0f, 4f * v * (-v + 1f)) * 255f).toInt
        (rc << 16) + (gc << 8) + bc
      }
      colorMap(index % layerWidth)(index / layerWidth) = color
    }

    if (!isInited) {
      val d = new Dimension(width * caseWidth, height * caseHeight)
      setPreferredSize(d)
      setSize(d)
      isInited = true
    }
  }

  override def paintComponent(g: Graphics): Unit = {
    if (!hasValidValues) {
      return
    }

    for ((line, x) <- colorMap.zipWithIndex) {
      for ((v, y) <- line.zipWithIndex) {
        g.setColor(new Color(v))
        g.fillRect(x * caseWidth, y * caseHeight, caseWidth, caseHeight)
      }
    }
  }

  def destroy(): Unit = {

  }
}


text:
clone

git submodule update --init --recursive

cd osn-crawler

mvn clean install

cd ../social/scripts

./download_redis_kafka.sh

./start_redis_zoo_kafka.sh

./status_redis_zoo_kafka.sh

cd ../social

./activator run

try it on 77.234.213.237:9000


text:
package com.reward.omotesando.fragments;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;

import com.reward.omotesando.models.Item;

/**
 * ポイント交換確認ダイアログ。
 */
public class ExchangeDialogFragment extends DialogFragment {
    private static final String ARG_TITLE = "title";
    private static final String ARG_MESSAGE = "message";
    private static final String ARG_ITEM = "item";

    private static ProgressDialog progressDialog = null;

    private OnExchangeDialogListener mListener;

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param title Parameter 1.
     * @param message Parameter 2.
     * @param item Parameter 2.
     * @return A new instance of fragment ProgressDialogFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static ExchangeDialogFragment newInstance(String title, String message, Item item) {
        ExchangeDialogFragment fragment = new ExchangeDialogFragment();
        Bundle args = new Bundle();
        if (title != null) {
            args.putString(ARG_TITLE, title);
        }
        args.putString(ARG_MESSAGE, message);
        args.putSerializable(ARG_ITEM, item);
        fragment.setArguments(args);
        return fragment;
    }

    public ExchangeDialogFragment() {
        // Required empty public constructor
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        Fragment targetFragment = this.getTargetFragment();
        try {
            mListener = (OnExchangeDialogListener) targetFragment;
        } catch (ClassCastException e) {
            throw new ClassCastException("Don't implement OnExchangeDialogListener.");
        }
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        if (progressDialog != null) {
            return progressDialog;
        }

        String title = getArguments().getString(ARG_TITLE);
        final Item item = (Item) getArguments().getSerializable(ARG_ITEM);
        String message = getArguments().getString(ARG_MESSAGE);

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
                .setTitle(title)
                .setMessage(message)
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        mListener.onExchangeDialogClick(which, item);
                    }
                })
                .setNegativeButton("Cancel", null);

        return builder.create();
    }

    @Override
    public Dialog getDialog(){
        return progressDialog;
    }

    @Override
    public void onDestroy(){
        super.onDestroy();
        progressDialog = null;
    }

    public static interface OnExchangeDialogListener {
        public void onExchangeDialogClick(int which, Item item);
    }

}


text:
export function isFunction(func) {
	if (typeof func === 'function' && func.call) {
		return true;
	}

	return false;
}


text:
package org.sagebionetworks.repo.manager.loginlockout;

import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.sagebionetworks.repo.model.UnsuccessfulLoginLockoutDAO;
import org.sagebionetworks.repo.model.UnsuccessfulLoginLockoutDTO;

@RunWith(MockitoJUnitRunner.class)
public class ExponentialBackoffAttemptReporterTest {
	@Mock
	UnsuccessfulLoginLockoutDAO mockUnsuccessfulLoginLockoutDAO;

	final long userId = 12345L;

	final long unsuccessfulLoginCount = 3;

	UnsuccessfulLoginLockoutDTO lockoutInfo;

	ExponentialBackoffLoginAttemptReporter reporter;

	@Before
	public void setUp() throws Exception {
		lockoutInfo = new UnsuccessfulLoginLockoutDTO(userId).withUnsuccessfulLoginCount(unsuccessfulLoginCount);
		reporter = new ExponentialBackoffLoginAttemptReporter(lockoutInfo, mockUnsuccessfulLoginLockoutDAO);
	}

	@Test(expected = IllegalArgumentException.class)
	public void testConstructor_nullDTO(){
		new ExponentialBackoffLoginAttemptReporter(null, mockUnsuccessfulLoginLockoutDAO);
	}

	@Test(expected = IllegalArgumentException.class)
	public void testConstructor_nullDAO(){
		new ExponentialBackoffLoginAttemptReporter(lockoutInfo, null);
	}

	@Test
	public void testReportSuccess() {
		reporter.reportSuccess();

		verify(mockUnsuccessfulLoginLockoutDAO).createOrUpdateUnsuccessfulLoginLockoutInfo(new UnsuccessfulLoginLockoutDTO(userId));
		verifyNoMoreInteractions(mockUnsuccessfulLoginLockoutDAO);
	}

	@Test
	public void testReportFailure() {
		final long databaseTimeStamp = 3133641630824L;
		when(mockUnsuccessfulLoginLockoutDAO.getDatabaseTimestampMillis()).thenReturn(databaseTimeStamp);

		reporter.reportFailure();

		UnsuccessfulLoginLockoutDTO expected = new UnsuccessfulLoginLockoutDTO(userId)
			.withUnsuccessfulLoginCount(unsuccessfulLoginCount + 1) // 3 + 1 = 4
				.withLockoutExpiration(databaseTimeStamp + 16); // 2^4 = 16

		verify(mockUnsuccessfulLoginLockoutDAO).getDatabaseTimestampMillis();
		verify(mockUnsuccessfulLoginLockoutDAO).createOrUpdateUnsuccessfulLoginLockoutInfo(expected);
		verifyNoMoreInteractions(mockUnsuccessfulLoginLockoutDAO);
	}

	@Test
	public void testReportSuccessAndReportFailureIdempotent(){
		reporter.reportSuccess();
		reporter.reportFailure();
		reporter.reportSuccess();

		verify(mockUnsuccessfulLoginLockoutDAO, times(1)).createOrUpdateUnsuccessfulLoginLockoutInfo(new UnsuccessfulLoginLockoutDTO(userId));
		verifyNoMoreInteractions(mockUnsuccessfulLoginLockoutDAO);
	}
}


text:
package de.robotricker.transportpipes.rendersystems.pipe.modelled;

import org.bukkit.entity.Player;
import org.bukkit.util.Vector;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import de.robotricker.transportpipes.duct.Duct;
import de.robotricker.transportpipes.duct.DuctRegister;
import de.robotricker.transportpipes.duct.pipe.Pipe;
import de.robotricker.transportpipes.hitbox.AxisAlignedBB;
import de.robotricker.transportpipes.items.ItemService;
import de.robotricker.transportpipes.location.TPDirection;
import de.robotricker.transportpipes.protocol.ArmorStandData;
import de.robotricker.transportpipes.rendersystems.ModelledRenderSystem;
import de.robotricker.transportpipes.rendersystems.pipe.modelled.model.ModelledPipeModel;
import de.robotricker.transportpipes.rendersystems.pipe.modelled.model.data.ModelledPipeConnectionModelData;

public class ModelledPipeRenderSystem extends ModelledRenderSystem {

    private ModelledPipeModel model = new ModelledPipeModel();

    private Map<Pipe, ArmorStandData> midASD = new HashMap<>();
    private Map<Pipe, Map<TPDirection, ArmorStandData>> connASD = new HashMap<>();
    private AxisAlignedBB midAABB;
    private Map<TPDirection, AxisAlignedBB> connAABBs = new HashMap<>();

    @Inject
    public ModelledPipeRenderSystem(ItemService itemService, DuctRegister ductRegister) {
        super(ductRegister.baseDuctTypeOf("Pipe"));
        ModelledPipeModel.init(itemService, ductRegister);

        midAABB = new AxisAlignedBB(4d / 16d, 4d / 16d, 4d / 16d, 12d / 16d, 12d / 16d, 12d / 16d);
        connAABBs.put(TPDirection.NORTH, new AxisAlignedBB(4d / 16d, 4d / 16d, 0d / 16d, 12d / 16d, 12d / 16d, 4d / 16d));
        connAABBs.put(TPDirection.EAST, new AxisAlignedBB(12d / 16d, 4d / 16d, 4d / 16d, 16d / 16d, 12d / 16d, 12d / 16d));
        connAABBs.put(TPDirection.SOUTH, new AxisAlignedBB(4d / 16d, 4d / 16d, 12d / 16d, 12d / 16d, 12d / 16d, 16d / 16d));
        connAABBs.put(TPDirection.WEST, new AxisAlignedBB(0d / 16d, 4d / 16d, 4d / 16d, 4d / 16d, 12d / 16d, 12d / 16d));
        connAABBs.put(TPDirection.UP, new AxisAlignedBB(4d / 16d, 12d / 16d, 4d / 16d, 12d / 16d, 16d / 16d, 12d / 16d));
        connAABBs.put(TPDirection.DOWN, new AxisAlignedBB(4d / 16d, 0d / 16d, 4d / 16d, 12d / 16d, 4d / 16d, 12d / 16d));

    }

    @Override
    public void createDuctASD(Duct duct, Collection<TPDirection> connections) {
        Pipe pipe = (Pipe) duct;
        if (midASD.containsKey(pipe)) {
            return;
        }

        midASD.put(pipe, model.createMidASD(pipe.getDuctType()));
        Map<TPDirection, ArmorStandData> connMap = new HashMap<>();
        for (TPDirection connDir : connections) {
            connMap.put(connDir, model.createConnASD(ModelledPipeConnectionModelData.createConnectionModelData(pipe, connDir)));
        }
        connASD.put(pipe, connMap);
    }

    @Override
    public void updateDuctASD(Duct duct, Collection<TPDirection> connections, List<ArmorStandData> removeASD, List<ArmorStandData> addASD) {
        Pipe pipe = (Pipe) duct;
        if (!midASD.containsKey(pipe) || !connASD.containsKey(pipe)) {
            return;
        }
        Map<TPDirection, ArmorStandData> connMap = connASD.get(pipe);

        for (TPDirection connDir : TPDirection.values()) {
            if (connMap.containsKey(connDir) && connections.contains(connDir)) {
                // direction was active before and after update
                ArmorStandData newASD = model.createConnASD(ModelledPipeConnectionModelData.createConnectionModelData(pipe, connDir));
                if (!connMap.get(connDir).isSimilar(newASD)) {
                    // ASD changed after update in this direction
                    removeASD.add(connMap.get(connDir));
                    addASD.add(newASD);
                    connMap.put(connDir, newASD);
                }
            } else if (!connMap.containsKey(connDir) && connections.contains(connDir)) {
                // direction wasn't active before update but direction IS active after update
                ArmorStandData newASD = model.createConnASD(ModelledPipeConnectionModelData.createConnectionModelData(pipe, connDir));
                addASD.add(newASD);
                connMap.put(connDir, newASD);
            } else if (connMap.containsKey(connDir) && !connections.contains(connDir)) {
                // direction was active before update but isn't active after update
                removeASD.add(connMap.get(connDir));
                connMap.remove(connDir);
            }
        }
    }

    @Override
    public void destroyDuctASD(Duct duct) {
        Pipe pipe = (Pipe) duct;
        midASD.remove(pipe);
        connASD.remove(pipe);
    }

    @Override
    public List<ArmorStandData> getASDForDuct(Duct duct) {
        Pipe pipe = (Pipe) duct;

        List<ArmorStandData> asd = new ArrayList<>();
        if (midASD.containsKey(pipe)) {
            asd.add(midASD.get(pipe));
        }
        if (connASD.containsKey(pipe)) {
            asd.addAll(connASD.get(pipe).values());
        }
        return asd;
    }

    @Override
    public AxisAlignedBB getOuterHitbox(Duct duct) {
        Pipe pipe = (Pipe) duct;
        if (pipe == null) {
            return null;
        }
        List<AxisAlignedBB> aabbs = new ArrayList<>();
        aabbs.add(midAABB);
        Collection<TPDirection> pipeConns = pipe.getAllConnections();
        for (TPDirection connDir : pipeConns) {
            aabbs.add(connAABBs.get(connDir));
        }
        double minx = Double.MAX_VALUE;
        double miny = Double.MAX_VALUE;
        double minz = Double.MAX_VALUE;
        double maxx = Double.MIN_VALUE;
        double maxy = Double.MIN_VALUE;
        double maxz = Double.MIN_VALUE;
        for (AxisAlignedBB aabb : aabbs) {
            minx = Math.min(aabb.getMin().getDoubleX(), minx);
            miny = Math.min(aabb.getMin().getDoubleY(), miny);
            minz = Math.min(aabb.getMin().getDoubleZ(), minz);
            maxx = Math.max(aabb.getMax().getDoubleX(), maxx);
            maxy = Math.max(aabb.getMax().getDoubleY(), maxy);
            maxz = Math.max(aabb.getMax().getDoubleZ(), maxz);
        }
        return new AxisAlignedBB(minx, miny, minz, maxx, maxy, maxz);
    }

    @Override
    public TPDirection getClickedDuctFace(Player player, Duct duct) {
        Pipe pipe = (Pipe) duct;
        Vector ray = player.getEyeLocation().getDirection();
        Vector origin = player.getEyeLocation().toVector();

        Collection<TPDirection> connDirs = pipe.getAllConnections();
        TPDirection clickedMidFace = midAABB.performRayIntersection(ray, origin, pipe.getBlockLoc());
        if (clickedMidFace != null && !connDirs.contains(clickedMidFace)) {
            return clickedMidFace;
        } else {
            double nearestDistanceSquared = Double.MAX_VALUE;
            TPDirection currentClickedConnFace = null;
            for (TPDirection connDir : connDirs) {
                AxisAlignedBB connAABB = connAABBs.get(connDir);
                double newDistanceSquared = connAABB.getAABBMiddle(pipe.getBlockLoc()).distanceSquared(origin);
                if (newDistanceSquared < nearestDistanceSquared) {
                    TPDirection clickedConnFace = connAABB.performRayIntersection(ray, origin, pipe.getBlockLoc());
                    if (clickedConnFace != null) {
                        nearestDistanceSquared = newDistanceSquared;
                        currentClickedConnFace = clickedConnFace;
                    }
                }
            }
            return currentClickedConnFace;
        }
    }

}


text:
using OperasWebsites.Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace OperasWebsites
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);

            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            Database.SetInitializer<OperasDB>(new OperasInitializer());

        }
    }
}