diff --git a/.gitignore b/.gitignore
index f180c06fd5a40a346201cc5d373544a297bd935a..17b4b682cb70c43d59d34f3437b971ab4550913e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -75,3 +75,7 @@ ID
 
 # IDE stuffs
 nbproject
+
+# JNI generated files
+*_wrap.cpp
+*_loader.c
diff --git a/daemon/src/Android.mk b/daemon/src/Android.mk
index 21991c8dc18dca045ea849a305b17ed2133b822f..51476033dc89bafc0368e65d30ee7ea9c8fd3227 100644
--- a/daemon/src/Android.mk
+++ b/daemon/src/Android.mk
@@ -21,6 +21,7 @@ MY_DBUS=libdbus-c++-0.9.0-android
 MY_SPEEX=speex
 MY_OPENSSL=openssl
 MY_LIBYAML=libyaml
+MY_JNI_WRAP=callmanager_wrap.cpp
 
 
 include $(CLEAR_VARS)
@@ -67,6 +68,7 @@ LOCAL_SRC_FILES := \
 		config/yamlnode.cpp \
 		dbus/callmanager.cpp \
     		dbus/configurationmanager.cpp  \
+		dbus/$(MY_JNI_WRAP) \
     		dbus/instance.cpp  \
     		dbus/dbusmanager.cpp \
 		history/historyitem.cpp \
