diff --git a/jni/libucommon/sources/inc/ucommon/generics.h b/jni/libucommon/sources/inc/ucommon/generics.h
new file mode 100644
index 0000000..28a4d0b
--- /dev/null
+++ b/jni/libucommon/sources/inc/ucommon/generics.h
@@ -0,0 +1,575 @@
+// Copyright (C) 2006-2010 David Sugar, Tycho Softworks.
+//
+// This file is part of GNU uCommon C++.
+//
+// GNU uCommon C++ is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as published
+// by the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// GNU uCommon C++ is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with GNU uCommon C++.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Generic templates for C++.  These are templates that do not depend
+ * on any ucommon classes.  They can be used for generic C++ programming.
+ * @file ucommon/generics.h
+ */
+
+#ifndef _UCOMMON_GENERICS_H_
+#define _UCOMMON_GENERICS_H_
+
+#ifndef _UCOMMON_CPR_H_
+#include <ucommon/cpr.h>
+#endif
+
+#include <cstdlib>
+#include <string.h>
+
+#ifdef  NEW_STDLIB
+#include <stdexcept>
+#endif
+
+#if defined(NEW_STDLIB) || defined(OLD_STDLIB)
+#define THROW(x)    throw x
+#define THROWS(x)   throw(x)
+#define THROWS_ANY  throw()
+#else
+#define THROW(x)    ::abort()
+#define THROWS(x)
+#define THROWS_ANY
+#endif
+
+NAMESPACE_UCOMMON
+
+/**
+ * Generic smart pointer class.  This is the original Common C++ "Pointer"
+ * class with a few additions.
+ * @author David Sugar <dyfet@gnutelephony.org>
+ */
+template <typename T>
+class pointer
+{
+protected:
+    unsigned *counter;
+    T *object;
+
+public:
+    inline void release(void) {
+        if(counter && --(*counter)==0) {
+            delete counter;
+            delete object;
+        }
+        object = NULL;
+        counter = NULL;
+    }
+
+    inline void retain(void) {
+        if(counter)
+            ++*counter;
+    }
+
+    inline void set(T* ptr) {
+        if(object != ptr) {
+            release();
+            counter = new unsigned;
+            *counter = 1;
+            object = ptr;
+        }
+    }
+
+    inline void set(const pointer<T> &ref) {
+        if(object == ref.object)
+            return;
+
+        if(counter && --(*counter)==0) {
+            delete counter;
+            delete object;
+        }
+        object = ref.object;
+        counter = ref.counter;
+        if(counter)
+            ++(*counter);
+    }
+
+    inline pointer() {
+        counter = NULL;
+        object = NULL;
+    }
+
+    inline explicit pointer(T* ptr = NULL) : object(ptr) {
+        if(object) {
+            counter = new unsigned;
+            *counter = 1;
+        }
+        else
+            counter = NULL;
+    }
+
+    inline pointer(const pointer<T> &ref) {
+        object = ref.object;
+        counter = ref.counter;
+        if(counter)
+            ++(*counter);
+    }
+
+    inline pointer& operator=(const pointer<T> &ref) {
+        this->set(ref);
+        return *this;
+    }
+
+    inline pointer& operator=(T *ptr) {
+        this->set(ptr);
+        return *this;
+    }
+
+    inline ~pointer()
+        {release();}
+
+    inline T& operator*() const
+        {return *object;};
+
+    inline T* operator->() const
+        {return object;};
+
+    inline bool operator!() const
+        {return (counter == NULL);};
+
+    inline operator bool() const
+        {return counter != NULL;};
+};
+
+/**
+ * Generic smart array class.  This is the original Common C++ "Pointer" class
+ * with a few additions for arrays.
+ * @author David Sugar <dyfet@gnutelephony.org>
+ */
+template <typename T>
+class array_pointer
+{
+protected:
+    unsigned *counter;
+    T *array;
+
+public:
+    inline void release(void) {
+        if(counter && --(*counter)==0) {
+            delete counter;
+            delete[] array;
+        }
+        array = NULL;
+        counter = NULL;
+    }
+
+    inline void retain(void) {
+        if(counter)
+            ++*counter;
+    }
+
+    inline void set(T* ptr) {
+        if(array != ptr) {
+            release();
+            counter = new unsigned;
+            *counter = 1;
+            array = ptr;
+        }
+    }
+
+    inline void set(const array_pointer<T> &ref) {
+        if(array == ref.array)
+            return;
+
+        if(counter && --(*counter)==0) {
+            delete counter;
+            delete[] array;
+        }
+        array = ref.array;
+        counter = ref.counter;
+        if(counter)
+            ++(*counter);
+    }
+
+    inline array_pointer() {
+        counter = NULL;
+        array = NULL;
+    }
+
+    inline explicit array_pointer(T* ptr = NULL) : array(ptr) {
+        if(array) {
+            counter = new unsigned;
+            *counter = 1;
+        }
+        else
+            counter = NULL;
+    }
+
+    inline array_pointer(const array_pointer<T> &ref) {
+        array = ref.array;
+        counter = ref.counter;
+        if(counter)
+            ++(*counter);
+    }
+
+    inline array_pointer& operator=(const array_pointer<T> &ref) {
+        this->set(ref);
+        return *this;
+    }
+
+    inline array_pointer& operator=(T *ptr) {
+        this->set(ptr);
+        return *this;
+    }
+
+    inline ~array_pointer()
+        {release();}
+
+    inline T* operator*() const
+        {return array;};
+
+    inline T& operator[](size_t offset) const
+        {return array[offset];};
+
+    inline T* operator()(size_t offset) const
+        {return &array[offset];};
+
+    inline bool operator!() const
+        {return (counter == NULL);};
+
+    inline operator bool() const
+        {return counter != NULL;};
+};
+
+/**
+ * Manage temporary object stored on the heap.  This is used to create a
+ * object on the heap who's scope is controlled by the scope of a member
+ * function call.  Sometimes we have data types and structures which cannot
+ * themselves appear as auto variables.  We may also have a limited stack
+ * frame size in a thread context, and yet have a dynamic object that we
+ * only want to exist during the life of the method call.  Using temporary
+ * allows any type to be created from the heap but have a lifespan of a
+ * method's stack frame.
+ * @author David Sugar <dyfet@gnutelephony.org>
+ */
+template <typename T>
+class temporary
+{
+protected:
+    T *object;
+public:
+    /**
+     * Construct a temporary object, create our stack frame reference.
+     */
+    inline temporary()
+        {object = NULL;};
+
+    /**
+     * Disable copy constructor.
+     */
+    temporary(const temporary<T>&)
+        {::abort();};
+
+    /**
+     * Construct an assigned pointer.
+     */
+    inline temporary(T *ptr)
+        {object = ptr;};
+
+    /**
+     * Assign a temporary object.  This adds a pointer to an existing
+     * type to the current temporary pointer.  If the temporary was
+     * already assigned, then it is deleted.
+     * @param temp object to assign.
+     */
+    inline T& operator=(T *temp) {
+        if(object)
+            delete object;
+        object = temp;
+        return *this;
+    }
+
+    /**
+     * Assign a temporary object.  This adds a pointer to an existing
+     * type to the current temporary pointer.  If the temporary was
+     * already assigned, then it is deleted.
+     * @param temp object to assign.
+     */
+    inline void set(T *temp) {
+        if(object)
+            delete object;
+        object = temp;
+    }
+
+    /**
+     * Access heap object through our temporary directly.
+     * @return reference to heap resident object.
+     */
+    inline T& operator*() const
+        {return *object;};
+
+    /**
+     * Access members of our heap object through our temporary.
+     * @return member reference of heap object.
+     */
+    inline T* operator->() const
+        {return object;};
+
+    inline operator bool() const
+        {return object != NULL;};
+
+    inline bool operator!() const
+        {return object == NULL;};
+
+    inline ~temporary() {
+        if(object)
+            delete object;
+        object = NULL;
+    }
+};
+
+/**
+ * Manage temporary array stored on the heap.   This is used to create an
+ * array on the heap who's scope is controlled by the scope of a member
+ * function call.  Sometimes we have data types and structures which cannot
+ * themselves appear as auto variables.  We may also have a limited stack
+ * frame size in a thread context, and yet have a dynamic object that we
+ * only want to exist during the life of the method call.  Using temporary
+ * allows any type to be created from the heap but have a lifespan of a
+ * method's stack frame.
+ * @author David Sugar <dyfet@gnutelephony.org>
+ */
+template <typename T>
+class temp_array
+{
+protected:
+    T *array;
+    size_t size;
+
+public:
+    /**
+     * Construct a temporary object, create our stack frame reference.
+     */
+    inline temp_array(size_t s)
+        {array =  new T[s]; size = s;};
+
+    /**
+     * Construct a temporary object with a copy of some initial value.
+     * @param initial object value to use.
+     */
+    inline temp_array(const T& initial, size_t s) {
+        array = new T[s];
+        size = s;
+        for(size_t p = 0; p < s; ++p)
+            array[p] = initial;
+    }
+
+    inline void reset(size_t s)
+        {delete[] array; array = new T[s]; size = s;};
+
+    inline void reset(const T& initial, size_t s) {
+        if(array)
+            delete[] array;
+        array = new T[s];
+        size = s;
+        for(size_t p = 0; p < s; ++p)
+            array[p] = initial;
+    }
+
+    inline void set(const T& initial) {
+        for(size_t p = 0; p < size; ++p)
+            array[p] = initial;
+    }
+
+    /**
+     * Disable copy constructor.
+     */
+    temp_array(const temp_array<T>&)
+        {::abort();};
+
+    inline operator bool() const
+        {return array != NULL;};
+
+    inline bool operator!() const
+        {return array == NULL;};
+
+    inline ~temp_array() {
+        if(array)
+            delete[] array;
+        array = NULL;
+        size = 0;
+    }
+
+    inline T& operator[](size_t offset) const {
+        crit(offset < size, "array out of bound");
+        return array[offset];
+    }
+
+    inline T* operator()(size_t offset) const {
+        crit(offset < size, "array out of bound");
+        return &array[offset];
+    }
+};
+
+/**
+ * Save and restore global objects in function call stack frames.
+ * @author David Sugar <dyfet@gnutelephony.org>
+ */
+template<typename T>
+class save_restore
+{
+private:
+    T *original;
+    T temp;
+
+public:
+    /**
+     * Save object into local copy and keep reference to the original object.
+     * @param object to save.
+     */
+    inline save_restore(T& object)
+        {original = &object; temp = object;};
+
+    /**
+     * Restore original when stack frame is released.
+     */
+    inline ~save_restore()
+        {*original = temp;};
+};
+
+/**
+ * Convenience function to validate object assuming it is castable to bool.
+ * @param object we are testing.
+ * @return true if object valid.
+ */
+template<class T>
+inline bool is(T& object)
+    {return object.operator bool();}
+
+/**
+ * Convenience function to test pointer object.  This solves issues where
+ * some compilers get confused between bool and pointer operators.
+ * @param object we are testing.
+ * @return true if object points to NULL.
+ */
+template<typename T>
+inline bool isnull(T& object)
+    {return (bool)(object.operator*() == NULL);}
+
+/**
+ * Convenience function to test pointer-pointer object.  This solves issues
+ * where some compilers get confused between bool and pointer operators.
+ * @param object we are testing.
+ * @return true if object points to NULL.
+ */
+template<typename T>
+inline bool isnullp(T *object)
+    {return (bool)(object->operator*() == NULL);}
+
+/**
+ * Convenience function to duplicate object pointer to heap.
+ * @param object we are duping.
+ * @return heap pointer instance.
+ */
+template<typename T>
+inline T* dup(const T& object)
+    {return new T(object);}
+
+template<typename T>
+inline void dupfree(T object)
+    {delete object;}
+
+template<>
+inline char *dup<char>(const char& object)
+    {return strdup(&object);}
+
+template<>
+inline void dupfree<char*>(char* object)
+    {::free(object);}
+
+/**
+ * Convenience function to reset an existing object.
+ * @param object type to reset.
+ */
+template<typename T>
+inline void reset_unsafe(T& object)
+    {new((caddr_t)&object) T;}
+
+/**
+ * Convenience function to zero an object and restore type info.
+ * @param object to zero in memory.
+ */
+template<typename T>
+inline void zero_unsafe(T& object)
+    {memset((void *)&object, 0, sizeof(T)); new((caddr_t)&object) T;}
+
+/**
+ * Convenience function to copy class.
+ * @param target to copy into.
+ * @param source to copy from.
+ */
+template<typename T>
+inline void copy_unsafe(T* target, const T* source)
+    {memcpy((void *)target, (void *)source, sizeof(T));}
+
+/**
+ * Convenience function to store object pointer into object.
+ * @param target to copy into.
+ * @param source to copy from.
+ */
+template<typename T>
+inline void store_unsafe(T& target, const T* source)
+    {memcpy((void *)&target, (void *)source, sizeof(T));}
+
+/**
+ * Convenience function to swap objects.
+ * @param o1 to swap.
+ * @param o2 to swap.
+ */
+template<typename T>
+inline void swap(T& o1, T& o2)
+    {cpr_memswap(&o1, &o2, sizeof(T));}
+
+/**
+ * Convenience function to return max of two objects.
+ * @param o1 to check.
+ * @param o2 to check.
+ * @return max object.
+ */
+template<typename T>
+inline T& (max)(T& o1, T& o2)
+{
+    return o1 > o2 ? o1 : o2;
+}
+
+/**
+ * Convenience function to return min of two objects.
+ * @param o1 to check.
+ * @param o2 to check.
+ * @return min object.
+ */
+template<typename T>
+inline T& (min)(T& o1, T& o2)
+{
+    return o1 < o2 ? o1 : o2;
+}
+
+/**
+ * Convenience macro to range restrict values.
+ * @param value to check.
+ * @param low value.
+ * @param high value.
+ * @return adjusted value.
+ */
+template<typename T>
+inline T& (limit)(T& value, T& low, T& high)
+{
+    return (value < low) ? low : ((value > high) ? high : value);
+}
+
+END_NAMESPACE
+
+#endif
