Create python package for jvpp generation.

Change-Id: I2254f90b2c3e423563bb91bf70877979f1e86a6b
Signed-off-by: Ed Warnicke <eaw@cisco.com>
Signed-off-by: Marek Gradzki <mgradzki@cisco.com>
diff --git a/vpp-api/java/jvpp/gen/jvppgen/__init__.py b/vpp-api/java/jvpp/gen/jvppgen/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vpp-api/java/jvpp/gen/jvppgen/__init__.py
diff --git a/vpp-api/java/jvpp/gen/jvppgen/callback_gen.py b/vpp-api/java/jvpp/gen/jvppgen/callback_gen.py
new file mode 100644
index 0000000..eadf3b5
--- /dev/null
+++ b/vpp-api/java/jvpp/gen/jvppgen/callback_gen.py
@@ -0,0 +1,102 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2016 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import util
+from string import Template
+
+from util import remove_suffix
+
+callback_suffix = "Callback"
+
+callback_template = Template("""
+package $base_package.$callback_package;
+
+/**
+ * <p>Represents callback for vpe.api message.
+ * <br>It was generated by callback_gen.py based on $inputfile preparsed data:
+ * <pre>
+$docs
+ * </pre>
+ */
+public interface $cls_name extends $base_package.$callback_package.$callback_type {
+
+    $callback_method
+
+}
+""")
+
+global_callback_template = Template("""
+package $base_package.$callback_package;
+
+/**
+ * <p>Global aggregated callback interface.
+ * <br>It was generated by callback_gen.py based on $inputfile
+ * <br>(python representation of vpe.api generated by vppapigen).
+ */
+public interface JVppGlobalCallback extends $callbacks {
+}
+""")
+
+
+def generate_callbacks(func_list, base_package, callback_package, dto_package, inputfile):
+    """ Generates callback interfaces """
+    print "Generating Callback interfaces"
+
+    if not os.path.exists(callback_package):
+        raise Exception("%s folder is missing" % callback_package)
+
+    callbacks = []
+    for func in func_list:
+
+        if util.is_ignored(func['name']):
+            continue
+
+        camel_case_name_with_suffix = util.underscore_to_camelcase_upper(func['name'])
+        if not util.is_reply(camel_case_name_with_suffix) and not util.is_notification(func['name']):
+            continue
+
+        if util.is_reply(camel_case_name_with_suffix):
+            camel_case_name = util.remove_reply_suffix(camel_case_name_with_suffix)
+            callback_type = "JVppCallback"
+        else:
+            camel_case_name_with_suffix = util.add_notification_suffix(camel_case_name_with_suffix)
+            camel_case_name = camel_case_name_with_suffix
+            callback_type = "JVppNotificationCallback"
+
+        callbacks.append("{0}.{1}.{2}".format(base_package, callback_package, camel_case_name + callback_suffix))
+        callback_path = os.path.join(callback_package, camel_case_name + callback_suffix + ".java")
+        callback_file = open(callback_path, 'w')
+
+        reply_type = "%s.%s.%s" % (base_package, dto_package, camel_case_name_with_suffix)
+        method = "void on{0}({1} reply);".format(camel_case_name_with_suffix, reply_type)
+        callback_file.write(
+            callback_template.substitute(inputfile=inputfile,
+                                         docs=util.api_message_to_javadoc(func),
+                                         cls_name=camel_case_name + callback_suffix,
+                                         callback_method=method,
+                                         base_package=base_package,
+                                         callback_package=callback_package,
+                                         callback_type=callback_type))
+        callback_file.flush()
+        callback_file.close()
+
+    callback_file = open(os.path.join(callback_package, "JVppGlobalCallback.java"), 'w')
+    callback_file.write(global_callback_template.substitute(inputfile=inputfile,
+                                                            callbacks=", ".join(callbacks),
+                                                            base_package=base_package,
+                                                            callback_package=callback_package))
+    callback_file.flush()
+    callback_file.close()
diff --git a/vpp-api/java/jvpp/gen/jvppgen/dto_gen.py b/vpp-api/java/jvpp/gen/jvppgen/dto_gen.py
new file mode 100644
index 0000000..426cd96
--- /dev/null
+++ b/vpp-api/java/jvpp/gen/jvppgen/dto_gen.py
@@ -0,0 +1,177 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2016 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+from string import Template
+
+import util
+
+dto_template = Template("""
+package $base_package.$dto_package;
+
+/**
+ * <p>This class represents $description.
+ * <br>It was generated by dto_gen.py based on $inputfile preparsed data:
+ * <pre>
+$docs
+ * </pre>
+ */
+public final class $cls_name implements $base_package.$dto_package.$base_type {
+
+$fields
+$methods
+}
+""")
+
+field_template = Template("""    public $type $name;\n""")
+
+send_template = Template("""    @Override
+    public int send(final $base_package.JVpp jvpp) throws org.openvpp.jvpp.VppInvocationException {
+        return jvpp.$method_name($args);
+    }\n""")
+
+
+def generate_dtos(func_list, base_package, dto_package, inputfile):
+    """ Generates dto objects in a dedicated package """
+    print "Generating DTOs"
+
+    if not os.path.exists(dto_package):
+        raise Exception("%s folder is missing" % dto_package)
+
+    for func in func_list:
+        camel_case_dto_name = util.underscore_to_camelcase_upper(func['name'])
+        camel_case_method_name = util.underscore_to_camelcase(func['name'])
+        dto_path = os.path.join(dto_package, camel_case_dto_name + ".java")
+
+        if util.is_ignored(func['name']):
+            continue
+
+        fields = ""
+        for t in zip(func['types'], func['args']):
+            # for retval don't generate dto field in Reply
+            field_name = util.underscore_to_camelcase(t[1])
+            if util.is_reply(camel_case_dto_name) and util.is_retval_field(field_name):
+                continue
+            fields += field_template.substitute(type=util.jni_2_java_type_mapping[t[0]],
+                                                name=field_name)
+        methods = ""
+        base_type = ""
+
+        # Generate request/reply or dump/dumpReply even if structure can be used as notification
+        if not util.is_just_notification(func["name"]):
+            if util.is_reply(camel_case_dto_name):
+                description = "vpe.api reply DTO"
+                request_dto_name = get_request_name(camel_case_dto_name, func['name'])
+                if util.is_details(camel_case_dto_name):
+                    # FIXME assumption that dump calls end with "Dump" suffix. Not enforced in vpe.api
+                    base_type += "JVppReply<%s.%s.%s>" % (base_package, dto_package, request_dto_name + "Dump")
+                    generate_dump_reply_dto(request_dto_name, base_package, dto_package, camel_case_dto_name,
+                                            camel_case_method_name, func)
+                else:
+                    base_type += "JVppReply<%s.%s.%s>" % (base_package, dto_package, request_dto_name)
+            else:
+                args = "" if fields is "" else "this"
+                methods = send_template.substitute(method_name=camel_case_method_name,
+                                                   base_package=base_package,
+                                                   args=args)
+                if util.is_dump(camel_case_dto_name):
+                    base_type += "JVppDump"
+                    description = "vpe.api dump request DTO"
+                else:
+                    base_type += "JVppRequest"
+                    description = "vpe.api request DTO"
+
+            write_dto_file(base_package, base_type, camel_case_dto_name, description, dto_package, dto_path, fields, func,
+                           inputfile, methods)
+
+        # for structures that are also used as notifications, generate dedicated notification DTO
+        if util.is_notification(func["name"]):
+            base_type = "JVppNotification"
+            description = "vpe.api notification DTO"
+            camel_case_dto_name = util.add_notification_suffix(camel_case_dto_name)
+            methods = ""
+            dto_path = os.path.join(dto_package, camel_case_dto_name + ".java")
+            write_dto_file(base_package, base_type, camel_case_dto_name, description, dto_package, dto_path, fields, func,
+                           inputfile, methods)
+
+    flush_dump_reply_dtos(inputfile)
+
+
+def write_dto_file(base_package, base_type, camel_case_dto_name, description, dto_package, dto_path, fields, func,
+                   inputfile, methods):
+    dto_file = open(dto_path, 'w')
+    dto_file.write(dto_template.substitute(inputfile=inputfile,
+                                           description=description,
+                                           docs=util.api_message_to_javadoc(func),
+                                           cls_name=camel_case_dto_name,
+                                           fields=fields,
+                                           methods=methods,
+                                           base_package=base_package,
+                                           base_type=base_type,
+                                           dto_package=dto_package))
+    dto_file.flush()
+    dto_file.close()
+
+
+dump_dto_suffix = "ReplyDump"
+dump_reply_artificial_dtos = {}
+
+# Returns request name or special one from unconventional_naming_rep_req map
+def get_request_name(camel_case_dto_name, func_name):
+    return util.underscore_to_camelcase_upper(
+        util.unconventional_naming_rep_req[func_name]) if func_name in util.unconventional_naming_rep_req \
+        else util.remove_reply_suffix(camel_case_dto_name)
+
+
+def flush_dump_reply_dtos(inputfile):
+    for dump_reply_artificial_dto in dump_reply_artificial_dtos.values():
+        dto_path = os.path.join(dump_reply_artificial_dto['dto_package'],
+                                dump_reply_artificial_dto['cls_name'] + ".java")
+        dto_file = open(dto_path, 'w')
+        dto_file.write(dto_template.substitute(inputfile=inputfile,
+                                               description="vpe.api dump reply wrapper",
+                                               docs=dump_reply_artificial_dto['docs'],
+                                               cls_name=dump_reply_artificial_dto['cls_name'],
+                                               fields=dump_reply_artificial_dto['fields'],
+                                               methods=dump_reply_artificial_dto['methods'],
+                                               base_package=dump_reply_artificial_dto['base_package'],
+                                               base_type=dump_reply_artificial_dto['base_type'],
+                                               dto_package=dump_reply_artificial_dto['dto_package']))
+        dto_file.flush()
+        dto_file.close()
+
+
+def generate_dump_reply_dto(request_dto_name, base_package, dto_package, camel_case_dto_name, camel_case_method_name,
+                            func):
+    base_type = "JVppReplyDump<%s.%s.%s, %s.%s.%s>" % (
+        base_package, dto_package, util.remove_reply_suffix(camel_case_dto_name) + "Dump",
+        base_package, dto_package, camel_case_dto_name)
+    fields = "    public java.util.List<%s> %s = new java.util.ArrayList<>();" % (camel_case_dto_name, camel_case_method_name)
+    cls_name = camel_case_dto_name + dump_dto_suffix
+
+    # In case of already existing artificial reply dump DTO, just update it
+    # Used for sub-dump dtos
+    if request_dto_name in dump_reply_artificial_dtos.keys():
+        dump_reply_artificial_dtos[request_dto_name]['fields'] = \
+            dump_reply_artificial_dtos[request_dto_name]['fields'] + '\n' + fields
+    else:
+        dump_reply_artificial_dtos[request_dto_name] = ({'docs': util.api_message_to_javadoc(func),
+                                                         'cls_name': cls_name,
+                                                         'fields': fields,
+                                                         'methods': "",
+                                                         'base_package': base_package,
+                                                         'base_type': base_type,
+                                                         'dto_package': dto_package,
+                                                         })
diff --git a/vpp-api/java/jvpp/gen/jvppgen/jvpp_c_gen.py b/vpp-api/java/jvpp/gen/jvppgen/jvpp_c_gen.py
new file mode 100644
index 0000000..1796ac1
--- /dev/null
+++ b/vpp-api/java/jvpp/gen/jvppgen/jvpp_c_gen.py
@@ -0,0 +1,525 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2016 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+# l
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import os, util
+from string import Template
+
+def is_manually_generated(f_name):
+    return f_name in {'control_ping_reply'}
+
+
+class_reference_template = Template("""jclass ${ref_name}Class;
+""")
+
+find_class_invocation_template = Template("""
+    ${ref_name}Class = (jclass)(*env)->NewGlobalRef(env, (*env)->FindClass(env, "org/openvpp/jvpp/dto/${class_name}"));
+    if ((*env)->ExceptionCheck(env)) {
+        (*env)->ExceptionDescribe(env);
+        return JNI_ERR;
+    }""")
+
+find_class_template = Template("""
+    ${ref_name}Class = (jclass)(*env)->NewGlobalRef(env, (*env)->FindClass(env, "${class_name}"));
+    if ((*env)->ExceptionCheck(env)) {
+        (*env)->ExceptionDescribe(env);
+        return JNI_ERR;
+    }""")
+
+class_cache_template = Template("""
+$class_references
+static int cache_class_references(JNIEnv* env) {
+    $find_class_invocations
+    return 0;
+}""")
+
+def generate_class_cache(func_list):
+    class_references = []
+    find_class_invocations = []
+    for f in func_list:
+        c_name = f['name']
+        class_name = util.underscore_to_camelcase_upper(c_name)
+        ref_name = util.underscore_to_camelcase(c_name)
+
+        if util.is_ignored(c_name):
+            continue
+
+        if util.is_reply(class_name):
+            class_references.append(class_reference_template.substitute(
+                ref_name=ref_name))
+            find_class_invocations.append(find_class_invocation_template.substitute(
+                ref_name=ref_name,
+                class_name=class_name))
+        elif util.is_notification(c_name):
+            class_references.append(class_reference_template.substitute(
+                ref_name=util.add_notification_suffix(ref_name)))
+            find_class_invocations.append(find_class_invocation_template.substitute(
+                ref_name=util.add_notification_suffix(ref_name),
+                class_name=util.add_notification_suffix(class_name)))
+
+    # add exception class to class cache
+    ref_name = 'callbackException'
+    class_name = 'org/openvpp/jvpp/VppCallbackException'
+    class_references.append(class_reference_template.substitute(
+        ref_name=ref_name))
+    find_class_invocations.append(find_class_template.substitute(
+            ref_name=ref_name,
+            class_name=class_name))
+    return class_cache_template.substitute(
+        class_references="".join(class_references), find_class_invocations="".join(find_class_invocations))
+
+
+# TODO: cache method and field identifiers to achieve better performance
+# https://jira.fd.io/browse/HONEYCOMB-42
+request_class_template = Template("""
+    jclass requestClass = (*env)->FindClass(env, "org/openvpp/jvpp/dto/${java_name_upper}");""")
+
+request_field_identifier_template = Template("""
+    jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, requestClass, "${java_name}", "${jni_signature}");
+    ${jni_type} ${java_name} = (*env)->Get${jni_getter}(env, request, ${java_name}FieldId);
+    """)
+
+u8_struct_setter_template = Template("""
+    mp->${c_name} = ${java_name};""")
+
+u16_struct_setter_template = Template("""
+    mp->${c_name} = clib_host_to_net_u16(${java_name});""")
+
+u32_struct_setter_template = Template("""
+    mp->${c_name} = clib_host_to_net_u32(${java_name});""")
+
+i32_struct_setter_template = Template("""
+    mp->${c_name} = clib_host_to_net_i32(${java_name});!""")
+
+u64_struct_setter_template = Template("""
+    mp->${c_name} = clib_host_to_net_u64(${java_name});""")
+
+u8_array_struct_setter_template = Template("""
+    if (${java_name}) {
+        jsize cnt = (*env)->GetArrayLength (env, ${java_name});
+        size_t max_size = ${field_length};
+        if (max_size != 0 && cnt > max_size) cnt = max_size;
+        (*env)->GetByteArrayRegion(env, ${java_name}, 0, cnt, (jbyte *)mp->${c_name});
+    }
+""")
+
+u16_array_struct_setter_template = Template("""
+    jshort * ${java_name}ArrayElements = (*env)->GetShortArrayElements(env, ${java_name}, NULL);
+    if (${java_name}) {
+        size_t _i;
+        jsize cnt = (*env)->GetArrayLength (env, ${java_name});
+        size_t max_size = ${field_length};
+        if (max_size != 0 && cnt > max_size) cnt = max_size;
+        for (_i = 0; _i < cnt; _i++) {
+            mp->${c_name}[_i] = clib_host_to_net_u16(${java_name}ArrayElements[_i]);
+        }
+    }
+    (*env)->ReleaseShortArrayElements (env, ${java_name}, ${java_name}ArrayElements, 0);
+    """)
+
+u32_array_struct_setter_template = Template("""
+    jint * ${java_name}ArrayElements = (*env)->GetIntArrayElements(env, ${java_name}, NULL);
+    if (${java_name}) {
+        size_t _i;
+        jsize cnt = (*env)->GetArrayLength (env, ${java_name});
+        size_t max_size = ${field_length};
+        if (max_size != 0 && cnt > max_size) cnt = max_size;
+        for (_i = 0; _i < cnt; _i++) {
+            mp->${c_name}[_i] = clib_host_to_net_u32(${java_name}ArrayElements[_i]);
+        }
+    }
+    (*env)->ReleaseIntArrayElements (env, ${java_name}, ${java_name}ArrayElements, 0);
+    """)
+
+u64_array_struct_setter_template = Template("""
+    jlong * ${java_name}ArrayElements = (*env)->GetLongArrayElements(env, ${java_name}, NULL);
+    if (${java_name}) {
+        size_t _i;
+        jsize cnt = (*env)->GetArrayLength (env, ${java_name});
+        size_t max_size = ${field_length};
+        if (max_size != 0 && cnt > max_size) cnt = max_size;
+        for (_i = 0; _i < cnt; _i++) {
+            mp->${c_name}[_i] = clib_host_to_net_u64(${java_name}ArrayElements[_i]);
+        }
+    }
+    (*env)->ReleaseLongArrayElements (env, ${java_name}, ${java_name}ArrayElements, 0);
+    """)
+
+vl_api_ip4_fib_counter_t_array_struct_setter_template = Template("""
+    // vl_api_ip4_fib_counter_t_array_field_setter_template FIXME""")
+
+vl_api_ip6_fib_counter_t_array_struct_setter_template = Template("""
+    // vl_api_ip6_fib_counter_t_array_field_setter_template FIXME""")
+
+struct_setter_templates = {'u8': u8_struct_setter_template,
+                          'u16': u16_struct_setter_template,
+                          'u32': u32_struct_setter_template,
+                          'i32': u32_struct_setter_template,
+                          'u64': u64_struct_setter_template,
+                          'u8[]': u8_array_struct_setter_template,
+                          'u16[]': u16_array_struct_setter_template,
+                          'u32[]': u32_array_struct_setter_template,
+                          'u64[]': u64_array_struct_setter_template,
+                          'vl_api_ip4_fib_counter_t[]': vl_api_ip4_fib_counter_t_array_struct_setter_template,
+                          'vl_api_ip6_fib_counter_t[]': vl_api_ip6_fib_counter_t_array_struct_setter_template
+                  }
+
+jni_impl_template = Template("""
+/**
+ * JNI binding for sending ${c_name} vpe.api message.
+ * Generated based on $inputfile preparsed data:
+$api_data
+ */
+JNIEXPORT jint JNICALL Java_org_openvpp_jvpp_JVppImpl_${java_name}0
+(JNIEnv * env, jclass clazz$args) {
+    vppjni_main_t *jm = &vppjni_main;
+    vl_api_${c_name}_t * mp;
+    u32 my_context_id;
+    int rv;
+    rv = vppjni_sanity_check (jm);
+    if (rv) return rv;
+    my_context_id = vppjni_get_context_id (jm);
+    $request_class
+    $field_identifiers
+    M(${c_name_uppercase}, ${c_name});
+    mp->context = clib_host_to_net_u32 (my_context_id);
+    $struct_setters
+    S;
+    if ((*env)->ExceptionCheck(env)) {
+        return JNI_ERR;
+    }
+    return my_context_id;
+}""")
+
+def generate_jni_impl(func_list, inputfile):
+    jni_impl = []
+    for f in func_list:
+        f_name = f['name']
+        camel_case_function_name = util.underscore_to_camelcase(f_name)
+        if is_manually_generated(f_name) or util.is_reply(camel_case_function_name) \
+                or util.is_ignored(f_name) or util.is_just_notification(f_name):
+            continue
+
+        arguments = ''
+        request_class = ''
+        field_identifiers = ''
+        struct_setters = ''
+        f_name_uppercase = f_name.upper()
+
+        if f['args']:
+            arguments = ', jobject request'
+            camel_case_function_name_upper = util.underscore_to_camelcase_upper(f_name)
+
+            request_class = request_class_template.substitute(java_name_upper=camel_case_function_name_upper)
+
+            # field identifiers
+            for t in zip(f['types'], f['args']):
+                jni_type = t[0]
+                java_field_name = util.underscore_to_camelcase(t[1])
+                jni_signature = util.jni_2_signature_mapping[jni_type]
+                jni_getter = util.jni_field_accessors[jni_type]
+                field_identifiers += request_field_identifier_template.substitute(
+                        jni_type=jni_type,
+                        java_name=java_field_name,
+                        jni_signature=jni_signature,
+                        jni_getter=jni_getter)
+
+            # field setters
+            for t in zip(f['c_types'], f['args'], f['lengths']):
+                c_type = t[0]
+                c_name = t[1]
+                field_length = t[2][0]
+
+                # check if we are processing variable length array:
+                if t[2][1]:
+                    field_length = util.underscore_to_camelcase(t[2][0])
+
+                java_field_name = util.underscore_to_camelcase(c_name)
+
+                struct_setter_template = struct_setter_templates[c_type]
+
+                struct_setters += struct_setter_template.substitute(
+                        c_name=c_name,
+                        java_name=java_field_name,
+                        field_length=field_length)
+
+        jni_impl.append(jni_impl_template.substitute(
+                inputfile=inputfile,
+                api_data=util.api_message_to_javadoc(f),
+                java_name=camel_case_function_name,
+                c_name_uppercase=f_name_uppercase,
+                c_name=f_name,
+                request_class=request_class,
+                field_identifiers=field_identifiers,
+                struct_setters=struct_setters,
+                args=arguments))
+
+    return "\n".join(jni_impl)
+
+
+dto_field_id_template = Template("""
+    jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}");""")
+
+default_dto_field_setter_template = Template("""
+    (*env)->Set${jni_setter}(env, dto, ${java_name}FieldId, mp->${c_name});
+""")
+
+variable_length_array_value_template = Template("""mp->${length_var_name}""")
+variable_length_array_template = Template("""clib_net_to_host_${length_field_type}(${value})""")
+
+u16_dto_field_setter_template = Template("""
+    (*env)->Set${jni_setter}(env, dto, ${java_name}FieldId, clib_net_to_host_u16(mp->${c_name}));
+""")
+
+u32_dto_field_setter_template = Template("""
+    (*env)->Set${jni_setter}(env, dto, ${java_name}FieldId, clib_net_to_host_u32(mp->${c_name}));
+""")
+
+u64_dto_field_setter_template = Template("""
+    (*env)->Set${jni_setter}(env, dto, ${java_name}FieldId, clib_net_to_host_u64(mp->${c_name}));
+""")
+
+u8_array_dto_field_setter_template = Template("""
+    jbyteArray ${java_name} = (*env)->NewByteArray(env, ${field_length});
+    (*env)->SetByteArrayRegion(env, ${java_name}, 0, ${field_length}, (const jbyte*)mp->${c_name});
+    (*env)->SetObjectField(env, dto, ${java_name}FieldId, ${java_name});
+""")
+
+u16_array_dto_field_setter_template = Template("""
+    {
+        jshortArray ${java_name} = (*env)->NewShortArray(env, ${field_length});
+        jshort * ${java_name}ArrayElements = (*env)->GetShortArrayElements(env, ${java_name}, NULL);
+        unsigned int _i;
+        for (_i = 0; _i < ${field_length}; _i++) {
+            ${java_name}ArrayElements[_i] = clib_net_to_host_u16(mp->${c_name}[_i]);
+        }
+
+        (*env)->ReleaseShortArrayElements(env,  ${java_name}, ${java_name}ArrayElements, 0);
+        (*env)->SetObjectField(env, dto, ${java_name}FieldId, ${java_name});
+    }
+""")
+
+u32_array_dto_field_setter_template = Template("""
+    {
+        jintArray ${java_name} = (*env)->NewIntArray(env, ${field_length});
+        jint * ${java_name}ArrayElements = (*env)->GetIntArrayElements(env, ${java_name}, NULL);
+        unsigned int _i;
+        for (_i = 0; _i < ${field_length}; _i++) {
+            ${java_name}ArrayElements[_i] = clib_net_to_host_u32(mp->${c_name}[_i]);
+        }
+
+        (*env)->ReleaseIntArrayElements(env,  ${java_name}, ${java_name}ArrayElements, 0);
+        (*env)->SetObjectField(env, dto, ${java_name}FieldId, ${java_name});
+    }
+""")
+
+# For each u64 array we get its elements. Then we convert values to host byte order.
+# All changes to  jlong* buffer are written to jlongArray (isCopy is set to NULL)
+u64_array_dto_field_setter_template = Template("""
+    {
+        jlongArray ${java_name} = (*env)->NewLongArray(env, ${field_length});
+        jlong * ${java_name}ArrayElements = (*env)->GetLongArrayElements(env, ${java_name}, NULL);
+        unsigned int _i;
+        for (_i = 0; _i < ${field_length}; _i++) {
+            ${java_name}ArrayElements[_i] = clib_net_to_host_u64(mp->${c_name}[_i]);
+        }
+
+        (*env)->ReleaseLongArrayElements(env,  ${java_name}, ${java_name}ArrayElements, 0);
+        (*env)->SetObjectField(env, dto, ${java_name}FieldId, ${java_name});
+    }
+""")
+
+dto_field_setter_templates = {'u8': default_dto_field_setter_template,
+                      'u16': u16_dto_field_setter_template,
+                      'u32': u32_dto_field_setter_template,
+                      'i32': u32_dto_field_setter_template,
+                      'u64': u64_dto_field_setter_template,
+                      'f64': default_dto_field_setter_template, #fixme
+                      'u8[]': u8_array_dto_field_setter_template,
+                      'u16[]': u16_array_dto_field_setter_template,
+                      'u32[]': u32_array_dto_field_setter_template,
+                      'u64[]': u64_array_dto_field_setter_template
+                      }
+
+# code fragment for checking result of the operation before sending request reply
+callback_err_handler_template = Template("""
+    // for negative result don't send callback message but send error callback
+    if (mp->retval<0) {
+        CallOnError("${handler_name}",mp->context,mp->retval);
+        return;
+    }
+    if (mp->retval == VNET_API_ERROR_IN_PROGRESS) {
+        clib_warning("Result in progress");
+        return;
+    }
+""")
+
+msg_handler_template = Template("""
+/**
+ * Handler for ${handler_name} vpe.api message.
+ * Generated based on $inputfile preparsed data:
+$api_data
+ */
+static void vl_api_${handler_name}_t_handler (vl_api_${handler_name}_t * mp)
+{
+    vppjni_main_t * jm = &vppjni_main;
+    JNIEnv *env = jm->jenv;
+    $err_handler
+
+    jmethodID constructor = (*env)->GetMethodID(env, ${class_ref_name}Class, "<init>", "()V");
+    jmethodID callbackMethod = (*env)->GetMethodID(env, jm->callbackClass, "on${dto_name}", "(Lorg/openvpp/jvpp/dto/${dto_name};)V");
+
+    jobject dto = (*env)->NewObject(env, ${class_ref_name}Class, constructor);
+    $dto_setters
+    (*env)->CallVoidMethod(env, jm->callback, callbackMethod, dto);
+}""")
+
+def generate_msg_handlers(func_list, inputfile):
+    handlers = []
+    for f in func_list:
+        handler_name = f['name']
+        dto_name = util.underscore_to_camelcase_upper(handler_name)
+        ref_name = util.underscore_to_camelcase(handler_name)
+
+        if is_manually_generated(handler_name) or util.is_ignored(handler_name):
+            continue
+
+        if not util.is_reply(dto_name) and not util.is_notification(handler_name):
+            continue
+
+        if util.is_notification(handler_name):
+            dto_name = util.add_notification_suffix(dto_name)
+            ref_name = util.add_notification_suffix(ref_name)
+
+        dto_setters = ''
+        err_handler = ''
+        # dto setters
+        for t in zip(f['c_types'], f['types'], f['args'], f['lengths']):
+            c_type = t[0]
+            jni_type = t[1]
+            c_name = t[2]
+            field_length = t[3][0]
+
+            if jni_type.endswith('Array') and field_length == '0':
+                raise Exception('Variable array \'%s\' defined in message \'%s\' '
+                                'should have defined length (e.g. \'%s[%s_length]\''
+                                % (c_name, handler_name, c_name, c_name))
+
+            # check if we are processing variable length array
+            if t[3][1]:
+                length_var_name = t[3][0]
+                length_field_type = f['c_types'][f['args'].index(length_var_name)]
+                field_length = variable_length_array_value_template.substitute(length_var_name=length_var_name)
+                if length_field_type != 'u8':  # we need net to host conversion:
+                    field_length = variable_length_array_template.substitute(
+                        length_field_type=length_field_type, value=field_length)
+
+            # for retval don't generate setters and generate retval check
+            if util.is_retval_field(c_name):
+                err_handler = callback_err_handler_template.substitute(
+                    handler_name=handler_name
+                )
+                continue
+
+            java_field_name = util.underscore_to_camelcase(c_name)
+            jni_signature = util.jni_2_signature_mapping[jni_type]
+            jni_setter = util.jni_field_accessors[jni_type]
+
+            dto_setters += dto_field_id_template.substitute(
+                    java_name=java_field_name,
+                    class_ref_name=ref_name,
+                    jni_signature=jni_signature)
+
+            dto_setter_template = dto_field_setter_templates[c_type]
+
+            dto_setters += dto_setter_template.substitute(
+                    java_name=java_field_name,
+                    jni_signature=jni_signature,
+                    c_name=c_name,
+                    jni_setter=jni_setter,
+                    field_length=field_length)
+
+        handlers.append(msg_handler_template.substitute(
+            inputfile=inputfile,
+            api_data=util.api_message_to_javadoc(f),
+            handler_name=handler_name,
+            dto_name=dto_name,
+            class_ref_name=ref_name,
+            dto_setters=dto_setters,
+            err_handler=err_handler))
+
+    return "\n".join(handlers)
+
+
+handler_registration_template = Template("""_(${upercase_name}, ${name}) \\
+""")
+
+
+def generate_handler_registration(func_list):
+    handler_registration = ["#define foreach_vpe_api_msg \\\n"]
+    for f in func_list:
+        name = f['name']
+        camelcase_name = util.underscore_to_camelcase(f['name'])
+
+        if (not util.is_reply(camelcase_name) and not util.is_notification(name)) or util.is_ignored(name):
+            continue
+
+        handler_registration.append(handler_registration_template.substitute(
+            name=name,
+            upercase_name=name.upper()))
+
+    return "".join(handler_registration)
+
+
+jvpp_c_template = Template("""/**
+ * This file contains JNI bindings for jvpp Java API.
+ * It was generated by jvpp_c_gen.py based on $inputfile
+ * (python representation of vpe.api generated by vppapigen).
+ */
+
+void CallOnError(const char* call, int context, int retval);
+
+// JAVA class reference cache
+$class_cache
+
+// JNI bindings
+$jni_implementations
+
+// Message handlers
+$msg_handlers
+
+// Registration of message handlers in vlib
+$handler_registration
+""")
+
+def generate_jvpp(func_list, inputfile):
+    """ Generates jvpp C file """
+    print "Generating jvpp C"
+
+    class_cache = generate_class_cache(func_list)
+    jni_impl = generate_jni_impl(func_list, inputfile)
+    msg_handlers = generate_msg_handlers(func_list, inputfile)
+    handler_registration = generate_handler_registration(func_list)
+
+    jvpp_c_file = open("jvpp_gen.h", 'w')
+    jvpp_c_file.write(jvpp_c_template.substitute(
+            inputfile=inputfile,
+            class_cache=class_cache,
+            jni_implementations=jni_impl,
+            msg_handlers=msg_handlers,
+            handler_registration=handler_registration))
+    jvpp_c_file.flush()
+    jvpp_c_file.close()
+
diff --git a/vpp-api/java/jvpp/gen/jvppgen/jvpp_callback_facade_gen.py b/vpp-api/java/jvpp/gen/jvppgen/jvpp_callback_facade_gen.py
new file mode 100644
index 0000000..7df1748
--- /dev/null
+++ b/vpp-api/java/jvpp/gen/jvppgen/jvpp_callback_facade_gen.py
@@ -0,0 +1,297 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2016 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os, util
+from string import Template
+
+import callback_gen
+import dto_gen
+
+jvpp_ifc_template = Template("""
+package $base_package.$callback_facade_package;
+
+/**
+ * <p>Callback Java API representation of vpe.api.
+ * <br>It was generated by jvpp_callback_facade_gen.py based on $inputfile
+ * <br>(python representation of vpe.api generated by vppapigen).
+ */
+public interface CallbackJVpp extends $base_package.$notification_package.NotificationRegistryProvider, java.lang.AutoCloseable {
+
+    @Override
+    void close();
+
+    // TODO add send
+
+$methods
+}
+""")
+
+jvpp_impl_template = Template("""
+package $base_package.$callback_facade_package;
+
+/**
+ * <p>Default implementation of CallbackJVpp interface.
+ * <br>It was generated by jvpp_callback_facade_gen.py based on $inputfile
+ * <br>(python representation of vpe.api generated by vppapigen).
+ */
+public final class CallbackJVppFacade extends $base_package.$notification_package.NotificationRegistryProviderContext implements $base_package.$callback_facade_package.CallbackJVpp {
+
+    private final $base_package.JVpp jvpp;
+    private final java.util.Map<Integer, $base_package.$callback_package.JVppCallback> callbacks;
+
+    /**
+     * <p>Create CallbackJVppFacade object for provided JVpp instance.
+     * Constructor internally creates CallbackJVppFacadeCallback class for processing callbacks
+     * and then connects to provided JVpp instance
+     *
+     * @param jvpp provided $base_package.JVpp instance
+     *
+     * @throws java.io.IOException in case instance cannot connect to JVPP
+     */
+    public CallbackJVppFacade(final $base_package.JVpp jvpp) throws java.io.IOException {
+        this.jvpp = java.util.Objects.requireNonNull(jvpp,"jvpp is null");
+        this.callbacks = new java.util.HashMap<>();
+        this.jvpp.connect(new CallbackJVppFacadeCallback(this.callbacks, getNotificationCallback()));
+    }
+
+    @Override
+    public void close() {
+    }
+
+    // TODO add send()
+
+$methods
+}
+""")
+
+method_template = Template(
+    """    void $name($base_package.$dto_package.$request request, $base_package.$callback_package.$callback callback) throws org.openvpp.jvpp.VppInvocationException;""")
+
+method_impl_template = Template("""    public final void $name($base_package.$dto_package.$request request, $base_package.$callback_package.$callback callback) throws org.openvpp.jvpp.VppInvocationException {
+        synchronized (callbacks) {
+            callbacks.put(jvpp.$name(request), callback);
+        }
+    }
+""")
+
+no_arg_method_template = Template("""    void $name($base_package.$callback_package.$callback callback) throws org.openvpp.jvpp.VppInvocationException;""")
+no_arg_method_impl_template = Template("""    public final void $name($base_package.$callback_package.$callback callback) throws org.openvpp.jvpp.VppInvocationException {
+        synchronized (callbacks) {
+            callbacks.put(jvpp.$name(), callback);
+        }
+    }
+""")
+
+
+def generate_jvpp(func_list, base_package, dto_package, callback_package, notification_package, callback_facade_package, inputfile):
+    """ Generates callback facade """
+    print "Generating JVpp callback facade"
+
+    if os.path.exists(callback_facade_package):
+        util.remove_folder(callback_facade_package)
+
+    os.mkdir(callback_facade_package)
+
+    methods = []
+    methods_impl = []
+    for func in func_list:
+
+        if util.is_notification(func['name']) or util.is_ignored(func['name']):
+            # TODO handle notifications
+            continue
+
+        camel_case_name = util.underscore_to_camelcase(func['name'])
+        camel_case_name_upper = util.underscore_to_camelcase_upper(func['name'])
+        if util.is_reply(camel_case_name):
+            continue
+
+        # Strip suffix for dump calls
+        callback_type = get_request_name(camel_case_name_upper, func['name']) + callback_gen.callback_suffix
+
+        if len(func['args']) == 0:
+            methods.append(no_arg_method_template.substitute(name=camel_case_name,
+                                                             base_package=base_package,
+                                                             dto_package=dto_package,
+                                                             callback_package=callback_package,
+                                                             callback=callback_type))
+            methods_impl.append(no_arg_method_impl_template.substitute(name=camel_case_name,
+                                                                       base_package=base_package,
+                                                                       dto_package=dto_package,
+                                                                       callback_package=callback_package,
+                                                                       callback=callback_type))
+        else:
+            methods.append(method_template.substitute(name=camel_case_name,
+                                                      request=camel_case_name_upper,
+                                                      base_package=base_package,
+                                                      dto_package=dto_package,
+                                                      callback_package=callback_package,
+                                                      callback=callback_type))
+            methods_impl.append(method_impl_template.substitute(name=camel_case_name,
+                                                                request=camel_case_name_upper,
+                                                                base_package=base_package,
+                                                                dto_package=dto_package,
+                                                                callback_package=callback_package,
+                                                                callback=callback_type))
+
+    join = os.path.join(callback_facade_package, "CallbackJVpp.java")
+    jvpp_file = open(join, 'w')
+    jvpp_file.write(
+        jvpp_ifc_template.substitute(inputfile=inputfile,
+                                     methods="\n".join(methods),
+                                     base_package=base_package,
+                                     dto_package=dto_package,
+                                     notification_package=notification_package,
+                                     callback_facade_package=callback_facade_package))
+    jvpp_file.flush()
+    jvpp_file.close()
+
+    jvpp_file = open(os.path.join(callback_facade_package, "CallbackJVppFacade.java"), 'w')
+    jvpp_file.write(jvpp_impl_template.substitute(inputfile=inputfile,
+                                                  methods="\n".join(methods_impl),
+                                                  base_package=base_package,
+                                                  dto_package=dto_package,
+                                                  notification_package=notification_package,
+                                                  callback_package=callback_package,
+                                                  callback_facade_package=callback_facade_package))
+    jvpp_file.flush()
+    jvpp_file.close()
+
+    generate_callback(func_list, base_package, dto_package, callback_package, notification_package, callback_facade_package, inputfile)
+
+
+jvpp_facade_callback_template = Template("""
+package $base_package.$callback_facade_package;
+
+/**
+ * <p>Implementation of JVppGlobalCallback interface for Java Callback API.
+ * <br>It was generated by jvpp_callback_facade_gen.py based on $inputfile
+ * <br>(python representation of vpe.api generated by vppapigen).
+ */
+public final class CallbackJVppFacadeCallback implements $base_package.$callback_package.JVppGlobalCallback {
+
+    private final java.util.Map<Integer, $base_package.$callback_package.JVppCallback> requests;
+    private final $base_package.$notification_package.GlobalNotificationCallback notificationCallback;
+    private static final java.util.logging.Logger LOG = java.util.logging.Logger.getLogger(CallbackJVppFacadeCallback.class.getName());
+
+    public CallbackJVppFacadeCallback(final java.util.Map<Integer, $base_package.$callback_package.JVppCallback> requestMap,
+                                      final $base_package.$notification_package.GlobalNotificationCallback notificationCallback) {
+        this.requests = requestMap;
+        this.notificationCallback = notificationCallback;
+    }
+
+    @Override
+    public void onError(org.openvpp.jvpp.VppCallbackException reply) {
+
+        $base_package.$callback_package.JVppCallback failedCall;
+        synchronized(requests) {
+            failedCall = requests.remove(reply.getCtxId());
+        }
+
+        if(failedCall != null) {
+            try {
+                failedCall.onError(reply);
+            } catch(RuntimeException ex) {
+                ex.addSuppressed(reply);
+                LOG.log(java.util.logging.Level.WARNING, String.format("Callback: %s failed while handling exception: %s", failedCall, reply), ex);
+            }
+        }
+    }
+
+$methods
+}
+""")
+
+jvpp_facade_callback_method_template = Template("""
+    @Override
+    @SuppressWarnings("unchecked")
+    public void on$callback_dto($base_package.$dto_package.$callback_dto reply) {
+
+        $base_package.$callback_package.$callback callback;
+        synchronized(requests) {
+            callback = ($base_package.$callback_package.$callback) requests.remove(reply.context);
+        }
+
+        if(callback != null) {
+            callback.on$callback_dto(reply);
+        }
+    }
+""")
+
+jvpp_facade_callback_notification_method_template = Template("""
+    @Override
+    @SuppressWarnings("unchecked")
+    public void on$callback_dto($base_package.$dto_package.$callback_dto notification) {
+        notificationCallback.on$callback_dto(notification);
+    }
+""")
+
+
+def generate_callback(func_list, base_package, dto_package, callback_package, notification_package, callback_facade_package, inputfile):
+    callbacks = []
+    for func in func_list:
+
+        if util.is_ignored(func['name']):
+            continue
+
+        camel_case_name_with_suffix = util.underscore_to_camelcase_upper(func['name'])
+
+        if util.is_reply(camel_case_name_with_suffix):
+            callbacks.append(jvpp_facade_callback_method_template.substitute(base_package=base_package,
+                                                                             dto_package=dto_package,
+                                                                             callback_package=callback_package,
+                                                                             callback=util.remove_reply_suffix(camel_case_name_with_suffix) + callback_gen.callback_suffix,
+                                                                             callback_dto=camel_case_name_with_suffix))
+
+        if util.is_notification(func["name"]):
+            with_notification_suffix = util.add_notification_suffix(camel_case_name_with_suffix)
+            callbacks.append(jvpp_facade_callback_notification_method_template.substitute(base_package=base_package,
+                                                                             dto_package=dto_package,
+                                                                             callback_package=callback_package,
+                                                                             callback=with_notification_suffix + callback_gen.callback_suffix,
+                                                                             callback_dto=with_notification_suffix))
+
+    jvpp_file = open(os.path.join(callback_facade_package, "CallbackJVppFacadeCallback.java"), 'w')
+    jvpp_file.write(jvpp_facade_callback_template.substitute(inputfile=inputfile,
+                                                             base_package=base_package,
+                                                             dto_package=dto_package,
+                                                             notification_package=notification_package,
+                                                             callback_package=callback_package,
+                                                             methods="".join(callbacks),
+                                                             callback_facade_package=callback_facade_package))
+    jvpp_file.flush()
+    jvpp_file.close()
+
+
+# Returns request name or special one from unconventional_naming_rep_req map
+def get_request_name(camel_case_dto_name, func_name):
+    if func_name in reverse_dict(util.unconventional_naming_rep_req):
+        request_name = util.underscore_to_camelcase_upper(reverse_dict(util.unconventional_naming_rep_req)[func_name])
+    else:
+        request_name = camel_case_dto_name
+    return remove_suffix(request_name)
+
+
+def reverse_dict(map):
+    return dict((v, k) for k, v in map.iteritems())
+
+
+def remove_suffix(name):
+    if util.is_reply(name):
+        return util.remove_reply_suffix(name)
+    else:
+        if util.is_dump(name):
+            return util.remove_suffix(name, util.dump_suffix)
+        else:
+            return name
diff --git a/vpp-api/java/jvpp/gen/jvppgen/jvpp_future_facade_gen.py b/vpp-api/java/jvpp/gen/jvppgen/jvpp_future_facade_gen.py
new file mode 100644
index 0000000..e1ca4d0
--- /dev/null
+++ b/vpp-api/java/jvpp/gen/jvppgen/jvpp_future_facade_gen.py
@@ -0,0 +1,315 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2016 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+from string import Template
+
+import dto_gen
+import util
+
+jvpp_facade_callback_template = Template("""
+package $base_package.$future_package;
+
+/**
+ * <p>Async facade callback setting values to future objects
+ * <br>It was generated by jvpp_future_facade_gen.py based on $inputfile
+ * <br>(python representation of vpe.api generated by vppapigen).
+ */
+public final class FutureJVppFacadeCallback implements $base_package.$callback_package.JVppGlobalCallback {
+
+    private final java.util.Map<java.lang.Integer, java.util.concurrent.CompletableFuture<? extends $base_package.$dto_package.JVppReply<?>>> requests;
+    private final $base_package.$notification_package.GlobalNotificationCallback notificationCallback;
+
+    public FutureJVppFacadeCallback(final java.util.Map<java.lang.Integer, java.util.concurrent.CompletableFuture<? extends $base_package.$dto_package.JVppReply<?>>> requestMap,
+                                    final $base_package.$notification_package.GlobalNotificationCallback notificationCallback) {
+        this.requests = requestMap;
+        this.notificationCallback = notificationCallback;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public void onError(org.openvpp.jvpp.VppCallbackException reply) {
+        final java.util.concurrent.CompletableFuture<$base_package.$dto_package.JVppReply<?>> completableFuture;
+
+        synchronized(requests) {
+            completableFuture = (java.util.concurrent.CompletableFuture<$base_package.$dto_package.JVppReply<?>>) requests.get(reply.getCtxId());
+        }
+
+        if(completableFuture != null) {
+            completableFuture.completeExceptionally(reply);
+
+            synchronized(requests) {
+                requests.remove(reply.getCtxId());
+            }
+        }
+    }
+
+$methods
+}
+""")
+
+jvpp_facade_callback_method_template = Template("""
+    @Override
+    @SuppressWarnings("unchecked")
+    public void on$callback_dto($base_package.$dto_package.$callback_dto reply) {
+        final java.util.concurrent.CompletableFuture<$base_package.$dto_package.JVppReply<?>> completableFuture;
+
+        synchronized(requests) {
+            completableFuture = (java.util.concurrent.CompletableFuture<$base_package.$dto_package.JVppReply<?>>) requests.get(reply.context);
+        }
+
+        if(completableFuture != null) {
+            completableFuture.complete(reply);
+
+            synchronized(requests) {
+                requests.remove(reply.context);
+            }
+        }
+    }
+""")
+
+jvpp_facade_callback_notification_method_template = Template("""
+    @Override
+    public void on$callback_dto($base_package.$dto_package.$callback_dto notification) {
+        notificationCallback.on$callback_dto(notification);
+    }
+""")
+
+# TODO reuse common parts with generic method callback
+jvpp_facade_control_ping_method_template = Template("""
+    @Override
+    @SuppressWarnings("unchecked")
+    public void on$callback_dto($base_package.$dto_package.$callback_dto reply) {
+        final java.util.concurrent.CompletableFuture<$base_package.$dto_package.JVppReply<?>> completableFuture;
+
+        synchronized(requests) {
+            completableFuture = (java.util.concurrent.CompletableFuture<$base_package.$dto_package.JVppReply<?>>) requests.get(reply.context);
+        }
+
+        if(completableFuture != null) {
+            // Finish dump call
+            if (completableFuture instanceof $base_package.$future_package.FutureJVppFacade.CompletableDumpFuture) {
+                completableFuture.complete((($base_package.$future_package.FutureJVppFacade.CompletableDumpFuture) completableFuture).getReplyDump());
+                // Remove future mapped to dump call context id
+                synchronized(requests) {
+                    requests.remove((($base_package.$future_package.FutureJVppFacade.CompletableDumpFuture) completableFuture).getContextId());
+                }
+            } else {
+                completableFuture.complete(reply);
+            }
+
+            synchronized(requests) {
+                requests.remove(reply.context);
+            }
+        }
+    }
+""")
+
+jvpp_facade_details_callback_method_template = Template("""
+    @Override
+    @SuppressWarnings("unchecked")
+    public void on$callback_dto($base_package.$dto_package.$callback_dto reply) {
+        final FutureJVppFacade.CompletableDumpFuture<$base_package.$dto_package.$callback_dto_reply_dump> completableFuture;
+
+        synchronized(requests) {
+            completableFuture = ($base_package.$future_package.FutureJVppFacade.CompletableDumpFuture<$base_package.$dto_package.$callback_dto_reply_dump>) requests.get(reply.context);
+        }
+
+        if(completableFuture != null) {
+            $base_package.$dto_package.$callback_dto_reply_dump replyDump = completableFuture.getReplyDump();
+            if(replyDump == null) {
+                replyDump = new $base_package.$dto_package.$callback_dto_reply_dump();
+                completableFuture.setReplyDump(replyDump);
+            }
+
+            replyDump.$callback_dto_field.add(reply);
+        }
+    }
+""")
+
+
+def generate_jvpp(func_list, base_package, dto_package, callback_package, notification_package, future_facade_package, inputfile):
+    """ Generates JVpp interface and JNI implementation """
+    print "Generating JVpp future facade"
+
+    if not os.path.exists(future_facade_package):
+        raise Exception("%s folder is missing" % future_facade_package)
+
+    methods = []
+    methods_impl = []
+    callbacks = []
+    for func in func_list:
+
+        if util.is_ignored(func['name']):
+            continue
+
+        camel_case_name_with_suffix = util.underscore_to_camelcase_upper(func['name'])
+        if not util.is_reply(camel_case_name_with_suffix) and not util.is_notification(func['name']):
+            continue
+
+        camel_case_method_name = util.underscore_to_camelcase(func['name'])
+
+        if not util.is_notification(func["name"]):
+            camel_case_request_method_name = util.remove_reply_suffix(util.underscore_to_camelcase(func['name']))
+            if util.is_details(camel_case_name_with_suffix):
+                camel_case_reply_name = get_standard_dump_reply_name(util.underscore_to_camelcase_upper(func['name']),
+                                                                     func['name'])
+                callbacks.append(jvpp_facade_details_callback_method_template.substitute(base_package=base_package,
+                                                                                         dto_package=dto_package,
+                                                                                         callback_dto=camel_case_name_with_suffix,
+                                                                                         callback_dto_field=camel_case_method_name,
+                                                                                         callback_dto_reply_dump=camel_case_reply_name + dto_gen.dump_dto_suffix,
+                                                                                         future_package=future_facade_package))
+
+                methods.append(future_jvpp_method_template.substitute(base_package=base_package,
+                                                                      dto_package=dto_package,
+                                                                      method_name=camel_case_request_method_name +
+                                                                                  util.underscore_to_camelcase_upper(util.dump_suffix),
+                                                                      reply_name=camel_case_reply_name + dto_gen.dump_dto_suffix,
+                                                                      request_name=util.remove_reply_suffix(camel_case_reply_name) +
+                                                                                   util.underscore_to_camelcase_upper(util.dump_suffix)))
+                methods_impl.append(future_jvpp_method_impl_template.substitute(base_package=base_package,
+                                                                                dto_package=dto_package,
+                                                                                method_name=camel_case_request_method_name +
+                                                                                            util.underscore_to_camelcase_upper(util.dump_suffix),
+                                                                                reply_name=camel_case_reply_name + dto_gen.dump_dto_suffix,
+                                                                                request_name=util.remove_reply_suffix(camel_case_reply_name) +
+                                                                                             util.underscore_to_camelcase_upper(util.dump_suffix)))
+            else:
+                request_name = util.underscore_to_camelcase_upper(util.unconventional_naming_rep_req[func['name']]) \
+                    if func['name'] in util.unconventional_naming_rep_req else util.remove_reply_suffix(camel_case_name_with_suffix)
+
+                methods.append(future_jvpp_method_template.substitute(base_package=base_package,
+                                                                      dto_package=dto_package,
+                                                                      method_name=camel_case_request_method_name,
+                                                                      reply_name=camel_case_name_with_suffix,
+                                                                      request_name=request_name))
+                methods_impl.append(future_jvpp_method_impl_template.substitute(base_package=base_package,
+                                                                                dto_package=dto_package,
+                                                                                method_name=camel_case_request_method_name,
+                                                                                reply_name=camel_case_name_with_suffix,
+                                                                                request_name=request_name))
+
+                # Callback handler is a bit special and a different template has to be used
+                if util.is_control_ping(camel_case_name_with_suffix):
+                    callbacks.append(jvpp_facade_control_ping_method_template.substitute(base_package=base_package,
+                                                                                         dto_package=dto_package,
+                                                                                         callback_dto=camel_case_name_with_suffix,
+                                                                                         future_package=future_facade_package))
+                else:
+                    callbacks.append(jvpp_facade_callback_method_template.substitute(base_package=base_package,
+                                                                                     dto_package=dto_package,
+                                                                                     callback_dto=camel_case_name_with_suffix))
+
+        if util.is_notification(func["name"]):
+            callbacks.append(jvpp_facade_callback_notification_method_template.substitute(base_package=base_package,
+                                                                                          dto_package=dto_package,
+                                                                                          callback_dto=util.add_notification_suffix(camel_case_name_with_suffix)))
+
+    jvpp_file = open(os.path.join(future_facade_package, "FutureJVppFacadeCallback.java"), 'w')
+    jvpp_file.write(jvpp_facade_callback_template.substitute(inputfile=inputfile,
+                                                             base_package=base_package,
+                                                             dto_package=dto_package,
+                                                             notification_package=notification_package,
+                                                             callback_package=callback_package,
+                                                             methods="".join(callbacks),
+                                                             future_package=future_facade_package))
+    jvpp_file.flush()
+    jvpp_file.close()
+
+    jvpp_file = open(os.path.join(future_facade_package, "FutureJVpp.java"), 'w')
+    jvpp_file.write(future_jvpp_template.substitute(inputfile=inputfile,
+                                                    base_package=base_package,
+                                                    methods="".join(methods),
+                                                    future_package=future_facade_package))
+    jvpp_file.flush()
+    jvpp_file.close()
+
+    jvpp_file = open(os.path.join(future_facade_package, "FutureJVppFacade.java"), 'w')
+    jvpp_file.write(future_jvpp_facade_template.substitute(inputfile=inputfile,
+                                                           base_package=base_package,
+                                                           dto_package=dto_package,
+                                                           methods="".join(methods_impl),
+                                                           future_package=future_facade_package))
+    jvpp_file.flush()
+    jvpp_file.close()
+
+
+future_jvpp_template = Template('''
+package $base_package.$future_package;
+
+/**
+ * <p>Async facade extension adding specific methods for each request invocation
+ * <br>It was generated by jvpp_future_facade_gen.py based on $inputfile
+ * <br>(python representation of vpe.api generated by vppapigen).
+ */
+public interface FutureJVpp extends FutureJVppInvoker {
+$methods
+}
+''')
+
+future_jvpp_method_template = Template('''
+    java.util.concurrent.CompletionStage<$base_package.$dto_package.$reply_name> $method_name($base_package.$dto_package.$request_name request);
+''')
+
+
+future_jvpp_facade_template = Template('''
+package $base_package.$future_package;
+
+/**
+ * <p>Implementation of FutureJVpp based on FutureJVppInvokerFacade
+ * <br>It was generated by jvpp_future_facade_gen.py based on $inputfile
+ * <br>(python representation of vpe.api generated by vppapigen).
+ */
+public class FutureJVppFacade extends FutureJVppInvokerFacade implements FutureJVpp {
+
+    /**
+     * <p>Create FutureJVppFacade object for provided JVpp instance.
+     * Constructor internally creates FutureJVppFacadeCallback class for processing callbacks
+     * and then connects to provided JVpp instance
+     *
+     * @param jvpp provided $base_package.JVpp instance
+     *
+     * @throws java.io.IOException in case instance cannot connect to JVPP
+     */
+    public FutureJVppFacade(final $base_package.JVpp jvpp) throws java.io.IOException {
+        super(jvpp, new java.util.HashMap<>());
+        jvpp.connect(new FutureJVppFacadeCallback(getRequests(), getNotificationCallback()));
+    }
+$methods
+}
+''')
+
+future_jvpp_method_impl_template = Template('''
+    @Override
+    public java.util.concurrent.CompletionStage<$base_package.$dto_package.$reply_name> $method_name($base_package.$dto_package.$request_name request) {
+        return send(request);
+    }
+''')
+
+# Returns request name or special one from unconventional_naming_rep_req map
+def get_standard_dump_reply_name(camel_case_dto_name, func_name):
+    # FIXME this is a hotfix for sub-details callbacks
+    # FIXME also for L2FibTableEntry
+    # It's all because unclear mapping between
+    #  request -> reply,
+    #  dump -> reply, details,
+    #  notification_start -> reply, notifications
+
+    # vpe.api needs to be "standardized" so we can parse the information and create maps before generating java code
+    suffix = func_name.split("_")[-1]
+    return util.underscore_to_camelcase_upper(
+        util.unconventional_naming_rep_req[func_name]) + util.underscore_to_camelcase_upper(suffix) if func_name in util.unconventional_naming_rep_req \
+        else camel_case_dto_name
diff --git a/vpp-api/java/jvpp/gen/jvppgen/jvpp_impl_gen.py b/vpp-api/java/jvpp/gen/jvppgen/jvpp_impl_gen.py
new file mode 100644
index 0000000..93ffd0f
--- /dev/null
+++ b/vpp-api/java/jvpp/gen/jvppgen/jvpp_impl_gen.py
@@ -0,0 +1,173 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2016 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os, util
+from string import Template
+
+jvpp_ifc_template = Template("""
+package $base_package;
+
+
+/**
+ * <p>Java representation of vpe.api.
+ * <br>It was generated by jvpp_impl_gen.py based on $inputfile
+ * <br>(python representation of vpe.api generated by vppapigen).
+ */
+public interface JVpp extends java.lang.AutoCloseable {
+
+    /**
+     * Generic connect with $base_package.callback.JVppCallback callback handler
+     * providing connecting to VPP
+     *
+     * @param callback JVppCallback instance providing callback handling
+     *
+     * @throws java.io.IOException if connection cannot be initiated
+     */
+    void connect($base_package.callback.JVppCallback callback) throws java.io.IOException;
+
+    /**
+     * Generic dispatch method for sending requests to VPP
+     *
+     * @throws org.openvpp.jvpp.VppInvocationException if send request had failed
+     */
+    int send($base_package.$dto_package.JVppRequest request) throws org.openvpp.jvpp.VppInvocationException;
+
+    @Override
+    void close();
+
+$methods
+}
+""")
+
+jvpp_impl_template = Template("""
+package $base_package;
+
+/**
+ * <p>Default implementation of JVpp interface.
+ * <br>It was generated by jvpp_impl_gen.py based on $inputfile
+ * <br>(python representation of vpe.api generated by vppapigen).
+ */
+public final class JVppImpl implements $base_package.JVpp {
+
+    private final $base_package.VppConnection connection;
+
+    public JVppImpl(final $base_package.VppConnection connection) {
+        this.connection = java.util.Objects.requireNonNull(connection,"Connection is null");
+    }
+
+    @Override
+    public void connect($base_package.callback.JVppCallback callback) throws java.io.IOException {
+        connection.connect(callback);
+    }
+
+    @Override
+    public void close() {
+        connection.close();
+    }
+
+    @Override
+    public int send($base_package.$dto_package.JVppRequest request)  throws org.openvpp.jvpp.VppInvocationException {
+        return request.send(this);
+    }
+
+$methods
+}
+""")
+
+method_template = Template("""    int $name($base_package.$dto_package.$request request) throws org.openvpp.jvpp.VppInvocationException;""")
+method_native_template = Template(
+    """    private static native int ${name}0($base_package.$dto_package.$request request);""")
+method_impl_template = Template("""    public final int $name($base_package.$dto_package.$request request) throws org.openvpp.jvpp.VppInvocationException {
+        java.util.Objects.requireNonNull(request,"Null request object");
+        connection.checkActive();
+        int result=${name}0(request);
+        if(result<0){
+            throw new org.openvpp.jvpp.VppInvocationException("${name}",result);
+        }
+        return result;
+    }
+""")
+
+no_arg_method_template = Template("""    int $name() throws org.openvpp.jvpp.VppInvocationException;""")
+no_arg_method_native_template = Template("""    private static native int ${name}0() throws org.openvpp.jvpp.VppInvocationException;""")
+no_arg_method_impl_template = Template("""    public final int $name() throws org.openvpp.jvpp.VppInvocationException {
+        connection.checkActive();
+        int result=${name}0();
+        if(result<0){
+            throw new org.openvpp.jvpp.VppInvocationException("${name}",result);
+        }
+        return result;
+    }
+""")
+
+
+def generate_jvpp(func_list, base_package, dto_package, inputfile):
+    """ Generates JVpp interface and JNI implementation """
+    print "Generating JVpp"
+
+    methods = []
+    methods_impl = []
+    for func in func_list:
+
+        # Skip structures that are used only as notifications
+        if util.is_just_notification(func['name']) or util.is_ignored(func['name']):
+            continue
+
+        camel_case_name = util.underscore_to_camelcase(func['name'])
+        camel_case_name_upper = util.underscore_to_camelcase_upper(func['name'])
+        if util.is_reply(camel_case_name):
+            continue
+
+        if len(func['args']) == 0:
+            methods.append(no_arg_method_template.substitute(name=camel_case_name,
+                                                             base_package=base_package,
+                                                             dto_package=dto_package))
+            methods_impl.append(
+                no_arg_method_native_template.substitute(name=camel_case_name,
+                                                         base_package=base_package,
+                                                         dto_package=dto_package))
+            methods_impl.append(no_arg_method_impl_template.substitute(name=camel_case_name,
+                                                                       base_package=base_package,
+                                                                       dto_package=dto_package))
+        else:
+            methods.append(method_template.substitute(name=camel_case_name,
+                                                      request=camel_case_name_upper,
+                                                      base_package=base_package,
+                                                      dto_package=dto_package))
+            methods_impl.append(method_native_template.substitute(name=camel_case_name,
+                                                                  request=camel_case_name_upper,
+                                                                  base_package=base_package,
+                                                                  dto_package=dto_package))
+            methods_impl.append(method_impl_template.substitute(name=camel_case_name,
+                                                                request=camel_case_name_upper,
+                                                                base_package=base_package,
+                                                                dto_package=dto_package))
+
+    jvpp_file = open("JVpp.java", 'w')
+    jvpp_file.write(
+        jvpp_ifc_template.substitute(inputfile=inputfile,
+                                     methods="\n".join(methods),
+                                     base_package=base_package,
+                                     dto_package=dto_package))
+    jvpp_file.flush()
+    jvpp_file.close()
+
+    jvpp_file = open("JVppImpl.java", 'w')
+    jvpp_file.write(jvpp_impl_template.substitute(inputfile=inputfile,
+                                                  methods="\n".join(methods_impl),
+                                                  base_package=base_package,
+                                                  dto_package=dto_package))
+    jvpp_file.flush()
+    jvpp_file.close()
diff --git a/vpp-api/java/jvpp/gen/jvppgen/notification_gen.py b/vpp-api/java/jvpp/gen/jvppgen/notification_gen.py
new file mode 100644
index 0000000..df6407f
--- /dev/null
+++ b/vpp-api/java/jvpp/gen/jvppgen/notification_gen.py
@@ -0,0 +1,164 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2016 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+
+import callback_gen
+import util
+from string import Template
+
+from util import remove_suffix
+
+notification_registry_template = Template("""
+package $base_package.$notification_package;
+
+/**
+ * <p>Registry for notification callbacks.
+ * <br>It was generated by notification_gen.py based on $inputfile
+ * <br>(python representation of vpe.api generated by vppapigen).
+ */
+public interface NotificationRegistry extends java.lang.AutoCloseable {
+
+    $register_callback_methods
+
+    @Override
+    void close();
+}
+""")
+
+global_notification_callback_template = Template("""
+package $base_package.$notification_package;
+
+/**
+ * <p>Aggregated callback interface for notifications only.
+ * <br>It was generated by notification_gen.py based on $inputfile
+ * <br>(python representation of vpe.api generated by vppapigen).
+ */
+public interface GlobalNotificationCallback extends $callbacks {
+
+}
+""")
+
+notification_registry_impl_template = Template("""
+package $base_package.$notification_package;
+
+/**
+ * <p>Notification registry delegating notification processing to registered callbacks.
+ * <br>It was generated by notification_gen.py based on $inputfile
+ * <br>(python representation of vpe.api generated by vppapigen).
+ */
+public final class NotificationRegistryImpl implements NotificationRegistry, GlobalNotificationCallback {
+
+    // TODO add a special NotificationCallback interface and only allow those to be registered
+    private final java.util.concurrent.ConcurrentMap<Class<? extends $base_package.$dto_package.JVppNotification>, $base_package.$callback_package.JVppNotificationCallback> registeredCallbacks =
+        new java.util.concurrent.ConcurrentHashMap<>();
+
+    $register_callback_methods
+    $handler_methods
+
+    @Override
+    public void close() {
+        registeredCallbacks.clear();
+    }
+}
+""")
+
+register_callback_impl_template = Template("""
+    public java.lang.AutoCloseable register$callback(final $base_package.$callback_package.$callback callback){
+        if(null != registeredCallbacks.putIfAbsent($base_package.$dto_package.$notification.class, callback)){
+            throw new IllegalArgumentException("Callback for " + $base_package.$dto_package.$notification.class +
+                "notification already registered");
+        }
+        return () -> registeredCallbacks.remove($base_package.$dto_package.$notification.class);
+    }
+""")
+
+handler_impl_template = Template("""
+    @Override
+    public void on$notification(
+        final $base_package.$dto_package.$notification notification) {
+        final $base_package.$callback_package.JVppNotificationCallback JVppNotificationCallback = registeredCallbacks.get($base_package.$dto_package.$notification.class);
+        if (null != JVppNotificationCallback) {
+            (($base_package.$callback_package.$callback) registeredCallbacks
+                .get($base_package.$dto_package.$notification.class))
+                .on$notification(notification);
+        }
+    }
+""")
+
+
+def generate_notification_registry(func_list, base_package, notification_package, callback_package, dto_package, inputfile):
+    """ Generates notification registry interface and implementation """
+    print "Generating Notification interfaces and implementation"
+
+    if not os.path.exists(notification_package):
+        raise Exception("%s folder is missing" % notification_package)
+
+    callbacks = []
+    register_callback_methods = []
+    register_callback_methods_impl = []
+    handler_methods = []
+    for func in func_list:
+
+        if not util.is_notification(func['name']):
+            continue
+
+        camel_case_name_with_suffix = util.underscore_to_camelcase_upper(func['name'])
+        notification_dto = util.add_notification_suffix(camel_case_name_with_suffix)
+        callback_ifc = notification_dto + callback_gen.callback_suffix
+        fully_qualified_callback_ifc = "{0}.{1}.{2}".format(base_package, callback_package, callback_ifc)
+        callbacks.append(fully_qualified_callback_ifc)
+
+        # TODO create NotificationListenerRegistration and return that instead of AutoCloseable to better indicate
+        # that the registration should be closed
+        register_callback_methods.append("java.lang.AutoCloseable register{0}({1} callback);"
+                                         .format(callback_ifc, fully_qualified_callback_ifc))
+        register_callback_methods_impl.append(register_callback_impl_template.substitute(base_package=base_package,
+                                                                                         callback_package=callback_package,
+                                                                                         dto_package=dto_package,
+                                                                                         notification=notification_dto,
+                                                                                         callback=callback_ifc))
+        handler_methods.append(handler_impl_template.substitute(base_package=base_package,
+                                                                callback_package=callback_package,
+                                                                dto_package=dto_package,
+                                                                notification=notification_dto,
+                                                                callback=callback_ifc))
+    if(callbacks):
+      callback_file = open(os.path.join(notification_package, "NotificationRegistry.java"), 'w')
+      callback_file.write(notification_registry_template.substitute(inputfile=inputfile,
+                                                                    register_callback_methods="\n    ".join(register_callback_methods),
+                                                                    base_package=base_package,
+                                                                    notification_package=notification_package))
+      callback_file.flush()
+      callback_file.close()
+
+      callback_file = open(os.path.join(notification_package, "GlobalNotificationCallback.java"), 'w')
+      callback_file.write(global_notification_callback_template.substitute(inputfile=inputfile,
+                                                                           callbacks=", ".join(callbacks),
+                                                                           base_package=base_package,
+                                                                           notification_package=notification_package))
+      callback_file.flush()
+      callback_file.close()
+
+      callback_file = open(os.path.join(notification_package, "NotificationRegistryImpl.java"), 'w')
+      callback_file.write(notification_registry_impl_template.substitute(inputfile=inputfile,
+                                                                         callback_package=callback_package,
+                                                                         dto_package=dto_package,
+                                                                         register_callback_methods="".join(register_callback_methods_impl),
+                                                                         handler_methods="".join(handler_methods),
+                                                                         base_package=base_package,
+                                                                         notification_package=notification_package))
+      callback_file.flush()
+      callback_file.close()
diff --git a/vpp-api/java/jvpp/gen/jvppgen/util.py b/vpp-api/java/jvpp/gen/jvppgen/util.py
new file mode 100644
index 0000000..f22132d
--- /dev/null
+++ b/vpp-api/java/jvpp/gen/jvppgen/util.py
@@ -0,0 +1,195 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2016 Cisco and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os, pprint
+from os import removedirs
+
+
+def underscore_to_camelcase(name):
+    name = name.title().replace("_", "")
+    return name[0].lower() + name[1:]
+
+
+def underscore_to_camelcase_upper(name):
+    name = name.title().replace("_", "")
+    return name[0].upper() + name[1:]
+
+
+def remove_folder(folder):
+    """ Remove folder with all its files """
+    for root, dirs, files in os.walk(folder, topdown=False):
+        for name in files:
+            os.remove(os.path.join(root, name))
+        removedirs(folder)
+
+
+reply_suffixes = ("reply", "details", "l2fibtableentry")
+
+
+def is_reply(name):
+    return name.lower().endswith(reply_suffixes)
+
+
+def is_details(name):
+    return name.lower().endswith(reply_suffixes[1]) or name.lower().endswith(reply_suffixes[2])
+
+def is_retval_field(name):
+    return name == 'retval'
+
+dump_suffix = "dump"
+
+
+def is_dump(name):
+    return name.lower().endswith(dump_suffix)
+
+
+def get_reply_suffix(name):
+    for reply_suffix in reply_suffixes:
+        if name.lower().endswith(reply_suffix):
+            if reply_suffix == reply_suffixes[2]:
+                # FIXME workaround for l2_fib_table_entry
+                return 'entry'
+            else:
+                return reply_suffix
+
+# http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/types.html
+jni_2_java_type_mapping = {'jbyte': 'byte',
+                           'jbyteArray': 'byte[]',
+                           'jchar': 'char',
+                           'jcharArray': 'char[]',
+                           'jshort': 'short',
+                           'jshortArray': 'short[]',
+                           'jint': 'int',
+                           'jintArray': 'int[]',
+                           'jlong': 'long',
+                           'jlongArray': 'long[]',
+                           'jdouble': 'double',
+                           'jdoubleArray': 'double[]',
+                           'jfloat': 'float',
+                           'jfloatArray': 'float[]',
+                           'void': 'void',
+                           'jstring': 'java.lang.String',
+                           'jobject': 'java.lang.Object',
+                           'jobjectArray': 'java.lang.Object[]'
+                           }
+
+# https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/types.html#type_signatures
+jni_2_signature_mapping = {'jbyte': 'B',
+                           'jbyteArray': '[B',
+                           'jchar': 'C',
+                           'jcharArray': '[C',
+                           'jshort': 'S',
+                           'jshortArray': '[S',
+                           'jint': 'I',
+                           'jintArray': '[I',
+                           'jlong': 'J',
+                           'jlongArray': '[J',
+                           'jdouble': 'D',
+                           'jdoubleArray': '[D',
+                           'jfloat': 'F',
+                           'jfloatArray': '[F'
+                           }
+
+# https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/functions.html#Get_type_Field_routines
+jni_field_accessors = {
+    'jbyte': 'ByteField',
+    'jbyteArray': 'ObjectField',
+    'jchar': 'CharField',
+    'jcharArray': 'ObjectField',
+    'jshort': 'ShortField',
+    'jshortArray': 'ObjectField',
+    'jint': 'IntField',
+    'jintArray': 'ObjectField',
+    'jlong': 'LongField',
+    'jlongArray': 'ObjectField',
+    'jdouble': 'DoubleField',
+    'jdoubleArray': 'ObjectField',
+    'jfloat': 'FloatField',
+    'jfloatArray': 'ObjectField'
+}
+
+# TODO watch out for unsigned types
+# http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/types.html
+vpp_2_jni_type_mapping = {'u8': 'jbyte',  # fixme
+                          'i8': 'jbyte',
+                          'u16': 'jshort',
+                          'i16': 'jshort',
+                          'u32': 'jint',  # fixme
+                          'i32': 'jint',
+                          'u64': 'jlong',  # fixme
+                          'i64': 'jlong',
+                          'f64': 'jdouble'
+                          }
+
+# vpe.api calls that do not follow naming conventions and have to be handled exceptionally when finding reply -> request mapping
+# FIXME in vpe.api
+unconventional_naming_rep_req = {
+                                 'cli_reply': 'cli_request',
+                                 'vnet_summary_stats_reply': 'vnet_get_summary_stats',
+                                 # This below is actually a sub-details callback. We cannot derive the mapping of dump request
+                                 # belonging to this sub-details from naming conventions. We need special mapping
+                                 'bridge_domain_sw_if_details': 'bridge_domain',
+                                 # This is standard dump call + details reply. However it's not called details but entry
+                                 'l2_fib_table_entry': 'l2_fib_table'
+                                 }
+
+#
+# FIXME no convention in the naming of events (notifications) in vpe.api
+notifications_message_suffixes = ("event", "counters")
+notification_messages_reused = ["sw_interface_set_flags"]
+
+# messages that must be ignored. These messages are INSUFFICIENTLY marked as disabled in vpe.api
+# FIXME
+ignored_messages = ["is_address_reachable"]
+
+
+def is_notification(name):
+    """ Returns true if the structure is a notification regardless of its no other use """
+    return is_just_notification(name) or name.lower() in notification_messages_reused
+
+
+def is_just_notification(name):
+    """ Returns true if the structure is just a notification and has no other use """
+    return name.lower().endswith(notifications_message_suffixes)
+
+
+def is_ignored(param):
+    return param.lower() in ignored_messages
+
+
+def remove_reply_suffix(camel_case_name_with_suffix):
+    return remove_suffix(camel_case_name_with_suffix, get_reply_suffix(camel_case_name_with_suffix))
+
+
+def remove_suffix(camel_case_name_with_suffix, suffix):
+    suffix_length = len(suffix)
+    return camel_case_name_with_suffix[:-suffix_length] if suffix_length != 0 else camel_case_name_with_suffix
+
+
+def is_control_ping(camel_case_name_with_suffix):
+    return "controlping" in camel_case_name_with_suffix.lower()
+
+def api_message_to_javadoc(api_message):
+    """ Converts vpe.api message description to javadoc """
+    str = pprint.pformat(api_message, indent=4, width=120, depth=None)
+    return " * " + str.replace("\n", "\n * ")
+
+
+notification_dto_suffix = "Notification"
+
+
+def add_notification_suffix(camel_case_dto_name):
+    camel_case_dto_name += notification_dto_suffix
+    return camel_case_dto_name