diff --git a/daemon/src/JavaJNI2CJNI_Load.py b/daemon/src/JavaJNI2CJNI_Load.py
new file mode 100755
index 0000000000000000000000000000000000000000..fa10db4ad654d56c9f867d887d1ec7e3272fd582
--- /dev/null
+++ b/daemon/src/JavaJNI2CJNI_Load.py
@@ -0,0 +1,85 @@
+#!/usr/bin/python
+import getopt, sys
+import re
+from string import Template
+
+def type_to_signature(itype):
+	if len(itype) > 2:
+		if itype[-2:] == '[]':
+			return "[%s" % type_to_signature(itype[:-2])
+	if itype == "int":
+		return "I"
+	if itype == "long":
+		return "J"
+	if itype == "void":
+		return "V"
+	if itype == "boolean":
+		return "Z"
+	if itype == "byte":
+		return "B"
+	if itype == "char":
+		return "C"
+	if itype == "short":
+		return "S"
+	if itype == "float":
+		return "F"
+	if itype == "double":
+		return "D"
+	if itype == "String":
+		return "Ljava/lang/String;"
+	if itype == "Object":
+		return "Ljava/lang/Object;"
+	return "Lcom/savoirfairelinux/sflphone/client/%s;" % itype
+
+def parse_java_file(input_stream, package, module):
+	outputs = []
+	package_prefix = "Java_%s_%sJNI" % (package.replace(".", "_"), module)
+	for line in input_stream:
+		definition = re.match(r'.*public final static native ([^\( ]*) ([^\)]*)\(([^)]*)\).*',line)
+		if definition is not None:
+			retour = definition.group(1)
+			name = definition.group(2)
+			args = definition.group(3)
+			args_sigs = []
+			args_frags = args.split(',')
+			for args_frag in args_frags:
+				argf = re.match(r'(\b)?([^ ]+) .*', args_frag.strip())
+				if argf is not None:
+					args_sigs.append(type_to_signature(argf.group(2)))
+			sig = "(%s)%s" % (''.join(args_sigs), type_to_signature(retour))
+			outputs.append("{\"%s\", \"%s\", (void*)& %s_%s}" % (name, sig, package_prefix, name.replace('_', '_1')))
+	return outputs
+
+def render_to_template(defs, template_string):
+	template = Template(template_string)
+	return template.substitute(defs= ",\r\n".join(defs) )
+
+
+if __name__ == "__main__":
+	try:
+		opts, args = getopt.getopt(sys.argv[1:], "i:o:t:m:p:", ["input=", "output=", "template=", "module=", "package="])
+	except getopt.GetoptError, err:
+		# print help information and exit:
+		print str(err) # will print something like "option -a not recognized"
+		sys.exit(2)
+	input_stream = None
+	output_file = None
+	template_string = None
+	package = ""
+	module = ""
+	for o, a in opts:
+		if o in ("-i", "--input"):
+			input_stream = open(a)
+		if o in ("-o", "--output"):
+			output_file = open(a, "w")
+		if o in ("-t", "--template"):
+			template_string = open(a).read()
+		if o in ("-m", "--module"):
+			module = a
+		if o in ("-p", "--package"):
+			package = a
+
+	defs = parse_java_file(input_stream, package, module)
+	output_file.write(render_to_template(defs, template_string))
+	output_file.close()
+	input_stream.close()
diff --git a/daemon/src/dbus/callmanager.i b/daemon/src/dbus/callmanager.i
new file mode 100644
index 0000000000000000000000000000000000000000..cc9f049eb17e44977f1ca2eedb13c58cd9b23f1d
--- /dev/null
+++ b/daemon/src/dbus/callmanager.i
@@ -0,0 +1,83 @@
+
+/* File : callmanager.i */
+%module sflphoneservice
+
+%include "typemaps.i"
+%include "std_string.i" /* std::string typemaps */
+%include "enums.swg"
+%include "arrays_java.i";
+%include "carrays.i";
+
+/* void* shall be handled as byte arrays */
+%typemap(jni) void * "void *"
+%typemap(jtype) void * "byte[]"
+%typemap(jstype) void * "byte[]"
+%typemap(javain) void * "$javainput"
+%typemap(in) void * %{
+	$1 = $input;
+%}
+%typemap(javadirectorin) void * "$jniinput"
+%typemap(out) void * %{
+	$result = $1;
+%}
+%typemap(javaout) void * {
+	return $jnicall;
+}
+
+/* not parsed by SWIG but needed by generated C files */
+%{
+#include <managerimpl.h>
+#include <dbus/callmanager.h>
+
+namespace Manager {
+extern ManagerImpl& instance();
+}
+%}
+
+/* parsed by SWIG to generate all the glue */
+/* %include "../managerimpl.h" */
+/* %include <dbus/callmanager.h> */
+
+/* %nodefaultctor ManagerImpl;
+%nodefaultdtor ManagerImpl; */
+
+class ManagerImpl {
+public:
+    void init(const std::string &config_file);
+    void setPath(const std::string &path);
+    bool outgoingCall(const std::string&, const std::string&, const std::string&, const std::string& = "");
+    void refuseCall(const std::string& id);
+    bool answerCall(const std::string& id);
+    void hangupCall(const std::string& id);
+};
+
+//%rename(Manager_instance) Manager::instance;
+
+namespace Manager {
+
+ManagerImpl& Manager::instance()
+{
+    // Meyers singleton
+    static ManagerImpl instance_;
+    return instance_;
+}
+
+}
+
+//class CallManager {
+//public:
+//    /* Manager::instance().outgoingCall */
+//    void placeCall(const std::string& accountID,
+//                   const std::string& callID,
+//                   const std::string& to);
+//    /* Manager::instance().refuseCall */
+//    void refuse(const std::string& callID);
+//    /* Manager::instance().answerCall */
+//    void accept(const std::string& callID);
+//    /* Manager::instance().hangupCall */
+//    void hangUp(const std::string& callID);
+//};
+
+#ifndef SWIG
+/* some bad declarations */
+#endif
diff --git a/daemon/src/managerimpl.cpp b/daemon/src/managerimpl.cpp
index 2b64814f63ce79ddd4bb414bffaef1380a40ba0d..9f5c88f903065014bd50bf547c6dfa8549bee8dd 100644
--- a/daemon/src/managerimpl.cpp
+++ b/daemon/src/managerimpl.cpp
@@ -91,7 +91,9 @@
 #include <sstream>
 #include <sys/types.h> // mkdir(2)
 #include <sys/stat.h>  // mkdir(2)
+#include <jni.h>
 
+extern JavaVM *gJavaVM;
 static jobject gManagerObject, gDataObject;
 
 ManagerImpl::ManagerImpl() :
@@ -314,6 +316,7 @@ void ManagerImpl::init(const std::string &config_file)
 
     //history_.load(preferences.getHistoryLimit());
     registerAccounts();
