bool isCurrentThreadInterrupted(JNIEnv *env, jobject peer) {
    jclass peerClass = (*env)->GetObjectClass(env, peer);
    jmethodID aMethod = getGetMethodID(env, peerClass, "isCurrentThreadInterruptedCallback", "()Z");
    if (aMethod == NULL) {
        return true;
    }
    if ((*env)->CallBooleanMethod(env, peer, aMethod)) {
        throwInterruptedIOException(env, "thread interrupted");
        return true;
    }
    return (*env)->ExceptionCheck(env);
}
JNIEXPORT jlong JNICALL Java_com_intel_bluetooth_BluetoothStackWIDCOMM_l2ServerAcceptAndOpenServerConnection
(JNIEnv *env, jobject peer, jlong handle) {
    WIDCOMMStackL2CapServer* srv = validL2CapServerHandle(env, handle);
    if (srv == NULL) {
        return 0;
    }
    if (srv->sdpService == NULL) {
        throwIOException(env, cCONNECTION_CLOSED);
        return 0;
    }
    if (!srv->finalizeSDPRecord(env)) {
        return 0;
    }
    #ifdef BWT_SINCE_SDK_6_0_1
    srv->sdpService->CommitRecord();
    #endif

    EnterCriticalSection(&stack->csCommIf);
    if (stack == NULL) {
        throwInterruptedIOException(env, cSTACK_CLOSED);
    }

    WIDCOMMStackL2CapConn* l2c = stack->createL2CapConn();
    if (l2c == NULL) {
        throwBluetoothConnectionException(env, BT_CONNECTION_ERROR_NO_RESOURCES, "No free connections Objects in Pool");
        LeaveCriticalSection(&stack->csCommIf);
        return 0;
    }
    srv->addClient(l2c);
    l2c->receiveMTU = srv->receiveMTU;
    l2c->transmitMTU = srv->transmitMTU;

    BOOL rc = l2c->Listen(&(srv->l2CapIf));
    if (stack != NULL) {
        LeaveCriticalSection(&stack->csCommIf);
    }

    if (!rc) {
        throwBluetoothConnectionException(env, BT_CONNECTION_ERROR_FAILED_NOINFO, "Failed to Listen");
        accept_l2_server_return 0;
    }

    HANDLE hEvents[2];
    hEvents[0] = l2c->hConnectionEvent;
    hEvents[1] = srv->hConnectionEvent;

    debug(("l2s(%i) l2(%i) L2CAP server waits for connection", srv->internalHandle, l2c->internalHandle));
    long incomingConnectionCountWas = incomingL2CAPConnectionCount;
    while ((stack != NULL) && (!srv->isClosing)  && (!l2c->isConnected) && (!l2c->isDisconnected) && (srv->sdpService != NULL)) {
        DWORD  rc = WaitForMultipleObjects(2, hEvents, FALSE, 500);
        if (rc == WAIT_FAILED) {
            throwRuntimeException(env, "WaitForSingleObject");
            accept_l2_server_return 0;
        }
        if ((stack != NULL) && (incomingConnectionCountWas != incomingL2CAPConnectionCount)) {
            debug(("L2CAP server incomingConnectionCount %i", incomingL2CAPConnectionCount));
            incomingConnectionCountWas = incomingL2CAPConnectionCount;
        }
        if (isCurrentThreadInterrupted(env, peer, "accept")) {
            accept_l2_server_return 0;
        }
    }
    if (stack == NULL) {
        throwInterruptedIOException(env, cSTACK_CLOSED);
        return 0;
    }
    if (!l2c->isConnected) {
        if (srv->isClosing || (srv->sdpService == NULL)) {
            throwInterruptedIOException(env, cCONNECTION_CLOSED);
        } else if (l2c->isDisconnected) {
            throwIOException(env, "Connection error");
        } else {
            throwIOException(env, "Failed to connect");
        }
        accept_l2_server_return 0;
    }

    debug(("l2s(%i) l2(%i) L2CAP server connection made", srv->internalHandle, l2c->internalHandle));
    l2c->selectConnectionTransmitMTU(env);
    return l2c->internalHandle;
}