diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..638c8d2a4f126823299db9c14b149df08d613908
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+bin
+build
+lib
diff --git a/CMakeLists.txt b/CMakeLists.txt
index dd63f3c448f9b6a57896ddcf56c24305ab6ca28b..e3f22131499f4f948a06fe53282be31df42deeaa 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,30 +1,48 @@
 # Pre-requisites about cmake itself
 CMAKE_MINIMUM_REQUIRED(VERSION 2.4)
+SET(CMAKE_CXX_STANDARD 11)
 
 if(COMMAND cmake_policy)
   cmake_policy(SET CMP0007 NEW) 
   cmake_policy(SET CMP0005 NEW) 
   cmake_policy(SET CMP0003 NEW)
   cmake_policy(SET CMP0002 NEW)
-   
 endif(COMMAND cmake_policy)
 
 # The project name and the type of project
 PROJECT(finddd-descriptor)
+SET(PACKAGE_NAME finddd-descriptor)
 
 SET(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/bin)
 SET(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib)
-SET(CMAKE_INSTALL_PREFIX /usr/local)
+
+IF ("${INSTALL_DIR}" STREQUAL "")
+  MESSAGE ("[INSTALL] set install_dir to /usr/local")
+  SET(CMAKE_INSTALL_PREFIX /usr/local)
+ELSE ()
+  MESSAGE ("[INSTALL] set install_dir to input ${INSTALL_DIR}")
+  SET(CMAKE_INSTALL_PREFIX ${INSTALL_DIR})
+ENDIF ()
 
 IF (NOT CMAKE_BUILD_TYPE)
  SET(CMAKE_BUILD_TYPE "DEBUG") 
 ENDIF (NOT CMAKE_BUILD_TYPE)
 
-SET(CMAKE_CXX_FLAGS_DEBUG "-g -Wall -D_REENTRANT")
 SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -D_REENTRANT")
+SET(CMAKE_CXX_FLAGS_DEBUG "-g -Wall -D_REENTRANT -O0 --coverage -fprofile-arcs")
+SET(CMAKE_LINK_FLAGS_DEBUG "--coverage -fprofile-arcs")
+
+#
+# Add ctest
+#
+INCLUDE(CTest)
 
 ADD_SUBDIRECTORY(src)
 
+ADD_SUBDIRECTORY(test/gtest)
+
+ADD_SUBDIRECTORY(test)
+
 FIND_PACKAGE(Doxygen)
 
 FIND_PATH(IRI_DOC_DIR doxygen.conf ${CMAKE_SOURCE_DIR}/doc/iri_doc/)
@@ -68,3 +86,33 @@ ELSE(UNIX)
 ENDIF(UNIX)
 
 
+IF (CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)")
+  SET (X86 TRUE)
+  SET(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")
+ELSE ()
+  SET (X86 FALSE)
+  SET(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "i386")
+ENDIF()
+
+IF (UNIX)
+  SET(CPACK_PACKAGE_FILE_NAME "iri-${PACKAGE_NAME}-dev-${CPACK_PACKAGE_VERSION}-${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}")
+  SET(CPACK_PACKAGE_NAME "iri-${PACKAGE_NAME}-dev")
+  SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Part of IRI-laboratory libraries. More information at https://gitlab.iri.upc.edu/labrobotica/labrobotica_how_to")
+  SET(CPACK_PACKAGING_INSTALL_PREFIX /usr)
+  SET(CPACK_GENERATOR "DEB")
+  SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "labrobotica - labrobotica@iri.upc.edu")
+
+# Uncomment to add the necessary mantainer scripts
+#   SET(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_SOURCE_DIR}/package_scripts/preinst;${CMAKE_SOURCE_DIR}/package_scripts/postinst;${CMAKE_SOURCE_DIR}/package_scripts/prerm;${CMAKE_SOURCE_DIR}/package_scripts/postrm")
+
+# Uncomment to add dependencies comma separated
+# SET(CPACK_DEBIAN_PACKAGE_DEPENDS "iri-<package_name>-dev (>= 1.0~${DISTRIB})")
+
+  INCLUDE(CPack)
+ELSE(UNIX)
+  ADD_CUSTOM_COMMAND(
+    COMMENT "packaging only implemented in unix"
+    TARGET  uninstall
+  )
+ENDIF(UNIX)
+
diff --git a/src/finddd_descriptor.hpp b/include/finddd_descriptor.hpp
similarity index 99%
rename from src/finddd_descriptor.hpp
rename to include/finddd_descriptor.hpp
index f2ee768acf7a16f9c3557936a318444570004cd4..2c0cc0634395c26eee307d4e2588c7809364df04 100644
--- a/src/finddd_descriptor.hpp
+++ b/include/finddd_descriptor.hpp
@@ -1,4 +1,3 @@
-
 #ifndef _finddd_alg_h_
 #define _finddd_alg_h_
 