+    INFO("init ended");
 }
 
 void ManagerImpl::setPath(const std::string &path) {
diff --git a/daemon/src/sflphoneservice.c.template b/daemon/src/sflphoneservice.c.template
new file mode 100644
index 0000000000000000000000000000000000000000..8755bcf21b3f1f9092f405e04aea220c72d7e8f7
--- /dev/null
+++ b/daemon/src/sflphoneservice.c.template
@@ -0,0 +1,104 @@
+#include "logger.h"
+
+JavaVM *gJavaVM;
+const char *ksflphoneservicePath = "com/savoirfairelinux/sflphone/client/sflphoneserviceJNI";
+//const char *kManagerPath = "com/savoirfairelinux/sflphone/client/ManagerImpl";
+//static jobject gManagerObject, gDataObject;
+
+//void initClassHelper(JNIEnv *env, const char *path, jobject *objptr) {
+//    jclass cls;
+//
+//	INFO("initClassHelper");
+//
+//	cls= env->FindClass(path);
+//	if(!cls) {
+//        ERROR("initClassHelper: failed to get %s class reference", path);
+//        return;
+//    }
+//    jmethodID constr = env->GetMethodID(cls, "<init>", "()V");
+//	INFO("initClassHelper: %s method found", path);
+//
+//    if(!constr) {
+//        ERROR("initClassHelper: failed to get %s constructor", path);
+//        return;
+//    }
+//    jobject obj = env->NewObject(cls, constr);
+//	INFO("initClassHelper: %s constructor found", path);
+//
+//    if(!obj) {
+//        ERROR("initClassHelper: failed to create a %s object", path);
+//        return;
+//    }
+//	/* protect cached object instances from Android GC */
+//    (*objptr) = env->NewGlobalRef(obj);
+//	INFO("initClassHelper: object found %x", objptr);
+//}
+
+void deinitClassHelper(JNIEnv *env, jobject obj) {
+	INFO("deinitClassHelper");
+
+	/* delete cached object instances */
+    env->DeleteGlobalRef(obj);
+	INFO("deinitClassHelper: object %x deleted", obj);
+}
+
+JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
+	JNIEnv *env;
+	jclass clazz;
+	jint r;
+
+    INFO("JNI_OnLoad");
+
+	//Assume it is c++
+	r = vm->GetEnv ((void **) &env, JNI_VERSION_1_6);
+    if (r != JNI_OK) {
+		ERROR("JNI_OnLoad: failed to get the environment using GetEnv()");
+        return -1;
+    }
+	INFO("JNI_Onload: GetEnv %p", env);
+
+	clazz = env->FindClass (ksflphoneservicePath);
+	if (!clazz) {
+        ERROR("JNI_Onload: whoops, %s class not found!", ksflphoneservicePath);
+	}
+	gJavaVM = vm;
+	INFO("JNI_Onload: JavaVM %p", gJavaVM);
+
+	/* put instances of class object we need into cache */
+    //initClassHelper(env, kManagerPath, &gManagerObject);
+
+	JNINativeMethod methods[] = {
+
+	$defs
+
+	};
+
+	r = env->RegisterNatives (clazz, methods, (int) (sizeof(methods) / sizeof(methods[0])));
+	return JNI_VERSION_1_6;
+}
+
+void JNI_OnUnLoad(JavaVM* vm, void* reserved) {
+    JNIEnv* env;
+	jclass clazz;
+
+	INFO("JNI_OnUnLoad");
+
+	/* get env */
+    if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+		ERROR("JNI_OnUnLoad: failed to get the environment using GetEnv()");
+        return;
+    }
+	INFO("JNI_OnUnLoad: GetEnv %p", env);
+
+    /* Get jclass with env->FindClass */
+	clazz = env->FindClass(ksflphoneservicePath);
+	if (!clazz) {
+        ERROR("JNI_OnUnLoad: whoops, %s class not found!", ksflphoneservicePath);
+	}
+
+	/* remove instances of class object we need into cache */
+    //deinitClassHelper(env, gManagerObject);
+
+	env->UnregisterNatives(clazz);
+	INFO("JNI_OnUnLoad: Native functions unregistered");
+}