@@ -18,6 +17,7 @@
 
 // util
 template <class T>
+[[deprecated]]
 inline std::string to_string (const T& t)
 {
   std::stringstream ss;
@@ -303,7 +303,7 @@ protected:
    * the PCA matrix.
    *
    */
-  inline void update_pca_matrix(std::string new_pca_matrix_file, int pca_nkeep)
+  inline void update_pca_matrix(std::string new_pca_matrix_file, size_t pca_nkeep)
   {
     this->pca_file_ = new_pca_matrix_file;
     this->pca_nkeep_=pca_nkeep;
@@ -325,14 +325,13 @@ protected:
       float num;
       getline(ifs, line);
       std::istringstream iss(line);
-      int i=0;
       do 
       {
         iss >> num;
         this->pca_mean_.push_back(num);
       }while(!iss.eof());
     }
-    int dout=0;
+    size_t dout=0;
     while (ifs.good())
     {
       float num;
@@ -371,7 +370,7 @@ protected:
     std::vector< std::vector<float> > PCA_t;
     PCA_t.resize(nkeep, std::vector<float>(this->pca_matrix_.size()));
     for(int i=0;i<nkeep;i++)
-      for(int j=0;j<this->pca_matrix_.size();j++)
+      for(size_t j=0;j<this->pca_matrix_.size();j++)
       {
 	PCA_t[i][j]=this->pca_matrix_[j][i];
       }
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6062c4eb2b74661fd1cff362b409226c21542172..325d3a29dd8df39da9be6c422db83a358ccdb3b9 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,24 +1,25 @@
+# application source files
+SET(sources finddd_descriptor.cpp)
+# application header files
+SET(headers ../include/finddd_descriptor.hpp)
+
+# add the necessary include directories
+INCLUDE_DIRECTORIES(../include)
+
 # locate the necessary dependencies
 FIND_PACKAGE( Boost 1.46 COMPONENTS program_options REQUIRED )
 INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIR} )
 
 #IF PCL in non-standard directory, uncomment this: 
 #set(PCL_DIR "<path-to-pcl>/PCLConfig.cmake") 
-find_package(PCL  1.3  REQUIRED  COMPONENTS  common io features )
-include_directories(${PCL_INCLUDE_DIRS})
-link_directories(${PCL_LIBRARY_DIRS})
-add_definitions(${PCL_DEFINITIONS})
+FIND_PACKAGE(PCL 1.3 REQUIRED COMPONENTS common io features )
+INCLUDE_DIRECTORIES(${PCL_INCLUDE_DIRS})
+LINK_DIRECTORIES(${PCL_LIBRARY_DIRS})
+ADD_DEFINITIONS(${PCL_DEFINITIONS})
 
 SET(CMAKE_BUILD_TYPE "RELEASE")
 
-# add the necessary include directories
-INCLUDE_DIRECTORIES(.)
-# application source files
-SET(sources finddd_descriptor.cpp)
-# application header files
-SET(headers finddd_descriptor.hpp)
 # create the executable file
 ADD_EXECUTABLE(finddd_descriptor ${sources})
 # link necessary libraries
-target_link_libraries(finddd_descriptor  ${Boost_LIBRARIES} ${PCL_COMMON_LIBRARIES}  ${PCL_IO_LIBRARIES} ${PCL_FEATURES_LIBRARIES})
-#target_link_libraries(finddd_descriptor  ${Boost_LIBRARIES} ${PCL_LIBRARY_DIRS})
+TARGET_LINK_LIBRARIES(finddd_descriptor  ${Boost_LIBRARIES} ${PCL_COMMON_LIBRARIES}  ${PCL_IO_LIBRARIES} ${PCL_FEATURES_LIBRARIES})
diff --git a/src/finddd_descriptor.cpp b/src/finddd_descriptor.cpp
index 2408b2c3a5bac821db443c1ee6da0ac11d8f6be4..6888c9a56a53cb9844b7cc420551f9383720b4c0 100755
--- a/src/finddd_descriptor.cpp
+++ b/src/finddd_descriptor.cpp
@@ -1,6 +1,5 @@
 #include "finddd_descriptor.hpp"
 
-
 #define PI 3.1415926535
 
 /** 
@@ -306,7 +305,7 @@ void FindddAlgorithm::compute_ndescs_integral_spatial_interpolation(pcl::PointCl
   if(this->use_soft_voting_) {
     for(uint v=0;v<cloud.height;v++) {
       for(uint u=0;u<cloud.width;u++)  {
-	if(isnan(pcl_normals(u,v).normal_x) || isnan(pcl_normals(u,v).normal_y) || isnan(pcl_normals(u,v).normal_z))
+	if(std::isnan(pcl_normals(u,v).normal_x) || std::isnan(pcl_normals(u,v).normal_y) || std::isnan(pcl_normals(u,v).normal_z))
 	  binned[u+cloud.width*v]=get_bin_float_empty(this->orient_bin_centers_x_.size()); // empty vector
 	else {
 	  binned[u+cloud.width*v] = get_bin_float_interp_xyz(pcl_normals(u,v).normal_x, pcl_normals(u,v).normal_y, pcl_normals(u,v).normal_z, this->orient_bin_centers_x_, this->orient_bin_centers_y_, this->orient_bin_centers_z_, this->radius_inf_);
@@ -314,7 +313,7 @@ void FindddAlgorithm::compute_ndescs_integral_spatial_interpolation(pcl::PointCl
   else {
     for(uint v=0;v<cloud.height;v++) {
       for(uint u=0;u<cloud.width;u++) {
-	if(isnan(pcl_normals(u,v).normal_x) || isnan(pcl_normals(u,v).normal_y) || isnan(pcl_normals(u,v).normal_z))
+	if(std::isnan(pcl_normals(u,v).normal_x) || std::isnan(pcl_normals(u,v).normal_y) || std::isnan(pcl_normals(u,v).normal_z))
 	  binned[u+cloud.width*v] = get_bin_float_empty(this->orient_bin_centers_x_.size()); // empty vector
 	else {
 	  binned[u+cloud.width*v] = get_bin_float_xyz(pcl_normals(u,v).normal_x, pcl_normals(u,v).normal_y, pcl_normals(u,v).normal_z, this->orient_bin_centers_x_, this->orient_bin_centers_y_, this->orient_bin_centers_z_);
@@ -578,9 +577,9 @@ void write_feats(std::string &output_file, DescriptorSet &descriptor_set, Finddd
 
   for(int ii=0;ii<descriptor_set.num;ii++)
   {
-    if( (!isnan(descriptor_set.descriptors[ii].point3d.x) &&
-	 !isnan(descriptor_set.descriptors[ii].point3d.y) &&
-	 !isnan(descriptor_set.descriptors[ii].point3d.z)) ||
+    if( (!std::isnan(descriptor_set.descriptors[ii].point3d.x) &&
+	 !std::isnan(descriptor_set.descriptors[ii].point3d.y) &&
+	 !std::isnan(descriptor_set.descriptors[ii].point3d.z)) ||
 	conf.keep_nan_points)
     {
       if(conf.save_in_ascii) write_point_ascii(pf, descriptor_set.descriptors[ii]);
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3a1ba87d055a1ecd62562db2903a991856e917f0
--- /dev/null
+++ b/test/CMakeLists.txt
@@ -0,0 +1,20 @@
+INCLUDE_DIRECTORIES(${GTEST_INCLUDE_DIRS})
+INCLUDE_DIRECTORIES(${GMOCK_INCLUDE_DIRS})
+
+INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)
+
+FIND_PACKAGE(PCL 1.3 REQUIRED COMPONENTS common io features )
+INCLUDE_DIRECTORIES(${PCL_INCLUDE_DIRS})
+LINK_DIRECTORIES(${PCL_LIBRARY_DIRS})
+ADD_DEFINITIONS(${PCL_DEFINITIONS})
+
+SET(CTEST_CUSTOM_COVERAGE_EXCLUDE *)
+
+ADD_EXECUTABLE(finddd_descriptor_tests finddd_descriptor_test/finddd_descriptor_test.cpp)
+ADD_DEPENDENCIES(finddd_descriptor_tests googletest)
+
+TARGET_LINK_LIBRARIES(finddd_descriptor_tests ${GTEST_LIBS_DIR}/libgtest.a ${GTEST_LIBS_DIR}/libgtest_main.a)
+TARGET_LINK_LIBRARIES(finddd_descriptor_tests ${GMOCK_LIBS_DIR}/libgmock.a ${GMOCK_LIBS_DIR}/libgmock_main.a)
+TARGET_LINK_LIBRARIES(finddd_descriptor_tests ${Boost_LIBRARIES} ${PCL_COMMON_LIBRARIES} ${PCL_IO_LIBRARIES} ${PCL_FEATURES_LIBRARIES})
+
+ADD_TEST(NAME FindddDescriptorTest COMMAND finddd_descriptor_tests)
diff --git a/test/finddd_descriptor_test/finddd_descriptor_test.cpp b/test/finddd_descriptor_test/finddd_descriptor_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..26b59ea8b6e9327cbbac25d21afc3676cf8cbfa1
--- /dev/null
+++ b/test/finddd_descriptor_test/finddd_descriptor_test.cpp
@@ -0,0 +1,30 @@
+// finddd_descriptor_test.cpp
+#include "finddd_descriptor.hpp"
+#include <gtest/gtest.h>
+ 
+TEST(P3DPointTest, EmptyConstructorTest) { 
+    P3D point;
+    ASSERT_EQ(0.0f, point.x);
+    ASSERT_EQ(0.0f, point.y);
+    ASSERT_EQ(0.0f, point.z);
+}
+ 
+TEST(P3DPointTest, NonEmptyConstructorTest) { 
+    P3D point(3.0f, 4.0f, -45.0f);
+    ASSERT_EQ(3.0f, point.x);
+    ASSERT_EQ(4.0f, point.y);
+    ASSERT_EQ(-45.0f, point.z);
+}
+ 
+
+
+//TEST(mutexTest, try_enterFailure) { 
+//    CMutex mutex;
+//    mutex.enter();
+//    ASSERT_FALSE(mutex.try_enter());
+//}
+ 
+int main(int argc, char **argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
diff --git a/test/gtest/CMakeLists.txt b/test/gtest/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e0e211ee8db34874d957991e2d0ce3711561839f
--- /dev/null
+++ b/test/gtest/CMakeLists.txt
@@ -0,0 +1,29 @@
+cmake_minimum_required(VERSION 2.8.8)
+project(gtest_builder C CXX)
+include(ExternalProject)
+
+ExternalProject_Add(googletest
+    GIT_REPOSITORY https://github.com/google/googletest.git
+    GIT_TAG v1.8.x
+    CMAKE_ARGS -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG:PATH=DebugLibs
+               -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE:PATH=ReleaseLibs
+               -DCMAKE_CXX_FLAGS=${MSVC_COMPILER_DEFS}
+               -Dgtest_force_shared_crt=ON
+               -DBUILD_GTEST=ON
+     PREFIX "${CMAKE_CURRENT_BINARY_DIR}"
+# Disable install step
+    INSTALL_COMMAND ""
+)
+
+# Specify include dir
+ExternalProject_Get_Property(googletest source_dir)
+set(GTEST_INCLUDE_DIRS ${source_dir}/googletest/include PARENT_SCOPE)
+set(GMOCK_INCLUDE_DIRS  ${source_dir}/googlemock/include PARENT_SCOPE)
+
+# Specify MainTest's link libraries
+ExternalProject_Get_Property(googletest binary_dir)
+set(GTEST_LIBS_DIR ${binary_dir}/googlemock/gtest PARENT_SCOPE)
+set(GMOCK_LIBS_DIR ${binary_dir}/googlemock PARENT_SCOPE)
+
+
+