diff --git a/.gitignore b/.gitignore
index 110095e942156cfff6256feaa36cb9fdf23886c3..4712ea21f1dffd034d8d0882f65ffa22fd4fa082 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,6 @@
 etc/
+tmp/
+bkp/
 build-*/
 build_*/
 dataset_*/
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 66f7191ebaedcb97ce2427d6667aea74274f64d9..92b25263c4a7811b53f4567b90aee79c426a7a73 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -146,15 +146,17 @@ if(BGS_PYTHON_SUPPORT)
   message(STATUS "NUMPY_INCLUDE_DIR: ${NUMPY_INCLUDE_DIR}\n")
 endif()
 
-#file(GLOB main src/Main.cpp src/FrameProcessor.cpp src/PreProcessor.cpp src/VideoAnalysis.cpp src/VideoCapture.cpp)
 file(GLOB main_src src/*.cpp src/*.c)
 file(GLOB main_inc src/*.h src/*.hpp)
 
-file(GLOB_RECURSE analysis_src src/package_analysis/*.cpp src/package_analysis/*.c)
-file(GLOB_RECURSE analysis_inc src/package_analysis/*.h src/package_analysis/*.hpp)
+file(GLOB_RECURSE utils_src src/utils/*.cpp src/utils/*.c)
+file(GLOB_RECURSE utils_inc src/utils/*.h src/utils/*.hpp)
 
-file(GLOB_RECURSE bgs_src src/package_bgs/*.cpp src/package_bgs/*.c)
-file(GLOB_RECURSE bgs_inc src/package_bgs/*.h src/package_bgs/*.hpp)
+file(GLOB_RECURSE tools_src src/tools/*.cpp src/tools/*.c)
+file(GLOB_RECURSE tools_inc src/tools/*.h src/tools/*.hpp)
+
+file(GLOB_RECURSE bgs_src src/algorithms/*.cpp src/algorithms/*.c)
+file(GLOB_RECURSE bgs_inc src/algorithms/*.h src/algorithms/*.hpp)
 
 include_directories(${CMAKE_CURRENT_SOURCE_DIR})
 include_directories(${OpenCV_INCLUDE_DIRS})
@@ -171,11 +173,11 @@ endif()
 
 # GMG is not available in older OpenCV versions
 if(${OpenCV_VERSION} VERSION_LESS 2.4.3)
-  file(GLOB gmg src/package_bgs/GMG.cpp)
+  file(GLOB gmg src/algorithms/GMG.cpp)
   list(REMOVE_ITEM bgs_src ${gmg})
 endif()
 
-add_library(bgslibrary_core SHARED ${bgs_src} ${analysis_src} ${bgs_inc} ${analysis_inc})
+add_library(bgslibrary_core SHARED ${bgs_src} ${tools_src} ${utils_src} ${bgs_inc} ${tools_inc} ${utils_inc})
 # generates the export header bgslibrary_core_EXPORTS.h automatically
 include(GenerateExportHeader)
 GENERATE_EXPORT_HEADER(bgslibrary_core
@@ -184,11 +186,11 @@ GENERATE_EXPORT_HEADER(bgslibrary_core
     EXPORT_FILE_NAME bgslibrary_core_EXPORTS.h
     STATIC_DEFINE BGSLIBRARY_CORE_EXPORTS_BUILT_AS_STATIC)
 target_link_libraries(bgslibrary_core ${OpenCV_LIBS})
-set_property(TARGET bgslibrary_core PROPERTY PUBLIC_HEADER ${bgs_inc})
+set_property(TARGET bgslibrary_core PROPERTY PUBLIC_HEADER ${bgs_inc} ${tools_inc} ${utils_inc})
 
 if(BGS_PYTHON_SUPPORT)
-  #add_library(bgs_python SHARED ${bgs_src} ${analysis_src})
-  #pybind11_add_module(bgs_python ${bgs_src} ${analysis_src})
+  #add_library(bgs_python SHARED ${bgs_src} ${tools_src})
+  #pybind11_add_module(bgs_python ${bgs_src} ${tools_src})
   pybind11_add_module(bgs_python ${bgs_python_src} ${bgs_python_inc})
 
   target_link_libraries(bgs_python PRIVATE bgslibrary_core ${OpenCV_LIBS} ${PYTHON_LIBRARY} pybind11::module)
@@ -247,7 +249,7 @@ install(TARGETS bgslibrary_core
   RUNTIME DESTINATION bin COMPONENT app
   LIBRARY DESTINATION lib COMPONENT runtime
   ARCHIVE DESTINATION lib COMPONENT runtime
-  PUBLIC_HEADER DESTINATION include/package_bgs COMPONENT dev
+  PUBLIC_HEADER DESTINATION include/bgslibrary COMPONENT dev
   FRAMEWORK DESTINATION "/Library/Frameworks"
 )
 
diff --git a/config/FrameProcessor.xml b/config/FrameProcessor.xml
index d510afee74e184043b51fd312b2fba2f52d4ada9..fe71fa44d8115acf8fe56e2cb5642942f7666a4d 100644
--- a/config/FrameProcessor.xml
+++ b/config/FrameProcessor.xml
@@ -7,8 +7,10 @@
 <enableStaticFrameDifference>0</enableStaticFrameDifference>
 <enableWeightedMovingMean>0</enableWeightedMovingMean>
 <enableWeightedMovingVariance>0</enableWeightedMovingVariance>
-<enableMixtureOfGaussianV2>0</enableMixtureOfGaussianV2>
 <enableAdaptiveBackgroundLearning>0</enableAdaptiveBackgroundLearning>
+<enableAdaptiveSelectiveBackgroundLearning>0</enableAdaptiveSelectiveBackgroundLearning>
+<enableMixtureOfGaussianV2>0</enableMixtureOfGaussianV2>
+<enableMixtureOfGaussianV1>0</enableMixtureOfGaussianV1>
 <enableKNN>0</enableKNN>
 <enableDPAdaptiveMedian>0</enableDPAdaptiveMedian>
 <enableDPGrimsonGMM>0</enableDPGrimsonGMM>
@@ -43,4 +45,5 @@
 <enableTwoPoints>0</enableTwoPoints>
 <enableViBe>0</enableViBe>
 <enableCodeBook>0</enableCodeBook>
+<enableGMG>0</enableGMG>
 </opencv_storage>
diff --git a/config/VideoCapture.xml b/config/VideoCapture.xml
index 60dd9aa81010d78759f5986f0aa5a2876da25f63..bddc163b2ab83c3a9965a5e1c2730bc3a9c48b4b 100644
--- a/config/VideoCapture.xml
+++ b/config/VideoCapture.xml
@@ -9,5 +9,6 @@
 <roi_y0>0</roi_y0>
 <roi_x1>0</roi_x1>
 <roi_y1>0</roi_y1>
+<showFPS>1</showFPS>
 <showOutput>1</showOutput>
 </opencv_storage>
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index c010f25a0d436c647178268f6e5c965a65edcf1b..0dc3d0a1f5f8e869fa92a9b61d963ce6de5f98af 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -79,22 +79,25 @@ endif()
 file(GLOB demo Demo.cpp)
 file(GLOB demo2 Demo2.cpp)
 
-file(GLOB_RECURSE analysis_src ../src/package_analysis/*.cpp ../src/package_analysis/*.c)
-file(GLOB_RECURSE analysis_inc ../src/package_analysis/*.h ../src/package_analysis/*.hpp)
+file(GLOB_RECURSE tools_src ../src/tools/*.cpp ../src/tools/*.c)
+file(GLOB_RECURSE tools_inc ../src/tools/*.h ../src/tools/*.hpp)
 
-file(GLOB_RECURSE bgs_src ../src/package_bgs/*.cpp ../src/package_bgs/*.c)
-file(GLOB_RECURSE bgs_inc ../src/package_bgs/*.h ../src/package_bgs/*.hpp)
+file(GLOB_RECURSE utils_src ../src/utils/*.cpp ../src/utils/*.c)
+file(GLOB_RECURSE utils_inc ../src/utils/*.h ../src/utils/*.hpp)
+
+file(GLOB_RECURSE bgs_src ../src/algorithms/*.cpp ../src/algorithms/*.c)
+file(GLOB_RECURSE bgs_inc ../src/algorithms/*.h ../src/algorithms/*.hpp)
 
 include_directories(${CMAKE_CURRENT_SOURCE_DIR})
 include_directories(${OpenCV_INCLUDE_DIRS})
 
 # GMG is not available in older OpenCV versions
 if(${OpenCV_VERSION} VERSION_LESS 2.4.3)
-  file(GLOB gmg ../src/package_bgs/GMG.cpp)
+  file(GLOB gmg ../src/algorithms/GMG.cpp)
   list(REMOVE_ITEM bgs_src ${gmg})
 endif()
 
-add_library(bgslibrary_core SHARED ${bgs_src} ${analysis_src} ${bgs_inc} ${analysis_inc})
+add_library(bgslibrary_core SHARED ${bgs_src} ${tools_src} ${utils_src} ${bgs_inc} ${tools_inc} ${utils_inc})
 # generates the export header bgslibrary_core_EXPORTS.h automatically
 include(GenerateExportHeader)
 GENERATE_EXPORT_HEADER(bgslibrary_core
@@ -103,7 +106,7 @@ GENERATE_EXPORT_HEADER(bgslibrary_core
     EXPORT_FILE_NAME bgslibrary_core_EXPORTS.h
     STATIC_DEFINE BGSLIBRARY_CORE_EXPORTS_BUILT_AS_STATIC)
 target_link_libraries(bgslibrary_core ${OpenCV_LIBS})
-set_property(TARGET bgslibrary_core PROPERTY PUBLIC_HEADER ${bgs_inc} ${analysis_inc})
+set_property(TARGET bgslibrary_core PROPERTY PUBLIC_HEADER ${bgs_inc} ${tools_inc} ${utils_inc})
 
 #if(WIN32)
 #  # set_property(TARGET bgslibrary_core PROPERTY SUFFIX ".lib")
diff --git a/examples/Demo.cpp b/examples/Demo.cpp
index 36c63c9d12bf66469c195daaac2e09ddc9f65ff2..6b081b74e4732a9acdeeaa4ddbb974684f3c8aa1 100644
--- a/examples/Demo.cpp
+++ b/examples/Demo.cpp
@@ -2,7 +2,7 @@
 #include <vector>
 #include <opencv2/opencv.hpp>
 
-#include "../src/package_bgs/bgslibrary.h"
+#include "../src/algorithms/algorithms.h"
 
 #if CV_MAJOR_VERSION >= 4
 #define CV_CAP_PROP_POS_FRAMES cv::CAP_PROP_POS_FRAMES
diff --git a/examples/Demo2.cpp b/examples/Demo2.cpp
index 1d02d30016109831ccb1620e4ba878b06a9ca2f6..544c6aeb7932abd2d51978421ef9b5f73e19b68c 100644
--- a/examples/Demo2.cpp
+++ b/examples/Demo2.cpp
@@ -2,7 +2,7 @@
 #include <vector>
 #include <opencv2/opencv.hpp>
 
-#include "../src/package_bgs/bgslibrary.h"
+#include "../src/algorithms/algorithms.h"
 
 #if CV_MAJOR_VERSION >= 4
 #define CV_LOAD_IMAGE_COLOR cv::IMREAD_COLOR
diff --git a/gui/qt/CMakeLists.txt b/gui/qt/CMakeLists.txt
index 07073e0f17bf4b3123fe60967d113dc613ce8287..7f008f6e32d9e131273e00b1a79bf8aef9ba5f22 100644
--- a/gui/qt/CMakeLists.txt
+++ b/gui/qt/CMakeLists.txt
@@ -53,18 +53,23 @@ if(OpenCV_FOUND)
   message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")
 endif()
 
-file(GLOB main bgslibrary_gui.cpp mainwindow.cpp qt_utils.cpp texteditor.cpp)
+file(GLOB main_src *.cpp *.c)
+file(GLOB main_inc *.h *.hpp)
 
-file(GLOB_RECURSE analysis_src ../../src/package_analysis/*.cpp)
-file(GLOB_RECURSE analysis_inc ../../src/package_analysis/*.h)
-file(GLOB_RECURSE bgs_src ../../src/package_bgs/*.cpp ../../src/package_bgs/*.c)
-file(GLOB_RECURSE bgs_inc ../../src/package_bgs/*.h)
+file(GLOB_RECURSE tools_src ../../src/tools/*.cpp ../../src/tools/*.c)
+file(GLOB_RECURSE tools_inc ../../src/tools/*.h ../../src/tools/*.hpp)
+
+file(GLOB_RECURSE utils_src ../../src/utils/*.cpp ../../src/utils/*.c)
+file(GLOB_RECURSE utils_inc ../../src/utils/*.h ../../src/utils/*.hpp)
+
+file(GLOB_RECURSE bgs_src ../../src/algorithms/*.cpp ../../src/algorithms/*.c)
+file(GLOB_RECURSE bgs_inc ../../src/algorithms/*.h)
 
 include_directories(${CMAKE_SOURCE_DIR} ${OpenCV_INCLUDE_DIRS})
 
-add_library(libbgs STATIC ${bgs_src} ${analysis_src})
+add_library(libbgs STATIC ${bgs_src} ${tools_src} ${utils_src} ${bgs_inc} ${tools_inc} ${utils_inc})
 target_link_libraries(libbgs ${OpenCV_LIBS})
-set_property(TARGET libbgs PROPERTY PUBLIC_HEADER ${bgs_inc} ${analysis_inc})
+set_property(TARGET libbgs PROPERTY PUBLIC_HEADER ${bgs_inc} ${tools_inc} ${utils_inc})
 
 if(WIN32)
   # set_property(TARGET libbgs PROPERTY SUFFIX ".lib")
@@ -73,7 +78,7 @@ else()
 endif()
 
 # Tell CMake to create the bgslibrary_gui executable
-add_executable(bgslibrary_gui ${main} ${app_RESOURCES_RCC})
+add_executable(bgslibrary_gui ${main_src} ${main_inc} ${app_RESOURCES_RCC})
 
 # Use the Widgets module from Qt 5.
 target_link_libraries(bgslibrary_gui Qt5::Widgets ${OpenCV_LIBS} libbgs)
diff --git a/gui/qt/bgslibrary_gui.pro b/gui/qt/bgslibrary_gui.pro
index 442a57b4b89f5dc00ec383013f57701c6cbf879d..53caf04b50b841cedfaa92d8725824370ccabef7 100644
--- a/gui/qt/bgslibrary_gui.pro
+++ b/gui/qt/bgslibrary_gui.pro
@@ -84,218 +84,221 @@ SOURCES += bgslibrary_gui.cpp\
     mainwindow.cpp \
     qt_utils.cpp \
     texteditor.cpp \
-    ../../src/package_analysis/ForegroundMaskAnalysis.cpp \
-    ../../src/package_analysis/PerformanceUtils.cpp \
-    ../../src/package_analysis/PixelUtils.cpp \
-    ../../src/package_bgs/dp/AdaptiveMedianBGS.cpp \
-    ../../src/package_bgs/dp/Eigenbackground.cpp \
-    ../../src/package_bgs/dp/Error.cpp \
-    ../../src/package_bgs/dp/GrimsonGMM.cpp \
-    ../../src/package_bgs/dp/Image.cpp \
-    ../../src/package_bgs/dp/MeanBGS.cpp \
-    ../../src/package_bgs/dp/PratiMediodBGS.cpp \
-    ../../src/package_bgs/dp/TextureBGS.cpp \
-    ../../src/package_bgs/dp/WrenGA.cpp \
-    ../../src/package_bgs/dp/ZivkovicAGMM.cpp \
-    ../../src/package_bgs/IMBS/IMBS.cpp \
-    ../../src/package_bgs/KDE/KernelTable.cpp \
-    ../../src/package_bgs/KDE/NPBGmodel.cpp \
-    ../../src/package_bgs/KDE/NPBGSubtractor.cpp \
-    ../../src/package_bgs/lb/BGModel.cpp \
-    ../../src/package_bgs/lb/BGModelFuzzyGauss.cpp \
-    ../../src/package_bgs/lb/BGModelFuzzySom.cpp \
-    ../../src/package_bgs/lb/BGModelGauss.cpp \
-    ../../src/package_bgs/lb/BGModelMog.cpp \
-    ../../src/package_bgs/lb/BGModelSom.cpp \
-    ../../src/package_bgs/LBP_MRF/graph.cpp \
-    ../../src/package_bgs/LBP_MRF/maxflow.cpp \
-    ../../src/package_bgs/LBP_MRF/MEDefs.cpp \
-    ../../src/package_bgs/LBP_MRF/MEHistogram.cpp \
-    ../../src/package_bgs/LBP_MRF/MEImage.cpp \
-    ../../src/package_bgs/LBP_MRF/MotionDetection.cpp \
-    ../../src/package_bgs/LBSP/BackgroundSubtractorLBSP.cpp \
-    ../../src/package_bgs/LBSP/BackgroundSubtractorLBSP_.cpp \
-    ../../src/package_bgs/LBSP/BackgroundSubtractorLOBSTER.cpp \
-    ../../src/package_bgs/LBSP/BackgroundSubtractorPAWCS.cpp \
-    ../../src/package_bgs/LBSP/BackgroundSubtractorSuBSENSE.cpp \
-    ../../src/package_bgs/LBSP/LBSP.cpp \
-    ../../src/package_bgs/LBSP/LBSP_.cpp \
-    ../../src/package_bgs/MultiLayer/blob.cpp \
-    ../../src/package_bgs/MultiLayer/BlobExtraction.cpp \
-    ../../src/package_bgs/MultiLayer/BlobResult.cpp \
-    ../../src/package_bgs/MultiLayer/CMultiLayerBGS.cpp \
-    ../../src/package_bgs/MultiLayer/LocalBinaryPattern.cpp \
-    ../../src/package_bgs/PBAS/PBAS.cpp \
-    ../../src/package_bgs/SigmaDelta/sdLaMa091.cpp \
-    ../../src/package_bgs/T2F/FuzzyUtils.cpp \
-    ../../src/package_bgs/T2F/MRF.cpp \
-    ../../src/package_bgs/T2F/T2FGMM.cpp \
-    ../../src/package_bgs/T2F/T2FMRF.cpp \
-    ../../src/package_bgs/TwoPoints/two_points.cpp \
-    ../../src/package_bgs/ViBe/vibe-background-sequential.cpp \
-    ../../src/package_bgs/VuMeter/TBackground.cpp \
-    ../../src/package_bgs/VuMeter/TBackgroundVuMeter.cpp \
-    ../../src/package_bgs/AdaptiveBackgroundLearning.cpp \
-    ../../src/package_bgs/AdaptiveSelectiveBackgroundLearning.cpp \
-    ../../src/package_bgs/DPAdaptiveMedian.cpp \
-    ../../src/package_bgs/DPEigenbackground.cpp \
-    ../../src/package_bgs/DPGrimsonGMM.cpp \
-    ../../src/package_bgs/DPMean.cpp \
-    ../../src/package_bgs/DPPratiMediod.cpp \
-    ../../src/package_bgs/DPTexture.cpp \
-    ../../src/package_bgs/DPWrenGA.cpp \
-    ../../src/package_bgs/DPZivkovicAGMM.cpp \
-    ../../src/package_bgs/FrameDifference.cpp \
-    ../../src/package_bgs/FuzzyChoquetIntegral.cpp \
-    ../../src/package_bgs/FuzzySugenoIntegral.cpp \
-    ../../src/package_bgs/GMG.cpp \
-    ../../src/package_bgs/IndependentMultimodal.cpp \
-    ../../src/package_bgs/KDE.cpp \
-    ../../src/package_bgs/KNN.cpp \
-    ../../src/package_bgs/LBAdaptiveSOM.cpp \
-    ../../src/package_bgs/LBFuzzyAdaptiveSOM.cpp \
-    ../../src/package_bgs/LBFuzzyGaussian.cpp \
-    ../../src/package_bgs/LBMixtureOfGaussians.cpp \
-    ../../src/package_bgs/LBP_MRF.cpp \
-    ../../src/package_bgs/LBSimpleGaussian.cpp \
-    ../../src/package_bgs/LOBSTER.cpp \
-    ../../src/package_bgs/MixtureOfGaussianV1.cpp \
-    ../../src/package_bgs/MixtureOfGaussianV2.cpp \
-    ../../src/package_bgs/MultiCue.cpp \
-    ../../src/package_bgs/MultiLayer.cpp \
-    ../../src/package_bgs/PAWCS.cpp \
-    ../../src/package_bgs/PixelBasedAdaptiveSegmenter.cpp \
-    ../../src/package_bgs/SigmaDelta.cpp \
-    ../../src/package_bgs/StaticFrameDifference.cpp \
-    ../../src/package_bgs/SuBSENSE.cpp \
-    ../../src/package_bgs/T2FGMM_UM.cpp \
-    ../../src/package_bgs/T2FGMM_UV.cpp \
-    ../../src/package_bgs/T2FMRF_UM.cpp \
-    ../../src/package_bgs/T2FMRF_UV.cpp \
-    ../../src/package_bgs/TwoPoints.cpp \
-    ../../src/package_bgs/ViBe.cpp \
-    ../../src/package_bgs/VuMeter.cpp \
-    ../../src/package_bgs/WeightedMovingMean.cpp \
-    ../../src/package_bgs/WeightedMovingVariance.cpp \
-    ../../src/package_bgs/CodeBook.cpp
-    ../../src/package_bgs/_template_/MyBGS.cpp \
+    ../../src/tools/ForegroundMaskAnalysis.cpp \
+    ../../src/tools/PerformanceUtils.cpp \
+    ../../src/tools/PixelUtils.cpp \
+    ../../src/algorithms/dp/AdaptiveMedianBGS.cpp \
+    ../../src/algorithms/dp/Eigenbackground.cpp \
+    ../../src/algorithms/dp/Error.cpp \
+    ../../src/algorithms/dp/GrimsonGMM.cpp \
+    ../../src/algorithms/dp/Image.cpp \
+    ../../src/algorithms/dp/MeanBGS.cpp \
+    ../../src/algorithms/dp/PratiMediodBGS.cpp \
+    ../../src/algorithms/dp/TextureBGS.cpp \
+    ../../src/algorithms/dp/WrenGA.cpp \
+    ../../src/algorithms/dp/ZivkovicAGMM.cpp \
+    ../../src/algorithms/IMBS/IMBS.cpp \
+    ../../src/algorithms/KDE/KernelTable.cpp \
+    ../../src/algorithms/KDE/NPBGmodel.cpp \
+    ../../src/algorithms/KDE/NPBGSubtractor.cpp \
+    ../../src/algorithms/lb/BGModel.cpp \
+    ../../src/algorithms/lb/BGModelFuzzyGauss.cpp \
+    ../../src/algorithms/lb/BGModelFuzzySom.cpp \
+    ../../src/algorithms/lb/BGModelGauss.cpp \
+    ../../src/algorithms/lb/BGModelMog.cpp \
+    ../../src/algorithms/lb/BGModelSom.cpp \
+    ../../src/algorithms/LBP_MRF/graph.cpp \
+    ../../src/algorithms/LBP_MRF/maxflow.cpp \
+    ../../src/algorithms/LBP_MRF/MEDefs.cpp \
+    ../../src/algorithms/LBP_MRF/MEHistogram.cpp \
+    ../../src/algorithms/LBP_MRF/MEImage.cpp \
+    ../../src/algorithms/LBP_MRF/MotionDetection.cpp \
+    ../../src/algorithms/LBSP/BackgroundSubtractorLBSP.cpp \
+    ../../src/algorithms/LBSP/BackgroundSubtractorLBSP_.cpp \
+    ../../src/algorithms/LBSP/BackgroundSubtractorLOBSTER.cpp \
+    ../../src/algorithms/LBSP/BackgroundSubtractorPAWCS.cpp \
+    ../../src/algorithms/LBSP/BackgroundSubtractorSuBSENSE.cpp \
+    ../../src/algorithms/LBSP/LBSP.cpp \
+    ../../src/algorithms/LBSP/LBSP_.cpp \
+    ../../src/algorithms/MultiLayer/blob.cpp \
+    ../../src/algorithms/MultiLayer/BlobExtraction.cpp \
+    ../../src/algorithms/MultiLayer/BlobResult.cpp \
+    ../../src/algorithms/MultiLayer/CMultiLayerBGS.cpp \
+    ../../src/algorithms/MultiLayer/LocalBinaryPattern.cpp \
+    ../../src/algorithms/PBAS/PBAS.cpp \
+    ../../src/algorithms/SigmaDelta/sdLaMa091.cpp \
+    ../../src/algorithms/T2F/FuzzyUtils.cpp \
+    ../../src/algorithms/T2F/MRF.cpp \
+    ../../src/algorithms/T2F/T2FGMM.cpp \
+    ../../src/algorithms/T2F/T2FMRF.cpp \
+    ../../src/algorithms/TwoPoints/two_points.cpp \
+    ../../src/algorithms/ViBe/vibe-background-sequential.cpp \
+    ../../src/algorithms/VuMeter/TBackground.cpp \
+    ../../src/algorithms/VuMeter/TBackgroundVuMeter.cpp \
+    ../../src/algorithms/AdaptiveBackgroundLearning.cpp \
+    ../../src/algorithms/AdaptiveSelectiveBackgroundLearning.cpp \
+    ../../src/algorithms/DPAdaptiveMedian.cpp \
+    ../../src/algorithms/DPEigenbackground.cpp \
+    ../../src/algorithms/DPGrimsonGMM.cpp \
+    ../../src/algorithms/DPMean.cpp \
+    ../../src/algorithms/DPPratiMediod.cpp \
+    ../../src/algorithms/DPTexture.cpp \
+    ../../src/algorithms/DPWrenGA.cpp \
+    ../../src/algorithms/DPZivkovicAGMM.cpp \
+    ../../src/algorithms/FrameDifference.cpp \
+    ../../src/algorithms/FuzzyChoquetIntegral.cpp \
+    ../../src/algorithms/FuzzySugenoIntegral.cpp \
+    ../../src/algorithms/GMG.cpp \
+    ../../src/algorithms/IndependentMultimodal.cpp \
+    ../../src/algorithms/KDE.cpp \
+    ../../src/algorithms/KNN.cpp \
+    ../../src/algorithms/LBAdaptiveSOM.cpp \
+    ../../src/algorithms/LBFuzzyAdaptiveSOM.cpp \
+    ../../src/algorithms/LBFuzzyGaussian.cpp \
+    ../../src/algorithms/LBMixtureOfGaussians.cpp \
+    ../../src/algorithms/LBP_MRF.cpp \
+    ../../src/algorithms/LBSimpleGaussian.cpp \
+    ../../src/algorithms/LOBSTER.cpp \
+    ../../src/algorithms/MixtureOfGaussianV1.cpp \
+    ../../src/algorithms/MixtureOfGaussianV2.cpp \
+    ../../src/algorithms/MultiCue.cpp \
+    ../../src/algorithms/MultiLayer.cpp \
+    ../../src/algorithms/PAWCS.cpp \
+    ../../src/algorithms/PixelBasedAdaptiveSegmenter.cpp \
+    ../../src/algorithms/SigmaDelta.cpp \
+    ../../src/algorithms/StaticFrameDifference.cpp \
+    ../../src/algorithms/SuBSENSE.cpp \
+    ../../src/algorithms/T2FGMM_UM.cpp \
+    ../../src/algorithms/T2FGMM_UV.cpp \
+    ../../src/algorithms/T2FMRF_UM.cpp \
+    ../../src/algorithms/T2FMRF_UV.cpp \
+    ../../src/algorithms/TwoPoints.cpp \
+    ../../src/algorithms/ViBe.cpp \
+    ../../src/algorithms/VuMeter.cpp \
+    ../../src/algorithms/WeightedMovingMean.cpp \
+    ../../src/algorithms/WeightedMovingVariance.cpp \
+    ../../src/algorithms/CodeBook.cpp
+    ../../src/algorithms/_template_/MyBGS.cpp \
 
 HEADERS  += mainwindow.h \
     qt_utils.h \
     texteditor.h \
-    ../../src/package_analysis/ForegroundMaskAnalysis.h \
-    ../../src/package_analysis/PerformanceUtils.h \
-    ../../src/package_analysis/PixelUtils.h \
-    ../../src/package_bgs/dp/AdaptiveMedianBGS.h \
-    ../../src/package_bgs/dp/Bgs.h \
-    ../../src/package_bgs/dp/BgsParams.h \
-    ../../src/package_bgs/dp/Eigenbackground.h \
-    ../../src/package_bgs/dp/Error.h \
-    ../../src/package_bgs/dp/GrimsonGMM.h \
-    ../../src/package_bgs/dp/Image.h \
-    ../../src/package_bgs/dp/MeanBGS.h \
-    ../../src/package_bgs/dp/PratiMediodBGS.h \
-    ../../src/package_bgs/dp/TextureBGS.h \
-    ../../src/package_bgs/dp/WrenGA.h \
-    ../../src/package_bgs/dp/ZivkovicAGMM.h \
-    ../../src/package_bgs/IMBS/IMBS.hpp \
-    ../../src/package_bgs/KDE/KernelTable.h \
-    ../../src/package_bgs/KDE/NPBGmodel.h \
-    ../../src/package_bgs/KDE/NPBGSubtractor.h \
-    ../../src/package_bgs/lb/BGModel.h \
-    ../../src/package_bgs/lb/BGModelFuzzyGauss.h \
-    ../../src/package_bgs/lb/BGModelFuzzySom.h \
-    ../../src/package_bgs/lb/BGModelGauss.h \
-    ../../src/package_bgs/lb/BGModelMog.h \
-    ../../src/package_bgs/lb/BGModelSom.h \
-    ../../src/package_bgs/lb/Types.h \
-    ../../src/package_bgs/LBP_MRF/block.h \
-    ../../src/package_bgs/LBP_MRF/graph.h \
-    ../../src/package_bgs/LBP_MRF/MEDefs.hpp \
-    ../../src/package_bgs/LBP_MRF/MEHistogram.hpp \
-    ../../src/package_bgs/LBP_MRF/MEImage.hpp \
-    ../../src/package_bgs/LBP_MRF/MotionDetection.hpp \
-    ../../src/package_bgs/LBSP/BackgroundSubtractorLBSP.h \
-    ../../src/package_bgs/LBSP/BackgroundSubtractorLBSP_.h \
-    ../../src/package_bgs/LBSP/BackgroundSubtractorLOBSTER.h \
-    ../../src/package_bgs/LBSP/BackgroundSubtractorPAWCS.h \
-    ../../src/package_bgs/LBSP/BackgroundSubtractorSuBSENSE.h \
-    ../../src/package_bgs/LBSP/DistanceUtils.h \
-    ../../src/package_bgs/LBSP/LBSP.h \
-    ../../src/package_bgs/LBSP/LBSP_.h \
-    ../../src/package_bgs/LBSP/RandUtils.h \
-    ../../src/package_bgs/MultiLayer/BackgroundSubtractionAPI.h \
-    ../../src/package_bgs/MultiLayer/BGS.h \
-    ../../src/package_bgs/MultiLayer/blob.h \
-    ../../src/package_bgs/MultiLayer/BlobExtraction.h \
-    ../../src/package_bgs/MultiLayer/BlobLibraryConfiguration.h \
-    ../../src/package_bgs/MultiLayer/BlobResult.h \
-    ../../src/package_bgs/MultiLayer/CMultiLayerBGS.h \
-    ../../src/package_bgs/MultiLayer/LocalBinaryPattern.h \
-    ../../src/package_bgs/MultiLayer/OpenCvDataConversion.h \
-    ../../src/package_bgs/MultiLayer/OpenCvLegacyIncludes.h \
-    ../../src/package_bgs/PBAS/PBAS.h \
-    ../../src/package_bgs/SigmaDelta/sdLaMa091.h \
-    ../../src/package_bgs/T2F/FuzzyUtils.h \
-    ../../src/package_bgs/T2F/MRF.h \
-    ../../src/package_bgs/T2F/T2FGMM.h \
-    ../../src/package_bgs/T2F/T2FMRF.h \
-    ../../src/package_bgs/TwoPoints/two_points.h \
-    ../../src/package_bgs/ViBe/vibe-background-sequential.h \
-    ../../src/package_bgs/VuMeter/TBackground.h \
-    ../../src/package_bgs/VuMeter/TBackgroundVuMeter.h \
-    ../../src/package_bgs/AdaptiveBackgroundLearning.h \
-    ../../src/package_bgs/AdaptiveSelectiveBackgroundLearning.h \
-    ../../src/package_bgs/bgslibrary.h \
-    ../../src/package_bgs/DPAdaptiveMedian.h \
-    ../../src/package_bgs/DPEigenbackground.h \
-    ../../src/package_bgs/DPGrimsonGMM.h \
-    ../../src/package_bgs/DPMean.h \
-    ../../src/package_bgs/DPPratiMediod.h \
-    ../../src/package_bgs/DPTexture.h \
-    ../../src/package_bgs/DPWrenGA.h \
-    ../../src/package_bgs/DPZivkovicAGMM.h \
-    ../../src/package_bgs/FrameDifference.h \
-    ../../src/package_bgs/FuzzyChoquetIntegral.h \
-    ../../src/package_bgs/FuzzySugenoIntegral.h \
-    ../../src/package_bgs/GMG.h \
-    ../../src/package_bgs/IBGS.h \
-    ../../src/package_bgs/IndependentMultimodal.h \
-    ../../src/package_bgs/KDE.h \
-    ../../src/package_bgs/KNN.h \
-    ../../src/package_bgs/LBAdaptiveSOM.h \
-    ../../src/package_bgs/LBFuzzyAdaptiveSOM.h \
-    ../../src/package_bgs/LBFuzzyGaussian.h \
-    ../../src/package_bgs/LBMixtureOfGaussians.h \
-    ../../src/package_bgs/LBP_MRF.h \
-    ../../src/package_bgs/LBSimpleGaussian.h \
-    ../../src/package_bgs/LOBSTER.h \
-    ../../src/package_bgs/MixtureOfGaussianV1.h \
-    ../../src/package_bgs/MixtureOfGaussianV2.h \
-    ../../src/package_bgs/MultiCue.h \
-    ../../src/package_bgs/MultiLayer.h \
-    ../../src/package_bgs/PAWCS.h \
-    ../../src/package_bgs/PixelBasedAdaptiveSegmenter.h \
-    ../../src/package_bgs/SigmaDelta.h \
-    ../../src/package_bgs/StaticFrameDifference.h \
-    ../../src/package_bgs/SuBSENSE.h \
-    ../../src/package_bgs/T2FGMM_UM.h \
-    ../../src/package_bgs/T2FGMM_UV.h \
-    ../../src/package_bgs/T2FMRF_UM.h \
-    ../../src/package_bgs/T2FMRF_UV.h \
-    ../../src/package_bgs/TwoPoints.h \
-    ../../src/package_bgs/ViBe.h \
-    ../../src/package_bgs/VuMeter.h \
-    ../../src/package_bgs/WeightedMovingMean.h \
-    ../../src/package_bgs/WeightedMovingVariance.h \
-    ../../src/package_bgs/CodeBook.h
-    ../../src/package_bgs/_template_/MyBGS.h \
+    ../../src/utils/GenericKeys.h \
+    ../../src/utils/GenericMacros.h \
+    ../../src/utils/ILoadSaveConfig.h \
+    ../../src/tools/ForegroundMaskAnalysis.h \
+    ../../src/tools/PerformanceUtils.h \
+    ../../src/tools/PixelUtils.h \
+    ../../src/algorithms/dp/AdaptiveMedianBGS.h \
+    ../../src/algorithms/dp/Bgs.h \
+    ../../src/algorithms/dp/BgsParams.h \
+    ../../src/algorithms/dp/Eigenbackground.h \
+    ../../src/algorithms/dp/Error.h \
+    ../../src/algorithms/dp/GrimsonGMM.h \
+    ../../src/algorithms/dp/Image.h \
+    ../../src/algorithms/dp/MeanBGS.h \
+    ../../src/algorithms/dp/PratiMediodBGS.h \
+    ../../src/algorithms/dp/TextureBGS.h \
+    ../../src/algorithms/dp/WrenGA.h \
+    ../../src/algorithms/dp/ZivkovicAGMM.h \
+    ../../src/algorithms/IMBS/IMBS.hpp \
+    ../../src/algorithms/KDE/KernelTable.h \
+    ../../src/algorithms/KDE/NPBGmodel.h \
+    ../../src/algorithms/KDE/NPBGSubtractor.h \
+    ../../src/algorithms/lb/BGModel.h \
+    ../../src/algorithms/lb/BGModelFuzzyGauss.h \
+    ../../src/algorithms/lb/BGModelFuzzySom.h \
+    ../../src/algorithms/lb/BGModelGauss.h \
+    ../../src/algorithms/lb/BGModelMog.h \
+    ../../src/algorithms/lb/BGModelSom.h \
+    ../../src/algorithms/lb/Types.h \
+    ../../src/algorithms/LBP_MRF/block.h \
+    ../../src/algorithms/LBP_MRF/graph.h \
+    ../../src/algorithms/LBP_MRF/MEDefs.hpp \
+    ../../src/algorithms/LBP_MRF/MEHistogram.hpp \
+    ../../src/algorithms/LBP_MRF/MEImage.hpp \
+    ../../src/algorithms/LBP_MRF/MotionDetection.hpp \
+    ../../src/algorithms/LBSP/BackgroundSubtractorLBSP.h \
+    ../../src/algorithms/LBSP/BackgroundSubtractorLBSP_.h \
+    ../../src/algorithms/LBSP/BackgroundSubtractorLOBSTER.h \
+    ../../src/algorithms/LBSP/BackgroundSubtractorPAWCS.h \
+    ../../src/algorithms/LBSP/BackgroundSubtractorSuBSENSE.h \
+    ../../src/algorithms/LBSP/DistanceUtils.h \
+    ../../src/algorithms/LBSP/LBSP.h \
+    ../../src/algorithms/LBSP/LBSP_.h \
+    ../../src/algorithms/LBSP/RandUtils.h \
+    ../../src/algorithms/MultiLayer/BackgroundSubtractionAPI.h \
+    ../../src/algorithms/MultiLayer/BGS.h \
+    ../../src/algorithms/MultiLayer/blob.h \
+    ../../src/algorithms/MultiLayer/BlobExtraction.h \
+    ../../src/algorithms/MultiLayer/BlobLibraryConfiguration.h \
+    ../../src/algorithms/MultiLayer/BlobResult.h \
+    ../../src/algorithms/MultiLayer/CMultiLayerBGS.h \
+    ../../src/algorithms/MultiLayer/LocalBinaryPattern.h \
+    ../../src/algorithms/MultiLayer/OpenCvDataConversion.h \
+    ../../src/algorithms/MultiLayer/OpenCvLegacyIncludes.h \
+    ../../src/algorithms/PBAS/PBAS.h \
+    ../../src/algorithms/SigmaDelta/sdLaMa091.h \
+    ../../src/algorithms/T2F/FuzzyUtils.h \
+    ../../src/algorithms/T2F/MRF.h \
+    ../../src/algorithms/T2F/T2FGMM.h \
+    ../../src/algorithms/T2F/T2FMRF.h \
+    ../../src/algorithms/TwoPoints/two_points.h \
+    ../../src/algorithms/ViBe/vibe-background-sequential.h \
+    ../../src/algorithms/VuMeter/TBackground.h \
+    ../../src/algorithms/VuMeter/TBackgroundVuMeter.h \
+    ../../src/algorithms/AdaptiveBackgroundLearning.h \
+    ../../src/algorithms/AdaptiveSelectiveBackgroundLearning.h \
+    ../../src/algorithms/bgslibrary.h \
+    ../../src/algorithms/DPAdaptiveMedian.h \
+    ../../src/algorithms/DPEigenbackground.h \
+    ../../src/algorithms/DPGrimsonGMM.h \
+    ../../src/algorithms/DPMean.h \
+    ../../src/algorithms/DPPratiMediod.h \
+    ../../src/algorithms/DPTexture.h \
+    ../../src/algorithms/DPWrenGA.h \
+    ../../src/algorithms/DPZivkovicAGMM.h \
+    ../../src/algorithms/FrameDifference.h \
+    ../../src/algorithms/FuzzyChoquetIntegral.h \
+    ../../src/algorithms/FuzzySugenoIntegral.h \
+    ../../src/algorithms/GMG.h \
+    ../../src/algorithms/IBGS.h \
+    ../../src/algorithms/IndependentMultimodal.h \
+    ../../src/algorithms/KDE.h \
+    ../../src/algorithms/KNN.h \
+    ../../src/algorithms/LBAdaptiveSOM.h \
+    ../../src/algorithms/LBFuzzyAdaptiveSOM.h \
+    ../../src/algorithms/LBFuzzyGaussian.h \
+    ../../src/algorithms/LBMixtureOfGaussians.h \
+    ../../src/algorithms/LBP_MRF.h \
+    ../../src/algorithms/LBSimpleGaussian.h \
+    ../../src/algorithms/LOBSTER.h \
+    ../../src/algorithms/MixtureOfGaussianV1.h \
+    ../../src/algorithms/MixtureOfGaussianV2.h \
+    ../../src/algorithms/MultiCue.h \
+    ../../src/algorithms/MultiLayer.h \
+    ../../src/algorithms/PAWCS.h \
+    ../../src/algorithms/PixelBasedAdaptiveSegmenter.h \
+    ../../src/algorithms/SigmaDelta.h \
+    ../../src/algorithms/StaticFrameDifference.h \
+    ../../src/algorithms/SuBSENSE.h \
+    ../../src/algorithms/T2FGMM_UM.h \
+    ../../src/algorithms/T2FGMM_UV.h \
+    ../../src/algorithms/T2FMRF_UM.h \
+    ../../src/algorithms/T2FMRF_UV.h \
+    ../../src/algorithms/TwoPoints.h \
+    ../../src/algorithms/ViBe.h \
+    ../../src/algorithms/VuMeter.h \
+    ../../src/algorithms/WeightedMovingMean.h \
+    ../../src/algorithms/WeightedMovingVariance.h \
+    ../../src/algorithms/CodeBook.h
+    ../../src/algorithms/_template_/MyBGS.h \
 
 FORMS    += mainwindow.ui
 
 DISTFILES += \
-    ../../src/package_bgs/LBSP/LBSP_16bits_dbcross_1ch.i \
-    ../../src/package_bgs/LBSP/LBSP_16bits_dbcross_3ch1t.i \
-    ../../src/package_bgs/LBSP/LBSP_16bits_dbcross_3ch3t.i \
-    ../../src/package_bgs/LBSP/LBSP_16bits_dbcross_s3ch.i \
-    ../../src/package_bgs/ViBe/LICENSE
+    ../../src/algorithms/LBSP/LBSP_16bits_dbcross_1ch.i \
+    ../../src/algorithms/LBSP/LBSP_16bits_dbcross_3ch1t.i \
+    ../../src/algorithms/LBSP/LBSP_16bits_dbcross_3ch3t.i \
+    ../../src/algorithms/LBSP/LBSP_16bits_dbcross_s3ch.i \
+    ../../src/algorithms/ViBe/LICENSE
diff --git a/gui/qt/mainwindow.h b/gui/qt/mainwindow.h
index fdb0c4b067a1a14a1007fc35d1d379f042f04203..521a7796dc1782a3cb8e1c244f0b0d949341462b 100644
--- a/gui/qt/mainwindow.h
+++ b/gui/qt/mainwindow.h
@@ -27,7 +27,7 @@
 
 #include "qt_utils.h"
 #include "texteditor.h"
-#include "../../src/package_bgs/bgslibrary.h"
+#include "../../src/algorithms/algorithms.h"
 
 namespace bgslibrary
 {
diff --git a/src/FrameProcessor.cpp b/src/FrameProcessor.cpp
index 91ebafd4b78a501d05644b381d530a36babdab6e..ab47cda08804cb56772d6a3ce939fce3fecb9b26 100644
--- a/src/FrameProcessor.cpp
+++ b/src/FrameProcessor.cpp
@@ -8,13 +8,12 @@ namespace bgslibrary
     firstTime(true), frameNumber(0), duration(0), 
     tictoc(""), frameToStop(0)
   {
-    std::cout << "FrameProcessor()" << std::endl;
-    setup("./config/FrameProcessor.xml");
+    debug_construction(FrameProcessor);
+    initLoadSaveConfig(quote(FrameProcessor));
   }
 
-  FrameProcessor::~FrameProcessor()
-  {
-    std::cout << "~FrameProcessor()" << std::endl;
+  FrameProcessor::~FrameProcessor() {
+    debug_destruction(FrameProcessor);
   }
 
   void FrameProcessor::init()
@@ -37,6 +36,9 @@ namespace bgslibrary
     if (enableAdaptiveBackgroundLearning)
       adaptiveBackgroundLearning = std::make_shared<AdaptiveBackgroundLearning>();
 
+    if (enableAdaptiveSelectiveBackgroundLearning)
+      adaptiveSelectiveBackgroundLearning = std::make_shared<AdaptiveSelectiveBackgroundLearning>();
+
     if (enableMixtureOfGaussianV2)
       mixtureOfGaussianV2 = std::make_shared<MixtureOfGaussianV2>();
 
@@ -196,6 +198,9 @@ namespace bgslibrary
     if (enableAdaptiveBackgroundLearning)
       process("AdaptiveBackgroundLearning", adaptiveBackgroundLearning, img_preProcessor, img_adaptiveBackgroundLearning);
 
+    if (enableAdaptiveSelectiveBackgroundLearning)
+      process("AdaptiveSelectiveBackgroundLearning", adaptiveSelectiveBackgroundLearning, img_preProcessor, img_adaptiveSelectiveBackgroundLearning);
+
     if (enableMixtureOfGaussianV2)
       process("MixtureOfGaussianV2", mixtureOfGaussianV2, img_preProcessor, img_mixtureOfGaussianV2);
 
@@ -329,6 +334,7 @@ namespace bgslibrary
       foregroundMaskAnalysis->process(frameNumber, "WeightedMovingMean", img_weightedMovingMean);
       foregroundMaskAnalysis->process(frameNumber, "WeightedMovingVariance", img_weightedMovingVariance);
       foregroundMaskAnalysis->process(frameNumber, "AdaptiveBackgroundLearning", img_adaptiveBackgroundLearning);
+      foregroundMaskAnalysis->process(frameNumber, "AdaptiveSelectiveBackgroundLearning", img_adaptiveSelectiveBackgroundLearning);
       foregroundMaskAnalysis->process(frameNumber, "MixtureOfGaussianV2", img_mixtureOfGaussianV2);
 
 #if CV_MAJOR_VERSION == 2
@@ -398,10 +404,7 @@ namespace bgslibrary
     std::cout << processname << "\ttime(sec):" << std::fixed << std::setprecision(6) << duration << std::endl;
   }
 
-  void FrameProcessor::saveConfig()
-  {
-    cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-
+  void FrameProcessor::save_config(cv::FileStorage &fs) {
     fs << "tictoc" << tictoc;
     fs << "enablePreProcessor" << enablePreProcessor;
     fs << "enableForegroundMaskAnalysis" << enableForegroundMaskAnalysis;
@@ -410,6 +413,7 @@ namespace bgslibrary
     fs << "enableWeightedMovingMean" << enableWeightedMovingMean;
     fs << "enableWeightedMovingVariance" << enableWeightedMovingVariance;
     fs << "enableAdaptiveBackgroundLearning" << enableAdaptiveBackgroundLearning;
+    fs << "enableAdaptiveSelectiveBackgroundLearning" << enableAdaptiveSelectiveBackgroundLearning;
     fs << "enableMixtureOfGaussianV2" << enableMixtureOfGaussianV2;
 
 #if CV_MAJOR_VERSION == 2
@@ -460,15 +464,9 @@ namespace bgslibrary
     fs << "enableTwoPoints" << enableTwoPoints;
     fs << "enableViBe" << enableViBe;
     fs << "enableCodeBook" << enableCodeBook;
-
-    fs.release();
   }
 
-  void FrameProcessor::loadConfig()
-  {
-    cv::FileStorage fs;
-    fs.open(config_xml, cv::FileStorage::READ);
-    
+  void FrameProcessor::load_config(cv::FileStorage &fs) {
     fs["tictoc"] >> tictoc;
     fs["enablePreProcessor"] >> enablePreProcessor;
     fs["enableForegroundMaskAnalysis"] >> enableForegroundMaskAnalysis;
@@ -477,6 +475,7 @@ namespace bgslibrary
     fs["enableWeightedMovingMean"] >> enableWeightedMovingMean;
     fs["enableWeightedMovingVariance"] >> enableWeightedMovingVariance;
     fs["enableAdaptiveBackgroundLearning"] >> enableAdaptiveBackgroundLearning;
+    fs["enableAdaptiveBackgroundLearning"] >> enableAdaptiveSelectiveBackgroundLearning;
     fs["enableMixtureOfGaussianV2"] >> enableMixtureOfGaussianV2;
 
 #if CV_MAJOR_VERSION == 2
@@ -527,7 +526,5 @@ namespace bgslibrary
     fs["enableTwoPoints"] >> enableTwoPoints;
     fs["enableViBe"] >> enableViBe;
     fs["enableCodeBook"] >> enableCodeBook;
-
-    fs.release();
   }
 }
diff --git a/src/FrameProcessor.h b/src/FrameProcessor.h
index 63a9f42c1588c8dd5dd009cee5549729ea62e890..8c0b10f1c9d7db0ff6f95c20b189669a62f2d3a2 100644
--- a/src/FrameProcessor.h
+++ b/src/FrameProcessor.h
@@ -4,8 +4,8 @@
 #include "IFrameProcessor.h"
 #include "PreProcessor.h"
 
-#include "package_bgs/bgslibrary.h"
-#include "package_analysis/ForegroundMaskAnalysis.h"
+#include "algorithms/algorithms.h"
+#include "tools/ForegroundMaskAnalysis.h"
 
 namespace bgslibrary
 {
@@ -38,19 +38,23 @@ namespace bgslibrary
     std::shared_ptr<WeightedMovingVariance> weightedMovingVariance;
     bool enableWeightedMovingVariance = false;
 
-#if CV_MAJOR_VERSION == 2
-    cv::Mat img_mixtureOfGaussianV1;
-    std::shared_ptr<MixtureOfGaussianV1> mixtureOfGaussianV1;
-    bool enableMixtureOfGaussianV1 = false;
-#endif
+    cv::Mat img_adaptiveBackgroundLearning;
+    std::shared_ptr<AdaptiveBackgroundLearning> adaptiveBackgroundLearning;
+    bool enableAdaptiveBackgroundLearning = false;
+
+    cv::Mat img_adaptiveSelectiveBackgroundLearning;
+    std::shared_ptr<AdaptiveSelectiveBackgroundLearning> adaptiveSelectiveBackgroundLearning;
+    bool enableAdaptiveSelectiveBackgroundLearning = false;
 
     cv::Mat img_mixtureOfGaussianV2;
     std::shared_ptr<MixtureOfGaussianV2> mixtureOfGaussianV2;
     bool enableMixtureOfGaussianV2 = false;
 
-    cv::Mat img_adaptiveBackgroundLearning;
-    std::shared_ptr<AdaptiveBackgroundLearning> adaptiveBackgroundLearning;
-    bool enableAdaptiveBackgroundLearning = false;
+#if CV_MAJOR_VERSION == 2
+    cv::Mat img_mixtureOfGaussianV1;
+    std::shared_ptr<MixtureOfGaussianV1> mixtureOfGaussianV1;
+    bool enableMixtureOfGaussianV1 = false;
+#endif
 
 #if CV_MAJOR_VERSION == 2 && CV_MINOR_VERSION >= 4 && CV_SUBMINOR_VERSION >= 3
     cv::Mat img_gmg;
@@ -216,8 +220,8 @@ namespace bgslibrary
     void process(const std::string name, const std::shared_ptr<IBGS> &bgs, const cv::Mat &img_input, cv::Mat &img_bgs);
     void tic(std::string value);
     void toc();
-
-    void saveConfig();
-    void loadConfig();
+    
+    void save_config(cv::FileStorage &fs);
+    void load_config(cv::FileStorage &fs);
   };
 }
diff --git a/src/IFrameProcessor.h b/src/IFrameProcessor.h
index 2b26eb4999ad558588f4386ff298d8f0cb2824c2..1cf0cdd2f344be361f3b4bce2fd02a6ed199e9cb 100644
--- a/src/IFrameProcessor.h
+++ b/src/IFrameProcessor.h
@@ -2,12 +2,19 @@
 
 #include <opencv2/opencv.hpp>
 
+#include "utils/GenericMacros.h"
+
 namespace bgslibrary
 {
   class IFrameProcessor
   {
   public:
+    IFrameProcessor(){
+      //debug_construction(IFrameProcessor);
+    }
+    virtual ~IFrameProcessor() {
+      //debug_destruction(IFrameProcessor);
+    }
     virtual void process(const cv::Mat &input) = 0;
-    virtual ~IFrameProcessor(){}
   };
 }
diff --git a/src/Main.cpp b/src/Main.cpp
index c8a836735d2a076490ce093d6214b1594aacb017..73993d39f44386dd7b44538483557ecd4e1efe3d 100644
--- a/src/Main.cpp
+++ b/src/Main.cpp
@@ -1,6 +1,6 @@
 #include <iostream>
 
-#include "Config.h"
+#include "utils/GenericKeys.h"
 #include "VideoAnalysis.h"
 
 namespace bgslibrary
diff --git a/src/PreProcessor.cpp b/src/PreProcessor.cpp
index d1c3f8c0b17fbadb09142f58afaf98bc9b491b1b..809d04d883210e67e678fbbdeb19ffb6cea60708 100644
--- a/src/PreProcessor.cpp
+++ b/src/PreProcessor.cpp
@@ -5,27 +5,23 @@ namespace bgslibrary
   PreProcessor::PreProcessor() : 
     firstTime(true), equalizeHist(false), gaussianBlur(false)
   {
-    std::cout << "PreProcessor()" << std::endl;
-    setup("./config/PreProcessor.xml");
+    debug_construction(PreProcessor);
+    initLoadSaveConfig(quote(PreProcessor));
   }
 
-  PreProcessor::~PreProcessor()
-  {
-    std::cout << "~PreProcessor()" << std::endl;
+  PreProcessor::~PreProcessor() {
+    debug_destruction(PreProcessor);
   }
 
-  void PreProcessor::setEqualizeHist(bool value)
-  {
+  void PreProcessor::setEqualizeHist(bool value) {
     equalizeHist = value;
   }
 
-  void PreProcessor::setGaussianBlur(bool value)
-  {
+  void PreProcessor::setGaussianBlur(bool value) {
     gaussianBlur = value;
   }
 
-  cv::Mat PreProcessor::getGrayScale()
-  {
+  cv::Mat PreProcessor::getGrayScale() {
     return img_gray.clone();
   }
 
@@ -34,11 +30,6 @@ namespace bgslibrary
     if (img_input.empty())
       return;
 
-    loadConfig();
-
-    if (firstTime)
-      saveConfig();
-
     img_input.copyTo(img_output);
 
     // Converts image from one color space to another
@@ -102,35 +93,24 @@ namespace bgslibrary
 
     cv::Mat img_canny;
     cv::Canny(
-      img_input, // image � Single-channel 8-bit input image
-      img_canny,  // edges � The output edge map. It will have the same size and the same type as image
-      100,       // threshold1 � The first threshold for the hysteresis procedure
-      200);      // threshold2 � The second threshold for the hysteresis procedure
+      img_input, // image � Single-channel 8-bit input image
+      img_canny,  // edges � The output edge map. It will have the same size and the same type as image
+      100,       // threshold1 � The first threshold for the hysteresis procedure
+      200);      // threshold2 � The second threshold for the hysteresis procedure
     cv::threshold(img_canny, img_canny, 128, 255, cv::THRESH_BINARY_INV);
 
     img_canny.copyTo(img_output);
   }
 
-  void PreProcessor::saveConfig()
-  {
-    cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-
+  void PreProcessor::save_config(cv::FileStorage &fs) {
     fs << "equalizeHist" << equalizeHist;
     fs << "gaussianBlur" << gaussianBlur;
     fs << "enableShow" << enableShow;
-
-    fs.release();
   }
 
-  void PreProcessor::loadConfig()
-  {
-    cv::FileStorage fs;
-    fs.open(config_xml, cv::FileStorage::READ);
-    
+  void PreProcessor::load_config(cv::FileStorage &fs) {
     fs["equalizeHist"] >> equalizeHist;
     fs["gaussianBlur"] >> gaussianBlur;
     fs["enableShow"] >> enableShow;
-
-    fs.release();
   }
 }
diff --git a/src/PreProcessor.h b/src/PreProcessor.h
index b0ee9f47c3c3f38d192c972315b17f92b8f6871c..a14de1837218dff0d85aa251085d6805a93aec3d 100644
--- a/src/PreProcessor.h
+++ b/src/PreProcessor.h
@@ -6,11 +6,12 @@
 #include <opencv2/highgui/highgui.hpp>
 #include <opencv2/imgproc/imgproc.hpp>
 #include <opencv2/features2d/features2d.hpp>
+// opencv legacy includes
 #include <opencv2/imgproc/types_c.h>
 //#include <opencv2/imgproc/imgproc_c.h>
 //#include <opencv2/highgui/highgui_c.h>
 
-#include "package_bgs/ILoadSaveConfig.h"
+#include "utils/ILoadSaveConfig.h"
 
 namespace bgslibrary
 {
@@ -37,7 +38,7 @@ namespace bgslibrary
     void applyCanny(const cv::Mat &img_input, cv::Mat &img_output);
 
   private:
-    void saveConfig();
-    void loadConfig();
+    void save_config(cv::FileStorage &fs);
+    void load_config(cv::FileStorage &fs);
   };
 }
diff --git a/src/VideoAnalysis.cpp b/src/VideoAnalysis.cpp
index 315cff4ecba80b6f98322368dfed9abb13ea5f06..d06918609e39b6cba3f3973ed294080387e8a680 100644
--- a/src/VideoAnalysis.cpp
+++ b/src/VideoAnalysis.cpp
@@ -6,12 +6,11 @@ namespace bgslibrary
     use_file(false), use_camera(false), cameraIndex(0),
     use_comp(false), frameToStop(0)
   {
-    std::cout << "VideoAnalysis()" << std::endl;
+    debug_construction(VideoAnalysis);
   }
 
-  VideoAnalysis::~VideoAnalysis()
-  {
-    std::cout << "~VideoAnalysis()" << std::endl;
+  VideoAnalysis::~VideoAnalysis() {
+    debug_destruction(VideoAnalysis);
   }
 
   bool VideoAnalysis::setup(int argc, const char **argv)
@@ -84,10 +83,8 @@ namespace bgslibrary
     std::cout << "imgref:      " << imgref << std::endl;
     //return false;
 
-    if (use_file)
-    {
-      if (filename.empty())
-      {
+    if (use_file) {
+      if (filename.empty()) {
         std::cout << "Specify filename" << std::endl;
         return false;
       }
@@ -98,10 +95,8 @@ namespace bgslibrary
     if (use_camera)
       flag = true;
 
-    if (flag && use_comp)
-    {
-      if (imgref.empty())
-      {
+    if (flag && use_comp) {
+      if (imgref.empty()) {
         std::cout << "Specify image reference" << std::endl;
         return false;
       }
@@ -114,8 +109,7 @@ namespace bgslibrary
   {
     //std::cout << "Press 'ESC' to stop..." << std::endl;
 
-    do
-    {
+    do {
       videoCapture = std::make_unique<VideoCapture>();
       frameProcessor = std::make_shared<FrameProcessor>();
 
diff --git a/src/VideoCapture.cpp b/src/VideoCapture.cpp
index bcf44e4d2e28b756af80573bcc117e7d57ced38d..2b86899bf6b5435373e71810d4e2d75ae261f5a6 100644
--- a/src/VideoCapture.cpp
+++ b/src/VideoCapture.cpp
@@ -70,16 +70,16 @@ namespace bgslibrary
 
   VideoCapture::VideoCapture() :
     key(0), start_time(0), delta_time(0), freq(0),
-    fps(0), frameNumber(0), stopAt(0), useCamera(false), cameraIndex(0),
-    useVideo(false), input_resize_percent(100), showOutput(true), enableFlip(false)
+    fps(0), frameNumber(0), stopAt(0), useCamera(false),
+    cameraIndex(0), useVideo(false), input_resize_percent(100),
+    showOutput(true), showFPS(true), enableFlip(false)
   {
-    std::cout << "VideoCapture()" << std::endl;
-    setup("./config/VideoCapture.xml");
+    debug_construction(VideoCapture);
+    initLoadSaveConfig(quote(VideoCapture));
   }
 
-  VideoCapture::~VideoCapture()
-  {
-    std::cout << "~VideoCapture()" << std::endl;
+  VideoCapture::~VideoCapture() {
+    debug_destruction(VideoCapture);
   }
 
   void VideoCapture::setFrameProcessor(const std::shared_ptr<IFrameProcessor> &_frameProcessor)
@@ -223,15 +223,24 @@ namespace bgslibrary
       cv::Mat img_input;
       frame.copyTo(img_input);
 
-      if (showOutput)
-        cv::imshow("Input", img_input);
-
       start_time = cv::getTickCount();
       frameProcessor->process(img_input);
       delta_time = cv::getTickCount() - start_time;
       freq = cv::getTickFrequency();
       fps = freq / delta_time;
-      std::cout << "FPS: " << fps << std::endl;
+      //std::cout << "FPS: " << fps << std::endl;
+      
+      if (showFPS)
+        cv::putText(img_input,
+              "FPS: " + std::to_string(fps),
+              cv::Point(10,15), // Coordinates
+              cv::FONT_HERSHEY_COMPLEX_SMALL, // Font
+              1.0, // Scale. 2.0 = 2x bigger
+              cv::Scalar(0,0,255), // BGR Color
+              1); // Line Thickness (Optional)
+
+      if (showOutput)
+        cv::imshow("Input", img_input);
 
       //cvResetImageROI(frame);
 
@@ -253,10 +262,7 @@ namespace bgslibrary
     capture.release();
   }
 
-  void VideoCapture::saveConfig()
-  {
-    cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-    
+  void VideoCapture::save_config(cv::FileStorage &fs) {
     fs << "stopAt" << stopAt;
     fs << "input_resize_percent" << input_resize_percent;
     fs << "enableFlip" << enableFlip;
@@ -266,16 +272,11 @@ namespace bgslibrary
     fs << "roi_y0" << VC_ROI::roi_y0;
     fs << "roi_x1" << VC_ROI::roi_x1;
     fs << "roi_y1" << VC_ROI::roi_y1;
+    fs << "showFPS" << showFPS;
     fs << "showOutput" << showOutput;
-    
-    fs.release();
   }
 
-  void VideoCapture::loadConfig()
-  {
-    cv::FileStorage fs;
-    fs.open(config_xml, cv::FileStorage::READ);
-    
+  void VideoCapture::load_config(cv::FileStorage &fs) {
     fs["stopAt"] >> stopAt;
     fs["input_resize_percent"] >> input_resize_percent;
     fs["enableFlip"] >> enableFlip;
@@ -285,8 +286,7 @@ namespace bgslibrary
     fs["roi_y0"] >> VC_ROI::roi_y0;
     fs["roi_x1"] >> VC_ROI::roi_x1;
     fs["roi_y1"] >> VC_ROI::roi_y1;
+    fs["showFPS"] >> showFPS;
     fs["showOutput"] >> showOutput;
-    
-    fs.release();
   }
 }
diff --git a/src/VideoCapture.h b/src/VideoCapture.h
index 1f6abc2f30ba3f4fc9ba1ab5a8fe0886d8e54014..9eaec286c178bddd3bfb0430710e8dcf5bb31572 100644
--- a/src/VideoCapture.h
+++ b/src/VideoCapture.h
@@ -6,13 +6,14 @@
 //#include <chrono>
 //#include <thread>
 #include <opencv2/opencv.hpp>
+// opencv legacy includes
 //#include <opencv2/highgui/highgui_c.h>
 //#include <opencv2/imgproc/imgproc_c.h>
 //#include <opencv2/imgproc/types_c.h>
 
-#include "Config.h"
+#include "utils/GenericKeys.h"
+#include "utils/ILoadSaveConfig.h"
 #include "IFrameProcessor.h"
-#include "package_bgs/ILoadSaveConfig.h"
 
 namespace bgslibrary
 {
@@ -35,6 +36,7 @@ namespace bgslibrary
     std::string videoFileName;
     int input_resize_percent;
     bool showOutput;
+    bool showFPS;
     bool enableFlip;
     double loopDelay = 33.333;
     bool firstTime = true;
@@ -51,8 +53,8 @@ namespace bgslibrary
   private:
     void setUpCamera();
     void setUpVideo();
-
-    void saveConfig();
-    void loadConfig();
+    
+    void save_config(cv::FileStorage &fs);
+    void load_config(cv::FileStorage &fs);
   };
 }
diff --git a/src/package_bgs/AdaptiveBackgroundLearning.cpp b/src/algorithms/AdaptiveBackgroundLearning.cpp
similarity index 72%
rename from src/package_bgs/AdaptiveBackgroundLearning.cpp
rename to src/algorithms/AdaptiveBackgroundLearning.cpp
index 3cace904cc764053ba5c5217fc33402e27988a82..d239dd0a0de50b52d0cba9ec3ee18e24989bfbb9 100644
--- a/src/package_bgs/AdaptiveBackgroundLearning.cpp
+++ b/src/algorithms/AdaptiveBackgroundLearning.cpp
@@ -3,16 +3,16 @@
 using namespace bgslibrary::algorithms;
 
 AdaptiveBackgroundLearning::AdaptiveBackgroundLearning() :
-  alpha(0.05), limit(-1), counter(0), minVal(0.0), maxVal(1.0),
-  enableThreshold(true), threshold(15)
+  IBGS(quote(AdaptiveBackgroundLearning)),
+  alpha(0.05), limit(-1), counter(0), minVal(0.0),
+  maxVal(1.0), enableThreshold(true), threshold(15)
 {
-  std::cout << "AdaptiveBackgroundLearning()" << std::endl;
-  setup("./config/AdaptiveBackgroundLearning.xml");
+  debug_construction(AdaptiveBackgroundLearning);
+  initLoadSaveConfig(algorithmName);
 }
 
-AdaptiveBackgroundLearning::~AdaptiveBackgroundLearning()
-{
-  std::cout << "~AdaptiveBackgroundLearning()" << std::endl;
+AdaptiveBackgroundLearning::~AdaptiveBackgroundLearning() {
+  debug_destruction(AdaptiveBackgroundLearning);
 }
 
 void AdaptiveBackgroundLearning::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -53,10 +53,9 @@ void AdaptiveBackgroundLearning::process(const cv::Mat &img_input, cv::Mat &img_
     cv::threshold(img_foreground, img_foreground, threshold, 255, cv::THRESH_BINARY);
 
 #ifndef MEX_COMPILE_FLAG
-  if (showOutput)
-  {
-    cv::imshow("A-Learning FG", img_foreground);
-    cv::imshow("A-Learning BG", img_background);
+  if (showOutput) {
+    cv::imshow(algorithmName + "_FG", img_foreground);
+    cv::imshow(algorithmName + "_BG", img_background);
   }
 #endif
 
@@ -66,29 +65,18 @@ void AdaptiveBackgroundLearning::process(const cv::Mat &img_input, cv::Mat &img_
   firstTime = false;
 }
 
-void AdaptiveBackgroundLearning::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-
+void AdaptiveBackgroundLearning::save_config(cv::FileStorage &fs) {
   fs << "alpha" << alpha;
   fs << "limit" << limit;
   fs << "enableThreshold" << enableThreshold;
   fs << "threshold" << threshold;
   fs << "showOutput" << showOutput;
-
-  fs.release();
 }
 
-void AdaptiveBackgroundLearning::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-
+void AdaptiveBackgroundLearning::load_config(cv::FileStorage &fs) {
   fs["alpha"] >> alpha;
   fs["limit"] >> limit;
   fs["enableThreshold"] >> enableThreshold;
   fs["threshold"] >> threshold;
   fs["showOutput"] >> showOutput;
-
-  fs.release();
 }
diff --git a/src/package_bgs/AdaptiveBackgroundLearning.h b/src/algorithms/AdaptiveBackgroundLearning.h
similarity index 61%
rename from src/package_bgs/AdaptiveBackgroundLearning.h
rename to src/algorithms/AdaptiveBackgroundLearning.h
index c7b45720c040f1759c29f659621bbcaab2bb7db1..5884ed4a133ad4ba4de58d5d04e8ba32aa63c2ff 100644
--- a/src/package_bgs/AdaptiveBackgroundLearning.h
+++ b/src/algorithms/AdaptiveBackgroundLearning.h
@@ -1,14 +1,12 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 namespace bgslibrary
 {
   namespace algorithms
   {
-    class AdaptiveBackgroundLearning : 
-      public IBGS, public ILoadSaveConfig
+    class AdaptiveBackgroundLearning : public IBGS
     {
     private:
       double alpha;
@@ -26,11 +24,10 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<AdaptiveBackgroundLearning> 
-      register_AdaptiveBackgroundLearning("AdaptiveBackgroundLearning");
+    bgs_register(AdaptiveBackgroundLearning);
   }
 }
diff --git a/src/package_bgs/AdaptiveSelectiveBackgroundLearning.cpp b/src/algorithms/AdaptiveSelectiveBackgroundLearning.cpp
similarity index 72%
rename from src/package_bgs/AdaptiveSelectiveBackgroundLearning.cpp
rename to src/algorithms/AdaptiveSelectiveBackgroundLearning.cpp
index 45c85daa52e5ed3cbe9bde2030bff852945e9068..84893b0a414df68c011cf99aed176e46dbcefc3a 100644
--- a/src/package_bgs/AdaptiveSelectiveBackgroundLearning.cpp
+++ b/src/algorithms/AdaptiveSelectiveBackgroundLearning.cpp
@@ -3,16 +3,16 @@
 using namespace bgslibrary::algorithms;
 
 AdaptiveSelectiveBackgroundLearning::AdaptiveSelectiveBackgroundLearning() :
-  alphaLearn(0.05), alphaDetection(0.05), learningFrames(-1), counter(0), minVal(0.0), maxVal(1.0),
-  threshold(15)
+  IBGS(quote(AdaptiveSelectiveBackgroundLearning)),
+  alphaLearn(0.05), alphaDetection(0.05), learningFrames(-1), 
+  counter(0), minVal(0.0), maxVal(1.0), threshold(15)
 {
-  std::cout << "AdaptiveSelectiveBackgroundLearning()" << std::endl;
-  setup("./config/AdaptiveSelectiveBackgroundLearning.xml");
+  debug_construction(AdaptiveSelectiveBackgroundLearning);
+  initLoadSaveConfig(algorithmName);
 }
 
-AdaptiveSelectiveBackgroundLearning::~AdaptiveSelectiveBackgroundLearning()
-{
-  std::cout << "~AdaptiveSelectiveBackgroundLearning()" << std::endl;
+AdaptiveSelectiveBackgroundLearning::~AdaptiveSelectiveBackgroundLearning() {
+  debug_destruction(AdaptiveSelectiveBackgroundLearning);
 }
 
 void AdaptiveSelectiveBackgroundLearning::process(const cv::Mat &img_input_, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -43,26 +43,20 @@ void AdaptiveSelectiveBackgroundLearning::process(const cv::Mat &img_input_, cv:
   cv::threshold(img_foreground, img_foreground, threshold, 255, cv::THRESH_BINARY);
   cv::medianBlur(img_foreground, img_foreground, 3);
 
-  if (learningFrames > 0 && counter <= learningFrames)
-  {
+  if (learningFrames > 0 && counter <= learningFrames) {
     //std::cout << "Adaptive update..." << std::endl;
     // Only Adaptive update of the background model
     img_background_f = alphaLearn * img_input_f + (1 - alphaLearn) * img_background_f;
     counter++;
   }
-  else
-  {
+  else {
     //std::cout << "Adaptive and Selective update..." << std::endl;
     int rows = img_input.rows;
     int cols = img_input.cols;
-
-    for (int i = 0; i < rows; i++)
-    {
-      for (int j = 0; j < cols; j++)
-      {
+    for (int i = 0; i < rows; i++) {
+      for (int j = 0; j < cols; j++) {
         // Adaptive and Selective update of the background model
-        if (img_foreground.at<uchar>(i, j) == 0)
-        {
+        if (img_foreground.at<uchar>(i, j) == 0) {
           img_background_f.at<float>(i, j) = alphaDetection * img_input_f.at<float>(i, j) + (1 - alphaDetection) * img_background_f.at<float>(i, j);
         }
       }
@@ -74,10 +68,9 @@ void AdaptiveSelectiveBackgroundLearning::process(const cv::Mat &img_input_, cv:
   //img_new_background.copyTo(img_background);
 
 #ifndef MEX_COMPILE_FLAG
-  if (showOutput)
-  {
-    cv::imshow("AS-Learning FG", img_foreground);
-    cv::imshow("AS-Learning BG", img_background);
+  if (showOutput) {
+    cv::imshow(algorithmName + "_FG", img_foreground);
+    cv::imshow(algorithmName + "_BG", img_background);
   }
 #endif
 
@@ -87,29 +80,18 @@ void AdaptiveSelectiveBackgroundLearning::process(const cv::Mat &img_input_, cv:
   firstTime = false;
 }
 
-void AdaptiveSelectiveBackgroundLearning::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-
+void AdaptiveSelectiveBackgroundLearning::save_config(cv::FileStorage &fs) {
   fs << "learningFrames" << learningFrames;
   fs << "alphaLearn" << alphaLearn;
   fs << "alphaDetection" << alphaDetection;
   fs << "threshold" << threshold;
   fs << "showOutput" << showOutput;
-
-  fs.release();
 }
 
-void AdaptiveSelectiveBackgroundLearning::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-
+void AdaptiveSelectiveBackgroundLearning::load_config(cv::FileStorage &fs) {
   fs["learningFrames"] >> learningFrames;
   fs["alphaLearn"] >> alphaLearn;
   fs["alphaDetection"] >> alphaDetection;
   fs["threshold"] >> threshold;
   fs["showOutput"] >> showOutput;
-
-  fs.release();
 }
diff --git a/src/package_bgs/AdaptiveSelectiveBackgroundLearning.h b/src/algorithms/AdaptiveSelectiveBackgroundLearning.h
similarity index 60%
rename from src/package_bgs/AdaptiveSelectiveBackgroundLearning.h
rename to src/algorithms/AdaptiveSelectiveBackgroundLearning.h
index 468388fcfff19d15de5646a926baf5694ffaed26..c5ad7c91b773450411bbaa7c7465554e62bdcdfd 100644
--- a/src/package_bgs/AdaptiveSelectiveBackgroundLearning.h
+++ b/src/algorithms/AdaptiveSelectiveBackgroundLearning.h
@@ -1,14 +1,12 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 namespace bgslibrary
 {
   namespace algorithms
   {
-    class AdaptiveSelectiveBackgroundLearning : 
-      public IBGS, public ILoadSaveConfig
+    class AdaptiveSelectiveBackgroundLearning : public IBGS
     {
     private:
       double alphaLearn;
@@ -26,11 +24,10 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<AdaptiveSelectiveBackgroundLearning> 
-      sregister_AdaptiveSelectiveBackgroundLearning("AdaptiveSelectiveBackgroundLearning");
+    bgs_register(AdaptiveSelectiveBackgroundLearning);
   }
 }
diff --git a/src/package_bgs/CodeBook.cpp b/src/algorithms/CodeBook.cpp
similarity index 87%
rename from src/package_bgs/CodeBook.cpp
rename to src/algorithms/CodeBook.cpp
index b5cf9c49c06e097f42386625d23f9873dd54d7c4..f7aa828ea968dbff02f8a2291580392dc20df0db 100644
--- a/src/package_bgs/CodeBook.cpp
+++ b/src/algorithms/CodeBook.cpp
@@ -3,46 +3,41 @@
 using namespace bgslibrary::algorithms;
 
 CodeBook::CodeBook() :
-  t(0), learningFrames(DEFAULT_LEARNFRAMES), alpha(DEFAULT_ALPHA), beta(DEFAULT_BETA)
+  IBGS(quote(CodeBook)),
+  t(0), learningFrames(DEFAULT_LEARNFRAMES), 
+  alpha(DEFAULT_ALPHA), beta(DEFAULT_BETA)
 {
-  std::cout << "CodeBook()" << std::endl;
-  setup("./config/CodeBook.xml");
+  debug_construction(CodeBook);
+  initLoadSaveConfig(algorithmName);
 }
 
-CodeBook::~CodeBook()
-{
-  std::cout << "~CodeBook()" << std::endl;
+CodeBook::~CodeBook() {
+  debug_destruction(CodeBook);
 }
 
 void CodeBook::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
   init(img_input, img_output, img_bgmodel);
   
-  if(firstTime)
-  {
+  if(firstTime) {
     img_foreground = cv::Mat::zeros(img_input.size(), CV_8UC1);
     //img_background = cv::Mat::zeros(img_input.size(), CV_8UC3);
-
     initializeCodebook(img_input.rows, img_input.cols);
   } 
 
   cv::Mat img_input_gray;
 
   if (img_input.channels() == 1)
-  {
     img_input_gray = img_input; 
-  } else
-  { 
+  else
     cv::cvtColor(img_input, img_input_gray, CV_BGR2GRAY);
-  }
 
   fg_cb(img_input_gray, img_foreground);
 
 #ifndef MEX_COMPILE_FLAG
-  if (showOutput)
-  {
-    cv::imshow("Codebook FG", img_foreground);
-    //cv::imshow("Codebook BG", img_background);
+  if (showOutput) {
+    cv::imshow(algorithmName + "_FG", img_foreground);
+    //cv::imshow(algorithmName + "_BG", img_background);
   }
 #endif
 
@@ -112,8 +107,7 @@ void CodeBook::fg_cb(const cv::Mat& frame, cv::Mat& fg)
   //fg = cv::Mat::zeros(frame.size(), CV_8UC1);
   //if (cbMain == 0) initializeCodebook(frame.rows, frame.cols);
   
-  if (t <= learningFrames)
-  {
+  if (t <= learningFrames) {
     update_cb(frame);
     return;
   }
@@ -182,27 +176,16 @@ void CodeBook::fg_cb(const cv::Mat& frame, cv::Mat& fg)
   }
 }
 
-void CodeBook::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-
+void CodeBook::save_config(cv::FileStorage &fs) {
   fs << "alpha" << alpha;
   fs << "beta" << beta;
   fs << "learningFrames" << learningFrames;
   fs << "showOutput" << showOutput;
-
-  fs.release();
 }
 
-void CodeBook::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-
+void CodeBook::load_config(cv::FileStorage &fs) {
   fs["alpha"] >> alpha;
   fs["beta"] >> beta;
   fs["learningFrames"] >> learningFrames;
   fs["showOutput"] >> showOutput;
-
-  fs.release();
 }
diff --git a/src/package_bgs/CodeBook.h b/src/algorithms/CodeBook.h
similarity index 82%
rename from src/package_bgs/CodeBook.h
rename to src/algorithms/CodeBook.h
index ba751ae2ce015d6ead999ff586cacb66f664b086..3fc8ff90f6e23bd56b0700d257c45ab18f44403d 100644
--- a/src/package_bgs/CodeBook.h
+++ b/src/algorithms/CodeBook.h
@@ -3,7 +3,6 @@
 #include <opencv2/opencv.hpp>
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 namespace bgslibrary
 {
@@ -19,7 +18,7 @@ namespace bgslibrary
       bool isStale;
     };
 
-    class CodeBook : public IBGS, public ILoadSaveConfig
+    class CodeBook : public IBGS
     {
     private:
       static const int Tdel = 200;
@@ -45,11 +44,11 @@ namespace bgslibrary
       void initializeCodebook(int w, int h);
       void update_cb(const cv::Mat& frame);
       void fg_cb(const cv::Mat& frame, cv::Mat& fg);
-
-      void saveConfig();
-      void loadConfig();
+      
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<CodeBook> register_CodeBook("CodeBook");
+    bgs_register(CodeBook);
   }
 }
diff --git a/src/package_bgs/DPAdaptiveMedian.cpp b/src/algorithms/DPAdaptiveMedian.cpp
similarity index 73%
rename from src/package_bgs/DPAdaptiveMedian.cpp
rename to src/algorithms/DPAdaptiveMedian.cpp
index 2427fecf1a7bff756139ea3e6b16e3e33d1d6c66..e121bdf3348f9b61cc699158ef83bb6cc02aebe3 100644
--- a/src/package_bgs/DPAdaptiveMedian.cpp
+++ b/src/algorithms/DPAdaptiveMedian.cpp
@@ -5,15 +5,16 @@
 using namespace bgslibrary::algorithms;
 
 DPAdaptiveMedian::DPAdaptiveMedian() :
-  frameNumber(0), threshold(40), samplingRate(7), learningFrames(30)
+  IBGS(quote(DPAdaptiveMedian)),
+  frameNumber(0), threshold(40), 
+  samplingRate(7), learningFrames(30)
 {
-  std::cout << "DPAdaptiveMedian()" << std::endl;
-  setup("./config/DPAdaptiveMedian.xml");
+  debug_construction(DPAdaptiveMedian);
+  initLoadSaveConfig(algorithmName);
 }
 
-DPAdaptiveMedian::~DPAdaptiveMedian()
-{
-  std::cout << "~DPAdaptiveMedian()" << std::endl;
+DPAdaptiveMedian::~DPAdaptiveMedian() {
+  debug_destruction(DPAdaptiveMedian);
 }
 
 void DPAdaptiveMedian::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -26,8 +27,7 @@ void DPAdaptiveMedian::process(const cv::Mat &img_input, cv::Mat &img_output, cv
     frame_data.ReleaseMemory(false);
   frame_data = frame;
 
-  if (firstTime)
-  {
+  if (firstTime) {
     int width = img_input.size().width;
     int height = img_input.size().height;
 
@@ -56,10 +56,9 @@ void DPAdaptiveMedian::process(const cv::Mat &img_input, cv::Mat &img_output, cv
   img_background = cv::cvarrToMat(bgs.Background()->Ptr());
 
 #ifndef MEX_COMPILE_FLAG
-  if (showOutput)
-  {
-    cv::imshow("Adaptive Median FG (McFarlane&Schofield)", img_foreground);
-    cv::imshow("Adaptive Median BG (McFarlane&Schofield)", img_background);
+  if (showOutput) {
+    cv::imshow(algorithmName + "_FG", img_foreground);
+    cv::imshow(algorithmName + "_BG", img_background);
   }
 #endif
 
@@ -71,29 +70,18 @@ void DPAdaptiveMedian::process(const cv::Mat &img_input, cv::Mat &img_output, cv
   frameNumber++;
 }
 
-void DPAdaptiveMedian::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-
+void DPAdaptiveMedian::save_config(cv::FileStorage &fs) {
   fs << "threshold" << threshold;
   fs << "samplingRate" << samplingRate;
   fs << "learningFrames" << learningFrames;
   fs << "showOutput" << showOutput;
-
-  fs.release();
 }
 
-void DPAdaptiveMedian::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-
+void DPAdaptiveMedian::load_config(cv::FileStorage &fs) {
   fs["threshold"] >> threshold;
   fs["samplingRate"] >> samplingRate;
   fs["learningFrames"] >> learningFrames;
   fs["showOutput"] >> showOutput;
-
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/DPAdaptiveMedian.h b/src/algorithms/DPAdaptiveMedian.h
similarity index 76%
rename from src/package_bgs/DPAdaptiveMedian.h
rename to src/algorithms/DPAdaptiveMedian.h
index 6426c60ab97bd1c922dabe9b35aab39f04b54c30..953f35fe73c8d4b17a2d515c51832973e582670f 100644
--- a/src/package_bgs/DPAdaptiveMedian.h
+++ b/src/algorithms/DPAdaptiveMedian.h
@@ -4,7 +4,6 @@
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 #include "dp/AdaptiveMedianBGS.h"
 
 using namespace Algorithms::BackgroundSubtraction;
@@ -13,7 +12,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class DPAdaptiveMedian : public IBGS, public ILoadSaveConfig
+    class DPAdaptiveMedian : public IBGS
     {
     private:
       long frameNumber;
@@ -34,11 +33,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<DPAdaptiveMedian> register_DPAdaptiveMedian("DPAdaptiveMedian");
+    bgs_register(DPAdaptiveMedian);
   }
 }
 
diff --git a/src/package_bgs/DPEigenbackground.cpp b/src/algorithms/DPEigenbackground.cpp
similarity index 77%
rename from src/package_bgs/DPEigenbackground.cpp
rename to src/algorithms/DPEigenbackground.cpp
index 1b6cc34901c1f61c83d8fdb0448c26c3acdf2389..dfc7d64dba4bb9f78126e2eb3b1c99925beab4ef 100644
--- a/src/package_bgs/DPEigenbackground.cpp
+++ b/src/algorithms/DPEigenbackground.cpp
@@ -5,15 +5,16 @@
 using namespace bgslibrary::algorithms;
 
 DPEigenbackground::DPEigenbackground() :
-  frameNumber(0), threshold(225), historySize(20), embeddedDim(10)
+  IBGS(quote(DPEigenbackground)),
+  frameNumber(0), threshold(225), 
+  historySize(20), embeddedDim(10)
 {
-  std::cout << "DPEigenbackground()" << std::endl;
-  setup("./config/DPEigenbackground.xml");
+  debug_construction(DPEigenbackground);
+  initLoadSaveConfig(algorithmName);
 }
 
-DPEigenbackground::~DPEigenbackground()
-{
-  std::cout << "~DPEigenbackground()" << std::endl;
+DPEigenbackground::~DPEigenbackground() {
+  debug_destruction(DPEigenbackground);
 }
 
 void DPEigenbackground::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -26,8 +27,7 @@ void DPEigenbackground::process(const cv::Mat &img_input, cv::Mat &img_output, c
     frame_data.ReleaseMemory(false);
   frame_data = frame;
 
-  if (firstTime)
-  {
+  if (firstTime) {
     int width = img_input.size().width;
     int height = img_input.size().height;
 
@@ -59,7 +59,7 @@ void DPEigenbackground::process(const cv::Mat &img_input, cv::Mat &img_output, c
 
 #ifndef MEX_COMPILE_FLAG
   if (showOutput)
-    cv::imshow("Eigenbackground (Oliver)", img_foreground);
+    cv::imshow(algorithmName + "_FG", img_foreground);
 #endif
 
   img_foreground.copyTo(img_output);
@@ -70,29 +70,18 @@ void DPEigenbackground::process(const cv::Mat &img_input, cv::Mat &img_output, c
   frameNumber++;
 }
 
-void DPEigenbackground::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-
+void DPEigenbackground::save_config(cv::FileStorage &fs) {
   fs << "threshold" << threshold;
   fs << "historySize" << historySize;
   fs << "embeddedDim" << embeddedDim;
   fs << "showOutput" << showOutput;
-
-  fs.release();
 }
 
-void DPEigenbackground::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-
+void DPEigenbackground::load_config(cv::FileStorage &fs) {
   fs["threshold"] >> threshold;
   fs["historySize"] >> historySize;
   fs["embeddedDim"] >> embeddedDim;
   fs["showOutput"] >> showOutput;
-
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/DPEigenbackground.h b/src/algorithms/DPEigenbackground.h
similarity index 75%
rename from src/package_bgs/DPEigenbackground.h
rename to src/algorithms/DPEigenbackground.h
index 90efc7e85f03784d09f409ed20fecab373e94168..34b1457c6e98e70b39a268a8a7d1f1e07d680403 100644
--- a/src/package_bgs/DPEigenbackground.h
+++ b/src/algorithms/DPEigenbackground.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 #include "opencv2/core/version.hpp"
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
@@ -14,7 +13,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class DPEigenbackground : public IBGS, public ILoadSaveConfig
+    class DPEigenbackground : public IBGS
     {
     private:
       long frameNumber;
@@ -37,11 +36,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<DPEigenbackground> register_DPEigenbackground("DPEigenbackground");
+    bgs_register(DPEigenbackground);
   }
 }
 
diff --git a/src/package_bgs/DPGrimsonGMM.cpp b/src/algorithms/DPGrimsonGMM.cpp
similarity index 78%
rename from src/package_bgs/DPGrimsonGMM.cpp
rename to src/algorithms/DPGrimsonGMM.cpp
index 6978a909481d1a053f5e70c6bd174f68fe28122a..743acf19e517ea82de47e6ab10711c10b1b6405b 100644
--- a/src/package_bgs/DPGrimsonGMM.cpp
+++ b/src/algorithms/DPGrimsonGMM.cpp
@@ -5,15 +5,16 @@
 using namespace bgslibrary::algorithms;
 
 DPGrimsonGMM::DPGrimsonGMM() :
-  frameNumber(0), threshold(9.0), alpha(0.01), gaussians(3)
+  IBGS(quote(DPGrimsonGMM)),
+  frameNumber(0), threshold(9.0), 
+  alpha(0.01), gaussians(3)
 {
-  std::cout << "DPGrimsonGMM()" << std::endl;
-  setup("./config/DPGrimsonGMM.xml");
+  debug_construction(DPGrimsonGMM);
+  initLoadSaveConfig(algorithmName);
 }
 
-DPGrimsonGMM::~DPGrimsonGMM()
-{
-  std::cout << "~DPGrimsonGMM()" << std::endl;
+DPGrimsonGMM::~DPGrimsonGMM() {
+  debug_destruction(DPGrimsonGMM);
 }
 
 void DPGrimsonGMM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -26,8 +27,7 @@ void DPGrimsonGMM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Ma
     frame_data.ReleaseMemory(false);
   frame_data = frame;
 
-  if (firstTime)
-  {
+  if (firstTime) {
     int width = img_input.size().width;
     int height = img_input.size().height;
 
@@ -58,7 +58,7 @@ void DPGrimsonGMM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Ma
 
 #ifndef MEX_COMPILE_FLAG
   if (showOutput)
-    cv::imshow("GMM (Grimson)", img_foreground);
+    cv::imshow(algorithmName + "_FG", img_foreground);
 #endif
 
   img_foreground.copyTo(img_output);
@@ -69,29 +69,18 @@ void DPGrimsonGMM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Ma
   frameNumber++;
 }
 
-void DPGrimsonGMM::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-
+void DPGrimsonGMM::save_config(cv::FileStorage &fs) {
   fs << "threshold" << threshold;
   fs << "alpha" << alpha;
   fs << "gaussians" << gaussians;
   fs << "showOutput" << showOutput;
-
-  fs.release();
 }
 
-void DPGrimsonGMM::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-
+void DPGrimsonGMM::load_config(cv::FileStorage &fs) {
   fs["threshold"] >> threshold;
   fs["alpha"] >> alpha;
   fs["gaussians"] >> gaussians;
   fs["showOutput"] >> showOutput;
-
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/DPGrimsonGMM.h b/src/algorithms/DPGrimsonGMM.h
similarity index 76%
rename from src/package_bgs/DPGrimsonGMM.h
rename to src/algorithms/DPGrimsonGMM.h
index 82503b77c9fc361d7952ff42435f3bd0ac10dcb3..2fa5bff3d3a7cb48f6caf597d450c8a84373f581 100644
--- a/src/package_bgs/DPGrimsonGMM.h
+++ b/src/algorithms/DPGrimsonGMM.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 #include "opencv2/core/version.hpp"
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
@@ -14,7 +13,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class DPGrimsonGMM : public IBGS, public ILoadSaveConfig
+    class DPGrimsonGMM : public IBGS
     {
     private:
       long frameNumber;
@@ -37,11 +36,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<DPGrimsonGMM> register_DPGrimsonGMM("DPGrimsonGMM");
+    bgs_register(DPGrimsonGMM);
   }
 }
 
diff --git a/src/package_bgs/DPMean.cpp b/src/algorithms/DPMean.cpp
similarity index 82%
rename from src/package_bgs/DPMean.cpp
rename to src/algorithms/DPMean.cpp
index 906b961953fb32130d1c07a51bede59eab972e08..18320cd5e57b52be02c29323578b6213c21182b6 100644
--- a/src/package_bgs/DPMean.cpp
+++ b/src/algorithms/DPMean.cpp
@@ -5,16 +5,16 @@
 using namespace bgslibrary::algorithms;
 
 DPMean::DPMean() :
+  IBGS(quote(DPMean)),
   frameNumber(0), threshold(2700),
   alpha(1e-6f), learningFrames(30)
 {
-  std::cout << "DPMean()" << std::endl;
-  setup("./config/DPMean.xml");
+  debug_construction(DPMean);
+  initLoadSaveConfig(algorithmName);
 }
 
-DPMean::~DPMean()
-{
-  std::cout << "~DPMean()" << std::endl;
+DPMean::~DPMean() {
+  debug_destruction(DPMean);
 }
 
 void DPMean::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -27,8 +27,7 @@ void DPMean::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img
     frame_data.ReleaseMemory(false);
   frame_data = frame;
 
-  if (firstTime)
-  {
+  if (firstTime) {
     int width = img_input.size().width;
     int height = img_input.size().height;
 
@@ -59,7 +58,7 @@ void DPMean::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img
 
 #ifndef MEX_COMPILE_FLAG
   if (showOutput)
-    cv::imshow("Temporal Mean (Donovan Parks)", img_foreground);
+    cv::imshow(algorithmName + "_FG", img_foreground);
 #endif
 
   img_foreground.copyTo(img_output);
@@ -70,29 +69,18 @@ void DPMean::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img
   frameNumber++;
 }
 
-void DPMean::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-
+void DPMean::save_config(cv::FileStorage &fs) {
   fs << "threshold" << threshold;
   fs << "alpha" << alpha;
   fs << "learningFrames" << learningFrames;
   fs << "showOutput" << showOutput;
-
-  fs.release();
 }
 
-void DPMean::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-
+void DPMean::load_config(cv::FileStorage &fs) {
   fs["threshold"] >> threshold;
   fs["alpha"] >> alpha;
   fs["learningFrames"] >> learningFrames;
   fs["showOutput"] >> showOutput;
-
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/DPMean.h b/src/algorithms/DPMean.h
similarity index 78%
rename from src/package_bgs/DPMean.h
rename to src/algorithms/DPMean.h
index 11356730657243ef1f7ccde1a0c0664e18e73385..6c3cdd7f5572c29cef7f5af0256fbdb39cceb09c 100644
--- a/src/package_bgs/DPMean.h
+++ b/src/algorithms/DPMean.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 #include "opencv2/core/version.hpp"
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
@@ -14,7 +13,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class DPMean : public IBGS, public ILoadSaveConfig
+    class DPMean : public IBGS
     {
     private:
       long frameNumber;
@@ -37,11 +36,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<DPMean> register_DPMean("DPMean");
+    bgs_register(DPMean);
   }
 }
 
diff --git a/src/package_bgs/DPPratiMediod.cpp b/src/algorithms/DPPratiMediod.cpp
similarity index 74%
rename from src/package_bgs/DPPratiMediod.cpp
rename to src/algorithms/DPPratiMediod.cpp
index 037cd067c1d7d2d8b5c28e8e3a3901c552a8e4f6..b9450101464e289c7151acfcdbe243dcdb6f4a64 100644
--- a/src/package_bgs/DPPratiMediod.cpp
+++ b/src/algorithms/DPPratiMediod.cpp
@@ -5,15 +5,16 @@
 using namespace bgslibrary::algorithms;
 
 DPPratiMediod::DPPratiMediod() :
-  frameNumber(0), threshold(30), samplingRate(5), historySize(16), weight(5)
+  IBGS(quote(DPMean)),
+  frameNumber(0), threshold(30), samplingRate(5), 
+  historySize(16), weight(5)
 {
-  std::cout << "DPPratiMediod()" << std::endl;
-  setup("./config/DPPratiMediod.xml");
+  debug_construction(DPPratiMediod);
+  initLoadSaveConfig(algorithmName);
 }
 
-DPPratiMediod::~DPPratiMediod()
-{
-  std::cout << "~DPPratiMediod()" << std::endl;
+DPPratiMediod::~DPPratiMediod() {
+  debug_destruction(DPPratiMediod);
 }
 
 void DPPratiMediod::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -26,8 +27,7 @@ void DPPratiMediod::process(const cv::Mat &img_input, cv::Mat &img_output, cv::M
     frame_data.ReleaseMemory(false);
   frame_data = frame;
 
-  if (firstTime)
-  {
+  if (firstTime) {
     int width = img_input.size().width;
     int height = img_input.size().height;
 
@@ -56,10 +56,9 @@ void DPPratiMediod::process(const cv::Mat &img_input, cv::Mat &img_output, cv::M
   img_background = cv::cvarrToMat(bgs.Background()->Ptr());
 
 #ifndef MEX_COMPILE_FLAG
-  if (showOutput)
-  {
-    cv::imshow("Temporal Median FG (Cucchiara&Calderara)", img_foreground);
-    cv::imshow("Temporal Median BG (Cucchiara&Calderara)", img_background);
+  if (showOutput) {
+    cv::imshow(algorithmName + "_FG", img_foreground);
+    cv::imshow(algorithmName + "_BG", img_background);
   }
 #endif
 
@@ -71,31 +70,20 @@ void DPPratiMediod::process(const cv::Mat &img_input, cv::Mat &img_output, cv::M
   frameNumber++;
 }
 
-void DPPratiMediod::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-
+void DPPratiMediod::save_config(cv::FileStorage &fs) {
   fs << "threshold" << threshold;
   fs << "samplingRate" << samplingRate;
   fs << "historySize" << historySize;
   fs << "weight" << weight;
   fs << "showOutput" << showOutput;
-
-  fs.release();
 }
 
-void DPPratiMediod::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-
+void DPPratiMediod::load_config(cv::FileStorage &fs) {
   fs["threshold"] >> threshold;
   fs["samplingRate"] >> samplingRate;
   fs["historySize"] >> historySize;
   fs["weight"] >> weight;
   fs["showOutput"] >> showOutput;
-
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/DPPratiMediod.h b/src/algorithms/DPPratiMediod.h
similarity index 76%
rename from src/package_bgs/DPPratiMediod.h
rename to src/algorithms/DPPratiMediod.h
index cb7016037cb6501c4cb16e5783cc96e400478326..8833016a406865b41edfbb59f07c0ea10aba1470 100644
--- a/src/package_bgs/DPPratiMediod.h
+++ b/src/algorithms/DPPratiMediod.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 #include "opencv2/core/version.hpp"
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
@@ -14,7 +13,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class DPPratiMediod : public IBGS, public ILoadSaveConfig
+    class DPPratiMediod : public IBGS
     {
     private:
       long frameNumber;
@@ -38,11 +37,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<DPPratiMediod> register_DPPratiMediod("DPPratiMediod");
+    bgs_register(DPPratiMediod);
   }
 }
 
diff --git a/src/package_bgs/DPTexture.cpp b/src/algorithms/DPTexture.cpp
similarity index 83%
rename from src/package_bgs/DPTexture.cpp
rename to src/algorithms/DPTexture.cpp
index 9f0b1bd2ae98024e1893e0f4076da4aedc5c1fbb..0448a797497165e9e23f4ee33edd438f77582fac 100644
--- a/src/package_bgs/DPTexture.cpp
+++ b/src/algorithms/DPTexture.cpp
@@ -4,15 +4,16 @@
 
 using namespace bgslibrary::algorithms;
 
-DPTexture::DPTexture()
-// : enableFiltering(true)
+DPTexture::DPTexture():
+  IBGS(quote(DPTexture)), 
+  // enableFiltering(true)
 {
-  std::cout << "DPTexture()" << std::endl;
-  setup("./config/DPTexture.xml");
+  debug_construction(DPTexture);
+  initLoadSaveConfig(algorithmName);
 }
 
-DPTexture::~DPTexture()
-{
+DPTexture::~DPTexture() {
+  debug_destruction(DPTexture);
   delete[] bgModel; // ~10Kb (25.708-15.968)
   delete[] modeArray;
   delete[] curTextureHist; // ~10Kb (16-6.396)
@@ -22,7 +23,6 @@ DPTexture::~DPTexture()
   fgMask.ReleaseImage();
   tempMask.ReleaseImage();
   texture.ReleaseImage();
-  std::cout << "~DPTexture()" << std::endl;
 }
 
 void DPTexture::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -31,8 +31,7 @@ void DPTexture::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
 
   frame = new IplImage(img_input);
 
-  if (firstTime)
-  {
+  if (firstTime) {
     width = img_input.size().width;
     height = img_input.size().height;
     size = width * height;
@@ -57,16 +56,11 @@ void DPTexture::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
     // initialize background model
     bgs.LBP(image, texture);
     bgs.Histogram(texture, curTextureHist);
-    for (int y = REGION_R + TEXTURE_R; y < height - REGION_R - TEXTURE_R; ++y)
-    {
-      for (int x = REGION_R + TEXTURE_R; x < width - REGION_R - TEXTURE_R; ++x)
-      {
+    for (int y = REGION_R + TEXTURE_R; y < height - REGION_R - TEXTURE_R; ++y) 
+      for (int x = REGION_R + TEXTURE_R; x < width - REGION_R - TEXTURE_R; ++x) {
         int index = x + y*width;
-
-        for (int m = 0; m < NUM_MODES; ++m)
-        {
-          for (int i = 0; i < NUM_BINS; ++i)
-          {
+        for (int m = 0; m < NUM_MODES; ++m) {
+          for (int i = 0; i < NUM_BINS; ++i) {
             bgModel[index].mode[m].r[i] = curTextureHist[index].r[i];
             bgModel[index].mode[m].g[i] = curTextureHist[index].g[i];
             bgModel[index].mode[m].b[i] = curTextureHist[index].b[i];
@@ -110,7 +104,7 @@ void DPTexture::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
 
 #ifndef MEX_COMPILE_FLAG
   if (showOutput)
-    cv::imshow("Texture BGS (Donovan Parks)", img_foreground);
+    cv::imshow(algorithmName + "_FG", img_foreground);
 #endif
 
   img_foreground.copyTo(img_output);
@@ -122,27 +116,16 @@ void DPTexture::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
   delete frame;
 }
 
-void DPTexture::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void DPTexture::save_config(cv::FileStorage &fs) {
   //fs << "alpha" << alpha;
   //fs << "enableFiltering" << enableFiltering;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void DPTexture::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void DPTexture::load_config(cv::FileStorage &fs) {
   //fs["alpha"] >> alpha;
   //fs["enableFiltering"] >> enableFiltering;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/DPTexture.h b/src/algorithms/DPTexture.h
similarity index 81%
rename from src/package_bgs/DPTexture.h
rename to src/algorithms/DPTexture.h
index ca7346311ba4680832055187250d320e72be492c..a908687a138ba1d4cf151a0a950db02b04f17f7c 100644
--- a/src/package_bgs/DPTexture.h
+++ b/src/algorithms/DPTexture.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 #include "opencv2/core/version.hpp"
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
@@ -13,7 +12,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class DPTexture : public IBGS, public ILoadSaveConfig
+    class DPTexture : public IBGS
     {
     private:
       int width;
@@ -41,11 +40,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<DPTexture> register_DPTextured("DPTexture");
+    bgs_register(DPTexture);
   }
 }
 
diff --git a/src/package_bgs/DPWrenGA.cpp b/src/algorithms/DPWrenGA.cpp
similarity index 78%
rename from src/package_bgs/DPWrenGA.cpp
rename to src/algorithms/DPWrenGA.cpp
index 970678566a60f5e82b7994b8eeabebf3366cc7a5..a7f91288855233f028b1ad34c6246b18ab96fa23 100644
--- a/src/package_bgs/DPWrenGA.cpp
+++ b/src/algorithms/DPWrenGA.cpp
@@ -5,15 +5,16 @@
 using namespace bgslibrary::algorithms;
 
 DPWrenGA::DPWrenGA() :
-  frameNumber(0), threshold(12.25f), alpha(0.005f), learningFrames(30)
+  IBGS(quote(DPWrenGA)),
+  frameNumber(0), threshold(12.25f), 
+  alpha(0.005f), learningFrames(30)
 {
-  std::cout << "DPWrenGA()" << std::endl;
-  setup("./config/DPWrenGA.xml");
+  debug_construction(DPWrenGA);
+  initLoadSaveConfig(algorithmName);
 }
 
-DPWrenGA::~DPWrenGA()
-{
-  std::cout << "~DPWrenGA()" << std::endl;
+DPWrenGA::~DPWrenGA() {
+  debug_destruction(DPWrenGA);
 }
 
 void DPWrenGA::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -26,8 +27,7 @@ void DPWrenGA::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &i
     frame_data.ReleaseMemory(false);
   frame_data = frame;
 
-  if (firstTime)
-  {
+  if (firstTime) {
     int width = img_input.size().width;
     int height = img_input.size().height;
 
@@ -57,7 +57,7 @@ void DPWrenGA::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &i
 
 #ifndef MEX_COMPILE_FLAG
   if (showOutput)
-    cv::imshow("Gaussian Average (Wren)", img_foreground);
+    cv::imshow(algorithmName + "_FG", img_foreground);
 #endif
 
   img_foreground.copyTo(img_output);
@@ -68,29 +68,18 @@ void DPWrenGA::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &i
   frameNumber++;
 }
 
-void DPWrenGA::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void DPWrenGA::save_config(cv::FileStorage &fs) {
   fs << "threshold" << threshold;
   fs << "alpha" << alpha;
   fs << "learningFrames" << learningFrames;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void DPWrenGA::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void DPWrenGA::load_config(cv::FileStorage &fs) {
   fs["threshold"] >> threshold;
   fs["alpha"] >> alpha;
   fs["learningFrames"] >> learningFrames;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/DPWrenGA.h b/src/algorithms/DPWrenGA.h
similarity index 77%
rename from src/package_bgs/DPWrenGA.h
rename to src/algorithms/DPWrenGA.h
index 9116a2064b9e5442a183db95dbaeb39e2850c58d..0fe1e6c7a8f8b87fd21146b5d8beb8195032cb33 100644
--- a/src/package_bgs/DPWrenGA.h
+++ b/src/algorithms/DPWrenGA.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 #include "opencv2/core/version.hpp"
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
@@ -14,7 +13,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class DPWrenGA : public IBGS, public ILoadSaveConfig
+    class DPWrenGA : public IBGS
     {
     private:
       long frameNumber;
@@ -37,11 +36,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<DPWrenGA> register_DPWrenGA("DPWrenGA");
+    bgs_register(DPWrenGA);
   }
 }
 
diff --git a/src/package_bgs/DPZivkovicAGMM.cpp b/src/algorithms/DPZivkovicAGMM.cpp
similarity index 77%
rename from src/package_bgs/DPZivkovicAGMM.cpp
rename to src/algorithms/DPZivkovicAGMM.cpp
index 0877cf1e575559f19725051fd9074fcb83de525e..289f5cc137a173769529454817d53b793fa0388d 100644
--- a/src/package_bgs/DPZivkovicAGMM.cpp
+++ b/src/algorithms/DPZivkovicAGMM.cpp
@@ -5,15 +5,16 @@
 using namespace bgslibrary::algorithms;
 
 DPZivkovicAGMM::DPZivkovicAGMM() :
-  frameNumber(0), threshold(25.0f), alpha(0.001f), gaussians(3)
+  IBGS(quote(DPZivkovicAGMM)),
+  frameNumber(0), threshold(25.0f), 
+  alpha(0.001f), gaussians(3)
 {
-  std::cout << "DPZivkovicAGMM()" << std::endl;
-  setup("./config/DPZivkovicAGMM.xml");
+  debug_construction(DPZivkovicAGMM);
+  initLoadSaveConfig(algorithmName);
 }
 
-DPZivkovicAGMM::~DPZivkovicAGMM()
-{
-  std::cout << "~DPZivkovicAGMM()" << std::endl;
+DPZivkovicAGMM::~DPZivkovicAGMM() {
+  debug_destruction(DPZivkovicAGMM);
 }
 
 void DPZivkovicAGMM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -26,8 +27,7 @@ void DPZivkovicAGMM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::
     frame_data.ReleaseMemory(false);
   frame_data = frame;
 
-  if (firstTime)
-  {
+  if (firstTime) {
     int width = img_input.size().width;
     int height = img_input.size().height;
 
@@ -57,7 +57,7 @@ void DPZivkovicAGMM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::
 
 #ifndef MEX_COMPILE_FLAG
   if (showOutput)
-    cv::imshow("Gaussian Mixture Model (Zivkovic)", img_foreground);
+    cv::imshow(algorithmName + "_FG", img_foreground);
 #endif
 
   img_foreground.copyTo(img_output);
@@ -68,29 +68,18 @@ void DPZivkovicAGMM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::
   frameNumber++;
 }
 
-void DPZivkovicAGMM::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void DPZivkovicAGMM::save_config(cv::FileStorage &fs) {
   fs << "threshold" << threshold;
   fs << "alpha" << alpha;
   fs << "gaussians" << gaussians;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void DPZivkovicAGMM::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void DPZivkovicAGMM::load_config(cv::FileStorage &fs) {
   fs["threshold"] >> threshold;
   fs["alpha"] >> alpha;
   fs["gaussians"] >> gaussians;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/DPZivkovicAGMM.h b/src/algorithms/DPZivkovicAGMM.h
similarity index 76%
rename from src/package_bgs/DPZivkovicAGMM.h
rename to src/algorithms/DPZivkovicAGMM.h
index cdbc16f761bd3145285dc6b15fd74f7475df6e62..4100ee63521190e234e5fd6288b5dcfd4db8c800 100644
--- a/src/package_bgs/DPZivkovicAGMM.h
+++ b/src/algorithms/DPZivkovicAGMM.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 #include "opencv2/core/version.hpp"
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
@@ -14,7 +13,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class DPZivkovicAGMM : public IBGS, public ILoadSaveConfig
+    class DPZivkovicAGMM : public IBGS
     {
     private:
       long frameNumber;
@@ -37,11 +36,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<DPZivkovicAGMM> register_DPZivkovicAGMM("DPZivkovicAGMM");
+    bgs_register(DPZivkovicAGMM);
   }
 }
 
diff --git a/src/package_bgs/FrameDifference.cpp b/src/algorithms/FrameDifference.cpp
similarity index 67%
rename from src/package_bgs/FrameDifference.cpp
rename to src/algorithms/FrameDifference.cpp
index f2ac50cc57cfa96c3913242aaa3754b0242eadbe..197aac48e4af9fd7cd7359e64767cf0c895e0bdf 100644
--- a/src/package_bgs/FrameDifference.cpp
+++ b/src/algorithms/FrameDifference.cpp
@@ -3,23 +3,22 @@
 using namespace bgslibrary::algorithms;
 
 FrameDifference::FrameDifference() :
+  IBGS(quote(FrameDifference)),
   enableThreshold(true), threshold(15)
 {
-  std::cout << "FrameDifference()" << std::endl;
-  setup("./config/FrameDifference.xml");
+  debug_construction(FrameDifference);
+  initLoadSaveConfig(algorithmName);
 }
 
-FrameDifference::~FrameDifference()
-{
-  std::cout << "~FrameDifference()" << std::endl;
+FrameDifference::~FrameDifference() {
+  debug_destruction(FrameDifference);
 }
 
 void FrameDifference::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
   init(img_input, img_output, img_bgmodel);
 
-  if (img_background.empty())
-  {
+  if (img_background.empty()) {
     img_input.copyTo(img_background);
     return;
   }
@@ -34,7 +33,7 @@ void FrameDifference::process(const cv::Mat &img_input, cv::Mat &img_output, cv:
 
 #ifndef MEX_COMPILE_FLAG
   if (showOutput)
-    cv::imshow("Frame Difference", img_foreground);
+    cv::imshow(algorithmName + "_FG", img_foreground);
 #endif
 
   img_foreground.copyTo(img_output);
@@ -45,25 +44,14 @@ void FrameDifference::process(const cv::Mat &img_input, cv::Mat &img_output, cv:
   firstTime = false;
 }
 
-void FrameDifference::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void FrameDifference::save_config(cv::FileStorage &fs) {
   fs << "enableThreshold" << enableThreshold;
   fs << "threshold" << threshold;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void FrameDifference::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void FrameDifference::load_config(cv::FileStorage &fs) {
   fs["enableThreshold"] >> enableThreshold;
   fs["threshold"] >> threshold;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
diff --git a/src/package_bgs/FrameDifference.h b/src/algorithms/FrameDifference.h
similarity index 59%
rename from src/package_bgs/FrameDifference.h
rename to src/algorithms/FrameDifference.h
index b2bf4395f1fadea483fe92ec70e559ba6f6e720f..b877313cb0b4018bfc8af4e26aab7632491d9443 100644
--- a/src/package_bgs/FrameDifference.h
+++ b/src/algorithms/FrameDifference.h
@@ -1,13 +1,12 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 namespace bgslibrary
 {
   namespace algorithms
   {
-    class FrameDifference : public IBGS, public ILoadSaveConfig
+    class FrameDifference : public IBGS
     {
     private:
       bool enableThreshold;
@@ -20,11 +19,10 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<FrameDifference> register_FrameDifference("FrameDifference");
+    bgs_register(FrameDifference);
   }
 }
-
diff --git a/src/package_bgs/FuzzyChoquetIntegral.cpp b/src/algorithms/FuzzyChoquetIntegral.cpp
similarity index 80%
rename from src/package_bgs/FuzzyChoquetIntegral.cpp
rename to src/algorithms/FuzzyChoquetIntegral.cpp
index ee8aac04cf8af3010551446055228275eb567b3d..b9140bfd17296af8d98ed483a8df5f05ba3f535d 100644
--- a/src/package_bgs/FuzzyChoquetIntegral.cpp
+++ b/src/algorithms/FuzzyChoquetIntegral.cpp
@@ -5,16 +5,17 @@
 using namespace bgslibrary::algorithms;
 
 FuzzyChoquetIntegral::FuzzyChoquetIntegral() :
-  frameNumber(0), framesToLearn(10), alphaLearn(0.1), alphaUpdate(0.01),
-  colorSpace(1), option(2), smooth(true), threshold(0.67)
+  IBGS(quote(FuzzyChoquetIntegral)),
+  frameNumber(0), framesToLearn(10), alphaLearn(0.1),
+  alphaUpdate(0.01), colorSpace(1), option(2),
+  smooth(true), threshold(0.67)
 {
-  std::cout << "FuzzyChoquetIntegral()" << std::endl;
-  setup("./config/FuzzyChoquetIntegral.xml");
+  debug_construction(FuzzyChoquetIntegral);
+  initLoadSaveConfig(algorithmName);
 }
 
-FuzzyChoquetIntegral::~FuzzyChoquetIntegral()
-{
-  std::cout << "~FuzzyChoquetIntegral()" << std::endl;
+FuzzyChoquetIntegral::~FuzzyChoquetIntegral() {
+  debug_destruction(FuzzyChoquetIntegral);
 }
 
 void FuzzyChoquetIntegral::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -24,9 +25,8 @@ void FuzzyChoquetIntegral::process(const cv::Mat &img_input, cv::Mat &img_output
   cv::Mat img_input_f3(img_input.size(), CV_32F);
   img_input.convertTo(img_input_f3, CV_32F, 1. / 255.);
 
-  if (firstTime)
-  {
-    std::cout << "FuzzyChoquetIntegral parameters:" << std::endl;
+  if (firstTime) {
+    std::cout << algorithmName + " parameters:" << std::endl;
 
     std::string colorSpaceName = "";
     switch (colorSpace)
@@ -44,10 +44,9 @@ void FuzzyChoquetIntegral::process(const cv::Mat &img_input, cv::Mat &img_output
       std::cout << "Fuzzing by 2 color components + 1 texture component" << std::endl;
   }
 
-  if (frameNumber <= framesToLearn)
-  {
+  if (frameNumber <= framesToLearn) {
     if (frameNumber == 0)
-      std::cout << "FuzzyChoquetIntegral initializing background model by adaptive learning..." << std::endl;
+      std::cout << algorithmName + " initializing background model by adaptive learning" << std::endl;
 
     if (img_background_f3.empty())
       img_input_f3.copyTo(img_background_f3);
@@ -63,7 +62,7 @@ void FuzzyChoquetIntegral::process(const cv::Mat &img_input, cv::Mat &img_output
 
 #ifndef MEX_COMPILE_FLAG
     if (showOutput)
-      cv::imshow("CI BG Model", img_background);
+      cv::imshow(algorithmName + "_BG", img_background);
 #endif
   }
   else
@@ -97,15 +96,13 @@ void FuzzyChoquetIntegral::process(const cv::Mat &img_input, cv::Mat &img_output
     IplImage* integral_choquet_f1 = cvCreateImage(cvSize(input_f1->width, input_f1->height), IPL_DEPTH_32F, 1);
 
     // 3 color components
-    if (option == 1)
-    {
+    if (option == 1) {
       fu.FuzzyMeasureG(0.4f, 0.3f, 0.3f, measureG);
       fu.getFuzzyIntegralChoquet(sim_texture_f1, sim_color_f3, option, measureG, integral_choquet_f1);
     }
 
     // 2 color components + 1 texture component
-    if (option == 2)
-    {
+    if (option == 2) {
       fu.FuzzyMeasureG(0.6f, 0.3f, 0.1f, measureG);
       fu.getFuzzyIntegralChoquet(sim_texture_f1, sim_color_f3, option, measureG, integral_choquet_f1);
     }
@@ -130,19 +127,18 @@ void FuzzyChoquetIntegral::process(const cv::Mat &img_input, cv::Mat &img_output
     img_background.copyTo(img_bgmodel);
 
 #ifndef MEX_COMPILE_FLAG
-    if (showOutput)
-    {
-      cvShowImage("CI LBP Input", lbp_input_f1);
-      cvShowImage("CI LBP Background", lbp_background_f1);
-      cvShowImage("CI Prob FG Mask", integral_choquet_f1);
+    if (showOutput) {
+      cvShowImage(algorithmName + "_LBP_IN", lbp_input_f1);
+      cvShowImage(algorithmName + "_LBP_BG", lbp_background_f1);
+      cvShowImage(algorithmName + "_FG_PROB", integral_choquet_f1);
 
-      cv::imshow("CI BG Model", img_background);
-      cv::imshow("CI FG Mask", img_foreground);
+      cv::imshow(algorithmName + "_BG", img_background);
+      cv::imshow(algorithmName + "_FG", img_foreground);
     }
 #endif
 
     if (frameNumber == (framesToLearn + 1))
-      std::cout << "FuzzyChoquetIntegral updating background model by adaptive-selective learning..." << std::endl;
+      std::cout << algorithmName + " updating background model by adaptive-selective learning" << std::endl;
 
     IplImage* updated_background_f3 = cvCreateImage(cvSize(input_f1->width, input_f1->height), IPL_DEPTH_32F, 3);
     cvSetZero(updated_background_f3);
@@ -167,10 +163,7 @@ void FuzzyChoquetIntegral::process(const cv::Mat &img_input, cv::Mat &img_output
   frameNumber++;
 }
 
-void FuzzyChoquetIntegral::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void FuzzyChoquetIntegral::save_config(cv::FileStorage &fs) {
   fs << "threshold" << threshold;
   fs << "framesToLearn" << framesToLearn;
   fs << "alphaLearn" << alphaLearn;
@@ -179,15 +172,9 @@ void FuzzyChoquetIntegral::saveConfig()
   fs << "option" << option;
   fs << "smooth" << smooth;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void FuzzyChoquetIntegral::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void FuzzyChoquetIntegral::load_config(cv::FileStorage &fs) {
   fs["threshold"] >> threshold;
   fs["framesToLearn"] >> framesToLearn;
   fs["alphaLearn"] >> alphaLearn;
@@ -196,8 +183,6 @@ void FuzzyChoquetIntegral::loadConfig()
   fs["option"] >> option;
   fs["smooth"] >> smooth;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/FuzzyChoquetIntegral.h b/src/algorithms/FuzzyChoquetIntegral.h
similarity index 72%
rename from src/package_bgs/FuzzyChoquetIntegral.h
rename to src/algorithms/FuzzyChoquetIntegral.h
index 9a57f30a20316cf8031607c18b4cf815ae461a41..ba348dbeaebd1daaf9fd3bd983373bf56be432a9 100644
--- a/src/package_bgs/FuzzyChoquetIntegral.h
+++ b/src/algorithms/FuzzyChoquetIntegral.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 #include "opencv2/core/version.hpp"
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
@@ -12,7 +11,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class FuzzyChoquetIntegral : public IBGS, public ILoadSaveConfig
+    class FuzzyChoquetIntegral : public IBGS
     {
     private:
       long long frameNumber;
@@ -35,11 +34,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<FuzzyChoquetIntegral> register_FuzzyChoquetIntegral("FuzzyChoquetIntegral");
+    bgs_register(FuzzyChoquetIntegral);
   }
 }
 
diff --git a/src/package_bgs/FuzzySugenoIntegral.cpp b/src/algorithms/FuzzySugenoIntegral.cpp
similarity index 82%
rename from src/package_bgs/FuzzySugenoIntegral.cpp
rename to src/algorithms/FuzzySugenoIntegral.cpp
index e4b3cf254c53b44e367e9d493b5fa8bd70c50dfa..03f63fa57ef71cb954235f3b52f1d2c223f03ab5 100644
--- a/src/package_bgs/FuzzySugenoIntegral.cpp
+++ b/src/algorithms/FuzzySugenoIntegral.cpp
@@ -5,16 +5,16 @@
 using namespace bgslibrary::algorithms;
 
 FuzzySugenoIntegral::FuzzySugenoIntegral() :
+  IBGS(quote(FuzzySugenoIntegral)),
   frameNumber(0), framesToLearn(10), alphaLearn(0.1), alphaUpdate(0.01),
   colorSpace(1), option(2), smooth(true), threshold(0.67)
 {
-  std::cout << "FuzzySugenoIntegral()" << std::endl;
-  setup("./config/FuzzySugenoIntegral.xml");
+  debug_construction(FuzzySugenoIntegral);
+  initLoadSaveConfig(algorithmName);
 }
 
-FuzzySugenoIntegral::~FuzzySugenoIntegral()
-{
-  std::cout << "~FuzzySugenoIntegral()" << std::endl;
+FuzzySugenoIntegral::~FuzzySugenoIntegral() {
+  debug_destruction(FuzzySugenoIntegral);
 }
 
 void FuzzySugenoIntegral::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -24,9 +24,8 @@ void FuzzySugenoIntegral::process(const cv::Mat &img_input, cv::Mat &img_output,
   cv::Mat img_input_f3(img_input.size(), CV_32F);
   img_input.convertTo(img_input_f3, CV_32F, 1. / 255.);
 
-  if (firstTime)
-  {
-    std::cout << "FuzzySugenoIntegral parameters:" << std::endl;
+  if (firstTime) {
+    std::cout << algorithmName + " parameters:" << std::endl;
 
     std::string colorSpaceName = "";
     switch (colorSpace)
@@ -44,10 +43,9 @@ void FuzzySugenoIntegral::process(const cv::Mat &img_input, cv::Mat &img_output,
       std::cout << "Fuzzing by 2 color components + 1 texture component" << std::endl;
   }
 
-  if (frameNumber <= framesToLearn)
-  {
+  if (frameNumber <= framesToLearn) {
     if (frameNumber == 0)
-      std::cout << "FuzzySugenoIntegral initializing background model by adaptive learning..." << std::endl;
+      std::cout << algorithmName + " initializing background model by adaptive learning" << std::endl;
 
     if (img_background_f3.empty())
       img_input_f3.copyTo(img_background_f3);
@@ -63,7 +61,7 @@ void FuzzySugenoIntegral::process(const cv::Mat &img_input, cv::Mat &img_output,
 
 #ifndef MEX_COMPILE_FLAG
     if (showOutput)
-      cv::imshow("SI BG Model", img_background);
+      cv::imshow(algorithmName + "_BG", img_background);
 #endif
   }
   else
@@ -97,15 +95,13 @@ void FuzzySugenoIntegral::process(const cv::Mat &img_input, cv::Mat &img_output,
     IplImage* integral_sugeno_f1 = cvCreateImage(cvSize(input_f1->width, input_f1->height), IPL_DEPTH_32F, 1);
 
     // 3 color components
-    if (option == 1)
-    {
+    if (option == 1) {
       fu.FuzzyMeasureG(0.4f, 0.3f, 0.3f, measureG);
       fu.getFuzzyIntegralSugeno(sim_texture_f1, sim_color_f3, option, measureG, integral_sugeno_f1);
     }
 
     // 2 color components + 1 texture component
-    if (option == 2)
-    {
+    if (option == 2) {
       fu.FuzzyMeasureG(0.6f, 0.3f, 0.1f, measureG);
       fu.getFuzzyIntegralSugeno(sim_texture_f1, sim_color_f3, option, measureG, integral_sugeno_f1);
     }
@@ -130,19 +126,18 @@ void FuzzySugenoIntegral::process(const cv::Mat &img_input, cv::Mat &img_output,
     img_background.copyTo(img_bgmodel);
 
 #ifndef MEX_COMPILE_FLAG
-    if (showOutput)
-    {
-      cvShowImage("SI LBP Input", lbp_input_f1);
-      cvShowImage("SI LBP Background", lbp_background_f1);
-      cvShowImage("SI Prob FG Mask", integral_sugeno_f1);
+    if (showOutput) {
+      cvShowImage(algorithmName + "_LBP_IN", lbp_input_f1);
+      cvShowImage(algorithmName + "_LBP_BG", lbp_background_f1);
+      cvShowImage(algorithmName + "_FG_PROB", integral_sugeno_f1);
 
-      cv::imshow("SI BG Model", img_background);
-      cv::imshow("SI FG Mask", img_foreground);
+      cv::imshow(algorithmName + "_BG", img_background);
+      cv::imshow(algorithmName + "_FG", img_foreground);
     }
 #endif
 
     if (frameNumber == (framesToLearn + 1))
-      std::cout << "FuzzySugenoIntegral updating background model by adaptive-selective learning..." << std::endl;
+      std::cout << algorithmName + " updating background model by adaptive-selective learning" << std::endl;
 
     IplImage* updated_background_f3 = cvCreateImage(cvSize(input_f1->width, input_f1->height), IPL_DEPTH_32F, 3);
     cvSetZero(updated_background_f3);
@@ -167,10 +162,7 @@ void FuzzySugenoIntegral::process(const cv::Mat &img_input, cv::Mat &img_output,
   frameNumber++;
 }
 
-void FuzzySugenoIntegral::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void FuzzySugenoIntegral::save_config(cv::FileStorage &fs) {
   fs << "threshold" << threshold;
   fs << "framesToLearn" << framesToLearn;
   fs << "alphaLearn" << alphaLearn;
@@ -179,15 +171,9 @@ void FuzzySugenoIntegral::saveConfig()
   fs << "option" << option;
   fs << "smooth" << smooth;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void FuzzySugenoIntegral::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void FuzzySugenoIntegral::load_config(cv::FileStorage &fs) {
   fs["threshold"] >> threshold;
   fs["framesToLearn"] >> framesToLearn;
   fs["alphaLearn"] >> alphaLearn;
@@ -196,8 +182,6 @@ void FuzzySugenoIntegral::loadConfig()
   fs["option"] >> option;
   fs["smooth"] >> smooth;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/FuzzySugenoIntegral.h b/src/algorithms/FuzzySugenoIntegral.h
similarity index 72%
rename from src/package_bgs/FuzzySugenoIntegral.h
rename to src/algorithms/FuzzySugenoIntegral.h
index 7f42a1118952230f8b8dddefee0e5817af199ef8..ed680a3cfc753a53c6f5029e0eeb11af2c75d59e 100644
--- a/src/package_bgs/FuzzySugenoIntegral.h
+++ b/src/algorithms/FuzzySugenoIntegral.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 #include "opencv2/core/version.hpp"
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
@@ -12,7 +11,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class FuzzySugenoIntegral : public IBGS, public ILoadSaveConfig
+    class FuzzySugenoIntegral : public IBGS
     {
     private:
       long long frameNumber;
@@ -35,11 +34,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<FuzzySugenoIntegral> register_FuzzySugenoIntegral("FuzzySugenoIntegral");
+    bgs_register(FuzzySugenoIntegral);
   }
 }
 
diff --git a/src/package_bgs/GMG.cpp b/src/algorithms/GMG.cpp
similarity index 62%
rename from src/package_bgs/GMG.cpp
rename to src/algorithms/GMG.cpp
index af66459ad7bd9a08b9226a713a07b21b73144c42..6abe1f40adcf5b6f1979cd43c212d688f7a0d103 100644
--- a/src/package_bgs/GMG.cpp
+++ b/src/algorithms/GMG.cpp
@@ -4,36 +4,35 @@
 
 using namespace bgslibrary::algorithms;
 
-GMG::GMG() : initializationFrames(20), decisionThreshold(0.7)
+GMG::GMG() : 
+  IBGS(quote(GMG)),
+  initializationFrames(20), decisionThreshold(0.7)
 {
-  std::cout << "GMG()" << std::endl;
-  setup("./config/GMG.xml");
+  debug_construction(GMG);
+  initLoadSaveConfig(algorithmName);
 
   cv::initModule_video();
   cv::setUseOptimized(true);
-  cv::setNumThreads(8);
+  cv::setNumThreads(4);
 
   fgbg = cv::Algorithm::create<cv::BackgroundSubtractorGMG>("BackgroundSubtractor.GMG");
 }
 
-GMG::~GMG()
-{
-  std::cout << "~GMG()" << std::endl;
+GMG::~GMG() {
+  debug_destruction(GMG);
 }
 
 void GMG::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
   init(img_input, img_output, img_bgmodel);
 
-  if (firstTime)
-  {
+  if (firstTime) {
     fgbg->set("initializationFrames", initializationFrames);
     fgbg->set("decisionThreshold", decisionThreshold);
   }
 
-  if (fgbg.empty())
-  {
-    std::cerr << "Failed to create BackgroundSubtractor.GMG Algorithm." << std::endl;
+  if (fgbg.empty()) {
+    std::cerr << "Failed to create " + algorithmName << std::endl;
     return;
   }
 
@@ -44,10 +43,9 @@ void GMG::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bg
   cv::add(img_input, cv::Scalar(100, 100, 0), img_segmentation, img_foreground);
 
 #ifndef MEX_COMPILE_FLAG
-  if (showOutput)
-  {
-    cv::imshow("GMG FG (Godbehere-Matsukawa-Goldberg)", img_foreground);
-    cv::imshow("GMG BG (Godbehere-Matsukawa-Goldberg)", img_background);
+  if (showOutput) {
+    cv::imshow(algorithmName + "_FG", img_foreground);
+    cv::imshow(algorithmName + "_BG", img_background);
   }
 #endif
 
@@ -57,27 +55,16 @@ void GMG::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bg
   firstTime = false;
 }
 
-void GMG::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void GMG::save_config(cv::FileStorage &fs) {
   fs << "initializationFrames" << initializationFrames;
   fs << "decisionThreshold" << decisionThreshold;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void GMG::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void GMG::load_config(cv::FileStorage &fs) {
   fs["initializationFrames"] >> initializationFrames;
   fs["decisionThreshold"] >> decisionThreshold;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/GMG.h b/src/algorithms/GMG.h
similarity index 74%
rename from src/package_bgs/GMG.h
rename to src/algorithms/GMG.h
index ebf80386bf43eb2b863f37b48388d2fc69a1f8b3..c5edd6b9393e4622265e3299c110e9405a3e2668 100644
--- a/src/package_bgs/GMG.h
+++ b/src/algorithms/GMG.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 #include "opencv2/core/version.hpp"
 #if CV_MAJOR_VERSION == 2 && CV_MINOR_VERSION >= 4 && CV_SUBMINOR_VERSION >= 3
@@ -10,7 +9,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class GMG : public IBGS, public ILoadSaveConfig
+    class GMG : public IBGS
     {
     private:
       cv::Ptr<cv::BackgroundSubtractorGMG> fgbg;
@@ -25,11 +24,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<GMG> register_GMG("GMG");
+    bgs_register(GMG);
   }
 }
 
diff --git a/src/package_bgs/IBGS.h b/src/algorithms/IBGS.h
similarity index 61%
rename from src/package_bgs/IBGS.h
rename to src/algorithms/IBGS.h
index a18a80a63365fdc9dc208fcf14ac2b7c4cb0922f..d9ba04126b00d703683e11d3a056d3fd760e7fc0 100644
--- a/src/package_bgs/IBGS.h
+++ b/src/algorithms/IBGS.h
@@ -9,21 +9,47 @@
 #include <map>
 
 #include <opencv2/opencv.hpp>
+
+// opencv legacy includes
 #include <opencv2/imgproc/types_c.h>
 #include <opencv2/imgproc/imgproc_c.h>
 #include <opencv2/highgui/highgui_c.h>
 
+#include "../utils/ILoadSaveConfig.h"
+
 #ifndef CV_RGB
-  #define  CV_RGB(r, g, b)   cv::Scalar((b), (g), (r), 0)
+#define CV_RGB(r, g, b) cv::Scalar((b), (g), (r), 0)
+#endif
+
+#if !defined(bgs_register)
+#define bgs_register(x) static BGS_Register<x> register_##x(quote(x))
 #endif
 
 namespace bgslibrary
 {
   namespace algorithms
   {
-    class IBGS
+    class IBGS : public ILoadSaveConfig
     {
+    private:
+      friend std::ostream& operator<<(std::ostream& o, const std::shared_ptr<IBGS>& ibgs) {
+        return ibgs.get()->dump(o);
+      }
+      friend std::ostream& operator<<(std::ostream& o, const IBGS *ibgs) {
+        return ibgs->dump(o);
+      }
+      friend std::string to_string(const std::shared_ptr<IBGS>& ibgs) {
+        std::ostringstream ss;
+        ss << ibgs;
+        return ss.str();
+      }
     public:
+      virtual std::ostream& dump(std::ostream& o) const {
+        return o << getAlgorithmName();
+      }
+      std::string getAlgorithmName() const {
+        return algorithmName;
+      }
       void setShowOutput(const bool _showOutput) {
         showOutput = _showOutput;
       }
@@ -38,9 +64,20 @@ namespace bgslibrary
       cv::Mat getBackgroundModel() {
         return img_background;
       }
+      IBGS(const std::string _algorithmName){
+        //debug_construction(IBGS);
+        algorithmName = _algorithmName;
+      }
+      IBGS(){
+        //debug_construction(IBGS);
+        algorithmName = "";
+      }
+      virtual ~IBGS() {
+        //debug_destruction(IBGS);
+      }
       virtual void process(const cv::Mat &img_input, cv::Mat &img_foreground, cv::Mat &img_background) = 0;
-      virtual ~IBGS() {}
     protected:
+      std::string algorithmName;
       bool firstTime = true;
       bool showOutput = true;
       cv::Mat img_background;
@@ -53,18 +90,22 @@ namespace bgslibrary
         img_outbg = cv::Mat::zeros(img_input.size(), CV_8UC3);
       }
     };
-
+    
     class BGS_Factory
     {
     public:
-      static BGS_Factory* Instance()
-      {
+      BGS_Factory() {
+        //debug_construction(BGS_Factory);
+      }
+      virtual ~BGS_Factory() {
+        //debug_destruction(BGS_Factory);
+      }
+      static BGS_Factory* Instance() {
         static BGS_Factory factory;
         return &factory;
       }
 
-      std::shared_ptr<IBGS> Create(std::string name)
-      {
+      std::shared_ptr<IBGS> Create(std::string name) {
         IBGS* instance = nullptr;
 
         // find name in the registry and call factory method.
@@ -79,8 +120,7 @@ namespace bgslibrary
           return nullptr;
       }
 
-      std::vector<std::string> GetRegisteredAlgorithmsName()
-      {
+      std::vector<std::string> GetRegisteredAlgorithmsName() {
         std::vector<std::string> algorithmsName;
         for (auto it = factoryFunctionRegistry.begin(); it != factoryFunctionRegistry.end(); ++it) {
           algorithmsName.push_back(it->first);
@@ -89,8 +129,7 @@ namespace bgslibrary
       }
 
       void RegisterFactoryFunction(std::string name,
-        std::function<IBGS*(void)> classFactoryFunction)
-      {
+        std::function<IBGS*(void)> classFactoryFunction) {
         // register the class factory function
         factoryFunctionRegistry[name] = classFactoryFunction;
       }
@@ -103,12 +142,15 @@ namespace bgslibrary
     class BGS_Register
     {
     public:
-      BGS_Register(std::string className)
-      {
+      BGS_Register(const std::string className) {
+        //debug_construction(BGS_Register);
         // register the class factory function
         BGS_Factory::Instance()->RegisterFactoryFunction(className,
           [](void) -> IBGS* { return new T(); });
       }
+      virtual ~BGS_Register() {
+        //debug_destruction(BGS_Register);
+      }
     };
   }
 }
diff --git a/src/package_bgs/IMBS/IMBS.cpp b/src/algorithms/IMBS/IMBS.cpp
similarity index 100%
rename from src/package_bgs/IMBS/IMBS.cpp
rename to src/algorithms/IMBS/IMBS.cpp
diff --git a/src/package_bgs/IMBS/IMBS.hpp b/src/algorithms/IMBS/IMBS.hpp
similarity index 99%
rename from src/package_bgs/IMBS/IMBS.hpp
rename to src/algorithms/IMBS/IMBS.hpp
index 4f5d066280c5786044a0395abb6c7690abeec862..7a89949e6a2a8d62e5b72e10bafef3f2d800f2e9 100644
--- a/src/package_bgs/IMBS/IMBS.hpp
+++ b/src/algorithms/IMBS/IMBS.hpp
@@ -7,6 +7,7 @@
 #include <opencv2/highgui/highgui.hpp>
 #include <opencv2/imgproc/imgproc.hpp>
 #include <opencv2/features2d/features2d.hpp>
+// opencv legacy includes
 #include <opencv2/imgproc/types_c.h>
 #include <opencv2/imgproc/imgproc_c.h>
 #include <opencv2/highgui/highgui_c.h>
diff --git a/src/package_bgs/IndependentMultimodal.cpp b/src/algorithms/IndependentMultimodal.cpp
similarity index 53%
rename from src/package_bgs/IndependentMultimodal.cpp
rename to src/algorithms/IndependentMultimodal.cpp
index 2ba7786d1ed0d74e01443b1be42c9141fff48a27..e5a69701ab0f98c7e6c024426bc03c4917ba05df 100644
--- a/src/package_bgs/IndependentMultimodal.cpp
+++ b/src/algorithms/IndependentMultimodal.cpp
@@ -4,16 +4,16 @@
 
 using namespace bgslibrary::algorithms;
 
-IndependentMultimodal::IndependentMultimodal() : fps(10)
+IndependentMultimodal::IndependentMultimodal() : 
+  IBGS(quote(IndependentMultimodal)), fps(10)
 {
-  std::cout << "IndependentMultimodal()" << std::endl;
+  debug_construction(IndependentMultimodal);
+  initLoadSaveConfig(algorithmName);
   pIMBS = new BackgroundSubtractorIMBS(fps);
-  setup("./config/IndependentMultimodal.xml");
 }
 
-IndependentMultimodal::~IndependentMultimodal()
-{
-  std::cout << "~IndependentMultimodal()" << std::endl;
+IndependentMultimodal::~IndependentMultimodal() {
+  debug_destruction(IndependentMultimodal);
   delete pIMBS;
 }
 
@@ -31,33 +31,23 @@ void IndependentMultimodal::process(const cv::Mat &img_input, cv::Mat &img_outpu
   img_background.copyTo(img_bgmodel);
 
 #ifndef MEX_COMPILE_FLAG
-  if (showOutput)
-  {
-    cv::imshow("IMBS FG", img_foreground);
-    cv::imshow("IMBS BG", img_background);
+  if (showOutput) {
+    cv::imshow(algorithmName + "_FG", img_foreground);
+    cv::imshow(algorithmName + "_BG", img_background);
   }
 #endif
 
   firstTime = false;
 }
 
-void IndependentMultimodal::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void IndependentMultimodal::save_config(cv::FileStorage &fs) {
+  fs << "fps" << fps;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void IndependentMultimodal::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void IndependentMultimodal::load_config(cv::FileStorage &fs) {
+  fs["fps"] >> fps;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/IndependentMultimodal.h b/src/algorithms/IndependentMultimodal.h
similarity index 65%
rename from src/package_bgs/IndependentMultimodal.h
rename to src/algorithms/IndependentMultimodal.h
index 1b78f9af3c8c378c12cdd99d51fea5e7ffe95421..2bbdbcfbb81642c563092aee0d6bffcab54e605a 100644
--- a/src/package_bgs/IndependentMultimodal.h
+++ b/src/algorithms/IndependentMultimodal.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 #include "opencv2/core/version.hpp"
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
@@ -12,7 +11,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class IndependentMultimodal : public IBGS, public ILoadSaveConfig
+    class IndependentMultimodal : public IBGS
     {
     private:
       BackgroundSubtractorIMBS* pIMBS;
@@ -25,11 +24,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<IndependentMultimodal> register_IndependentMultimodal("IndependentMultimodal");
+    bgs_register(IndependentMultimodal);
   }
 }
 
diff --git a/src/package_bgs/KDE.cpp b/src/algorithms/KDE.cpp
similarity index 84%
rename from src/package_bgs/KDE.cpp
rename to src/algorithms/KDE.cpp
index c481d4684eb695eb492867cfe624e1b81c0fad9e..e438ee7568dc577a4101de8107e7e2c4533a942f 100644
--- a/src/package_bgs/KDE.cpp
+++ b/src/algorithms/KDE.cpp
@@ -5,27 +5,27 @@
 using namespace bgslibrary::algorithms;
 
 KDE::KDE() :
-  SequenceLength(50), TimeWindowSize(100), SDEstimationFlag(1), lUseColorRatiosFlag(1),
+  IBGS(quote(KDE)),
+  SequenceLength(50), TimeWindowSize(100), 
+  SDEstimationFlag(1), lUseColorRatiosFlag(1),
   th(10e-8), alpha(0.3), framesToLearn(10), frameNumber(0)
 {
+  debug_construction(KDE);
+  initLoadSaveConfig(algorithmName);
   p = new NPBGSubtractor;
-  std::cout << "KDE()" << std::endl;
-  setup("./config/KDE.xml");
 }
 
-KDE::~KDE()
-{
+KDE::~KDE() {
+  debug_destruction(KDE);
   delete FGImage;
   delete p;
-  std::cout << "~KDE()" << std::endl;
 }
 
 void KDE::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
   init(img_input, img_output, img_bgmodel);
 
-  if (firstTime)
-  {
+  if (firstTime) {
     rows = img_input.size().height;
     cols = img_input.size().width;
     color_channels = img_input.channels();
@@ -53,16 +53,13 @@ void KDE::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bg
   }
 
   // Stores the first N frames to build the background model
-  if (frameNumber < framesToLearn)
-  {
+  if (frameNumber < framesToLearn) {
     p->AddFrame(img_input.data);
     frameNumber++;
   }
-  else
-  {
+  else {
     // Build the background model with first 10 frames
-    if (frameNumber == framesToLearn)
-    {
+    if (frameNumber == framesToLearn) {
       p->Estimation();
       frameNumber++;
     }
@@ -79,17 +76,14 @@ void KDE::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bg
 
 #ifndef MEX_COMPILE_FLAG
   if (showOutput)
-    cv::imshow("KDE", img_foreground);
+    cv::imshow(algorithmName + "_FG", img_foreground);
 #endif
 
   img_foreground.copyTo(img_output);
   img_background.copyTo(img_bgmodel);
 }
 
-void KDE::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void KDE::save_config(cv::FileStorage &fs) {
   fs << "framesToLearn" << framesToLearn;
   fs << "SequenceLength" << SequenceLength;
   fs << "TimeWindowSize" << TimeWindowSize;
@@ -98,15 +92,9 @@ void KDE::saveConfig()
   fs << "th" << th;
   fs << "alpha" << alpha;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void KDE::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void KDE::load_config(cv::FileStorage &fs) {
   fs["framesToLearn"] >> framesToLearn;
   fs["SequenceLength"] >> SequenceLength;
   fs["TimeWindowSize"] >> TimeWindowSize;
@@ -115,8 +103,6 @@ void KDE::loadConfig()
   fs["th"] >> th;
   fs["alpha"] >> alpha;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/KDE.h b/src/algorithms/KDE.h
similarity index 81%
rename from src/package_bgs/KDE.h
rename to src/algorithms/KDE.h
index 87dd74171637e282519936e6f74cb1c48e133f38..91e9fa181e325dc7925a2778c6edf9ca595ff70d 100644
--- a/src/package_bgs/KDE.h
+++ b/src/algorithms/KDE.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 #include "opencv2/core/version.hpp"
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
@@ -12,7 +11,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class KDE : public IBGS, public ILoadSaveConfig
+    class KDE : public IBGS
     {
     private:
       NPBGSubtractor *p;
@@ -39,11 +38,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<KDE> register_KDE("KDE");
+    bgs_register(KDE);
   }
 }
 
diff --git a/src/package_bgs/KDE/KernelTable.cpp b/src/algorithms/KDE/KernelTable.cpp
similarity index 100%
rename from src/package_bgs/KDE/KernelTable.cpp
rename to src/algorithms/KDE/KernelTable.cpp
diff --git a/src/package_bgs/KDE/KernelTable.h b/src/algorithms/KDE/KernelTable.h
similarity index 100%
rename from src/package_bgs/KDE/KernelTable.h
rename to src/algorithms/KDE/KernelTable.h
diff --git a/src/package_bgs/KDE/NPBGSubtractor.cpp b/src/algorithms/KDE/NPBGSubtractor.cpp
similarity index 100%
rename from src/package_bgs/KDE/NPBGSubtractor.cpp
rename to src/algorithms/KDE/NPBGSubtractor.cpp
diff --git a/src/package_bgs/KDE/NPBGSubtractor.h b/src/algorithms/KDE/NPBGSubtractor.h
similarity index 100%
rename from src/package_bgs/KDE/NPBGSubtractor.h
rename to src/algorithms/KDE/NPBGSubtractor.h
diff --git a/src/package_bgs/KDE/NPBGmodel.cpp b/src/algorithms/KDE/NPBGmodel.cpp
similarity index 100%
rename from src/package_bgs/KDE/NPBGmodel.cpp
rename to src/algorithms/KDE/NPBGmodel.cpp
diff --git a/src/package_bgs/KDE/NPBGmodel.h b/src/algorithms/KDE/NPBGmodel.h
similarity index 100%
rename from src/package_bgs/KDE/NPBGmodel.h
rename to src/algorithms/KDE/NPBGmodel.h
diff --git a/src/package_bgs/KNN.cpp b/src/algorithms/KNN.cpp
similarity index 78%
rename from src/package_bgs/KNN.cpp
rename to src/algorithms/KNN.cpp
index 5c58ca2bc5a932a5a9ea01da5c77c481f3da065a..332709498a65d80b7beba13e0d93999ae8d55459 100644
--- a/src/package_bgs/KNN.cpp
+++ b/src/algorithms/KNN.cpp
@@ -5,16 +5,17 @@
 using namespace bgslibrary::algorithms;
 
 KNN::KNN() :
-  history(500), nSamples(7), dist2Threshold(20.0f * 20.0f), knnSamples(0),
-  doShadowDetection(true), shadowValue(127), shadowThreshold(0.5f)
+  IBGS(quote(KNN)),
+  history(500), nSamples(7), dist2Threshold(20.0f * 20.0f),
+  knnSamples(0), doShadowDetection(true), shadowValue(127),
+  shadowThreshold(0.5f)
 {
-  std::cout << "KNN()" << std::endl;
-  setup("./config/KNN.xml");
+  debug_construction(KNN);
+  initLoadSaveConfig(algorithmName);
 }
 
-KNN::~KNN()
-{
-  std::cout << "~KNN()" << std::endl;
+KNN::~KNN() {
+  debug_destruction(KNN);
 }
 
 void KNN::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -47,10 +48,9 @@ void KNN::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bg
   knn->getBackgroundImage(img_background);
 
 #ifndef MEX_COMPILE_FLAG
-  if (showOutput)
-  {
-    cv::imshow("KNN FG", img_foreground);
-    cv::imshow("KNN BG", img_background);
+  if (showOutput) {
+    cv::imshow(algorithmName + "_FG", img_foreground);
+    cv::imshow(algorithmName + "_BG", img_background);
   }
 #endif
 
@@ -60,10 +60,7 @@ void KNN::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bg
   firstTime = false;
 }
 
-void KNN::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void KNN::save_config(cv::FileStorage &fs) {
   fs << "history" << history;
   fs << "nSamples" << nSamples;
   fs << "dist2Threshold" << dist2Threshold;
@@ -72,15 +69,9 @@ void KNN::saveConfig()
   fs << "shadowValue" << shadowValue;
   fs << "shadowThreshold" << shadowThreshold;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void KNN::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void KNN::load_config(cv::FileStorage &fs) {
   fs["history"] >> history;
   fs["nSamples"] >> nSamples;
   fs["dist2Threshold"] >> dist2Threshold;
@@ -89,8 +80,6 @@ void KNN::loadConfig()
   fs["shadowValue"] >> shadowValue;
   fs["shadowThreshold"] >> shadowThreshold;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/KNN.h b/src/algorithms/KNN.h
similarity index 78%
rename from src/package_bgs/KNN.h
rename to src/algorithms/KNN.h
index 45915445910f7883843f3a97c24e791c0fa699df..6950472604ee43f7b9ec238f8579a26a3340231a 100644
--- a/src/package_bgs/KNN.h
+++ b/src/algorithms/KNN.h
@@ -3,7 +3,6 @@
 #include <iostream>
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 #include "opencv2/core/version.hpp"
 #if CV_MAJOR_VERSION >= 3
@@ -15,7 +14,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class KNN : public IBGS, public ILoadSaveConfig
+    class KNN : public IBGS
     {
     private:
       cv::Ptr<cv::BackgroundSubtractorKNN> knn;
@@ -34,11 +33,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<KNN> register_KNN("KNN");
+    bgs_register(KNN);
   }
 }
 
diff --git a/src/package_bgs/LBAdaptiveSOM.cpp b/src/algorithms/LBAdaptiveSOM.cpp
similarity index 76%
rename from src/package_bgs/LBAdaptiveSOM.cpp
rename to src/algorithms/LBAdaptiveSOM.cpp
index 7d9a0a0d8c0881f33807a54c7312ec2fb8895373..a43e55acbc03a7316d75b20a94b29fd0fcf4ec48 100644
--- a/src/package_bgs/LBAdaptiveSOM.cpp
+++ b/src/algorithms/LBAdaptiveSOM.cpp
@@ -5,18 +5,18 @@
 using namespace bgslibrary::algorithms;
 
 LBAdaptiveSOM::LBAdaptiveSOM() :
+  IBGS(quote(LBAdaptiveSOM)),
   sensitivity(75), trainingSensitivity(245),
   learningRate(62), trainingLearningRate(255),
   trainingSteps(55)
 {
-  std::cout << "LBAdaptiveSOM()" << std::endl;
-  setup("./config/LBAdaptiveSOM.xml");
+  debug_construction(LBAdaptiveSOM);
+  initLoadSaveConfig(algorithmName);
 }
 
-LBAdaptiveSOM::~LBAdaptiveSOM()
-{
+LBAdaptiveSOM::~LBAdaptiveSOM() {
+  debug_destruction(LBAdaptiveSOM);
   delete m_pBGModel;
-  std::cout << "~LBAdaptiveSOM()" << std::endl;
 }
 
 void LBAdaptiveSOM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -25,8 +25,7 @@ void LBAdaptiveSOM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::M
 
   IplImage *frame = new IplImage(img_input);
 
-  if (firstTime)
-  {
+  if (firstTime) {
     int w = cvGetSize(frame).width;
     int h = cvGetSize(frame).height;
 
@@ -46,10 +45,9 @@ void LBAdaptiveSOM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::M
   img_background = cv::cvarrToMat(m_pBGModel->GetBG());
 
 #ifndef MEX_COMPILE_FLAG
-  if (showOutput)
-  {
-    cv::imshow("SOM Mask", img_foreground);
-    cv::imshow("SOM Model", img_background);
+  if (showOutput) {
+    cv::imshow(algorithmName + "_FG", img_foreground);
+    cv::imshow(algorithmName + "_BG", img_background);
   }
 #endif
 
@@ -61,33 +59,22 @@ void LBAdaptiveSOM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::M
   firstTime = false;
 }
 
-void LBAdaptiveSOM::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void LBAdaptiveSOM::save_config(cv::FileStorage &fs) {
   fs << "sensitivity" << sensitivity;
   fs << "trainingSensitivity" << trainingSensitivity;
   fs << "learningRate" << learningRate;
   fs << "trainingLearningRate" << trainingLearningRate;
   fs << "trainingSteps" << trainingSteps;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void LBAdaptiveSOM::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void LBAdaptiveSOM::load_config(cv::FileStorage &fs) {
   fs["sensitivity"] >> sensitivity;
   fs["trainingSensitivity"] >> trainingSensitivity;
   fs["learningRate"] >> learningRate;
   fs["trainingLearningRate"] >> trainingLearningRate;
   fs["trainingSteps"] >> trainingSteps;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/LBAdaptiveSOM.h b/src/algorithms/LBAdaptiveSOM.h
similarity index 74%
rename from src/package_bgs/LBAdaptiveSOM.h
rename to src/algorithms/LBAdaptiveSOM.h
index c4add4b77c59cd7b2b7ab2ebcb528463f2d72350..e1648960b2cd3104936eb952bd8726c8f1f6bd21 100644
--- a/src/package_bgs/LBAdaptiveSOM.h
+++ b/src/algorithms/LBAdaptiveSOM.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 #include "opencv2/core/version.hpp"
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
@@ -15,7 +14,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class LBAdaptiveSOM : public IBGS, public ILoadSaveConfig
+    class LBAdaptiveSOM : public IBGS
     {
     private:
       BGModel* m_pBGModel;
@@ -32,11 +31,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<LBAdaptiveSOM> register_LBAdaptiveSOM("LBAdaptiveSOM");
+    bgs_register(LBAdaptiveSOM);
   }
 }
 
diff --git a/src/package_bgs/LBFuzzyAdaptiveSOM.cpp b/src/algorithms/LBFuzzyAdaptiveSOM.cpp
similarity index 70%
rename from src/package_bgs/LBFuzzyAdaptiveSOM.cpp
rename to src/algorithms/LBFuzzyAdaptiveSOM.cpp
index b163d6543e2f945b602d15b2229169ce95d847a0..1eadf750568ff78c6a8b736f31cf62f6a9442039 100644
--- a/src/package_bgs/LBFuzzyAdaptiveSOM.cpp
+++ b/src/algorithms/LBFuzzyAdaptiveSOM.cpp
@@ -5,16 +5,17 @@
 using namespace bgslibrary::algorithms;
 
 LBFuzzyAdaptiveSOM::LBFuzzyAdaptiveSOM() :
-  sensitivity(90), trainingSensitivity(240), learningRate(38), trainingLearningRate(255), trainingSteps(81)
+  IBGS(quote(LBFuzzyAdaptiveSOM)),
+  sensitivity(90), trainingSensitivity(240), learningRate(38), 
+  trainingLearningRate(255), trainingSteps(81)
 {
-  std::cout << "LBFuzzyAdaptiveSOM()" << std::endl;
-  setup("./config/LBFuzzyAdaptiveSOM.xml");
+  debug_construction(LBFuzzyAdaptiveSOM);
+  initLoadSaveConfig(algorithmName);
 }
 
-LBFuzzyAdaptiveSOM::~LBFuzzyAdaptiveSOM()
-{
+LBFuzzyAdaptiveSOM::~LBFuzzyAdaptiveSOM() {
+  debug_destruction(LBFuzzyAdaptiveSOM);
   delete m_pBGModel;
-  std::cout << "~LBFuzzyAdaptiveSOM()" << std::endl;
 }
 
 void LBFuzzyAdaptiveSOM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -23,8 +24,7 @@ void LBFuzzyAdaptiveSOM::process(const cv::Mat &img_input, cv::Mat &img_output,
 
   IplImage *frame = new IplImage(img_input);
 
-  if (firstTime)
-  {
+  if (firstTime) {
     int w = cvGetSize(frame).width;
     int h = cvGetSize(frame).height;
 
@@ -44,10 +44,9 @@ void LBFuzzyAdaptiveSOM::process(const cv::Mat &img_input, cv::Mat &img_output,
   img_background = cv::cvarrToMat(m_pBGModel->GetBG());
 
 #ifndef MEX_COMPILE_FLAG
-  if (showOutput)
-  {
-    cv::imshow("FSOM Mask", img_foreground);
-    cv::imshow("FSOM Model", img_background);
+  if (showOutput) {
+    cv::imshow(algorithmName + "_FG", img_foreground);
+    cv::imshow(algorithmName + "_BG", img_background);
   }
 #endif
 
@@ -59,33 +58,22 @@ void LBFuzzyAdaptiveSOM::process(const cv::Mat &img_input, cv::Mat &img_output,
   firstTime = false;
 }
 
-void LBFuzzyAdaptiveSOM::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void LBFuzzyAdaptiveSOM::save_config(cv::FileStorage &fs) {
   fs << "sensitivity" << sensitivity;
   fs << "trainingSensitivity" << trainingSensitivity;
   fs << "learningRate" << learningRate;
   fs << "trainingLearningRate" << trainingLearningRate;
   fs << "trainingSteps" << trainingSteps;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void LBFuzzyAdaptiveSOM::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void LBFuzzyAdaptiveSOM::load_config(cv::FileStorage &fs) {
   fs["sensitivity"] >> sensitivity;
   fs["trainingSensitivity"] >> trainingSensitivity;
   fs["learningRate"] >> learningRate;
   fs["trainingLearningRate"] >> trainingLearningRate;
   fs["trainingSteps"] >> trainingSteps;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/LBFuzzyAdaptiveSOM.h b/src/algorithms/LBFuzzyAdaptiveSOM.h
similarity index 73%
rename from src/package_bgs/LBFuzzyAdaptiveSOM.h
rename to src/algorithms/LBFuzzyAdaptiveSOM.h
index 7169976b8ede4d240b8acca878ff4b0e50e0e0f5..6c9b4421de0d2fefe20d4b797f53f119455b4cfd 100644
--- a/src/package_bgs/LBFuzzyAdaptiveSOM.h
+++ b/src/algorithms/LBFuzzyAdaptiveSOM.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 #include "opencv2/core/version.hpp"
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
@@ -15,7 +14,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class LBFuzzyAdaptiveSOM : public IBGS, public ILoadSaveConfig
+    class LBFuzzyAdaptiveSOM : public IBGS
     {
     private:
       BGModel* m_pBGModel;
@@ -32,11 +31,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<LBFuzzyAdaptiveSOM> register_LBFuzzyAdaptiveSOM("LBFuzzyAdaptiveSOM");
+    bgs_register(LBFuzzyAdaptiveSOM);
   }
 }
 
diff --git a/src/package_bgs/LBFuzzyGaussian.cpp b/src/algorithms/LBFuzzyGaussian.cpp
similarity index 69%
rename from src/package_bgs/LBFuzzyGaussian.cpp
rename to src/algorithms/LBFuzzyGaussian.cpp
index e1127677d4b22a8f643abd96a45fc9fbdf01a1c9..95171913a037280b14984c358497c171140d9368 100644
--- a/src/package_bgs/LBFuzzyGaussian.cpp
+++ b/src/algorithms/LBFuzzyGaussian.cpp
@@ -5,16 +5,17 @@
 using namespace bgslibrary::algorithms;
 
 LBFuzzyGaussian::LBFuzzyGaussian() :
-  sensitivity(72), bgThreshold(162), learningRate(49), noiseVariance(195)
+  IBGS(quote(LBFuzzyGaussian)),
+  sensitivity(72), bgThreshold(162), 
+  learningRate(49), noiseVariance(195)
 {
-  std::cout << "LBFuzzyGaussian()" << std::endl;
-  setup("./config/LBFuzzyGaussian.xml");
+  debug_construction(LBFuzzyGaussian);
+  initLoadSaveConfig(algorithmName);
 }
 
-LBFuzzyGaussian::~LBFuzzyGaussian()
-{
+LBFuzzyGaussian::~LBFuzzyGaussian() {
+  debug_destruction(LBFuzzyGaussian);
   delete m_pBGModel;
-  std::cout << "~LBFuzzyGaussian()" << std::endl;
 }
 
 void LBFuzzyGaussian::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -23,8 +24,7 @@ void LBFuzzyGaussian::process(const cv::Mat &img_input, cv::Mat &img_output, cv:
 
   IplImage *frame = new IplImage(img_input);
 
-  if (firstTime)
-  {
+  if (firstTime) {
     int w = cvGetSize(frame).width;
     int h = cvGetSize(frame).height;
 
@@ -43,10 +43,9 @@ void LBFuzzyGaussian::process(const cv::Mat &img_input, cv::Mat &img_output, cv:
   img_background = cv::cvarrToMat(m_pBGModel->GetBG());
 
 #ifndef MEX_COMPILE_FLAG
-  if (showOutput)
-  {
-    cv::imshow("FG Mask", img_foreground);
-    cv::imshow("FG Model", img_background);
+  if (showOutput) {
+    cv::imshow(algorithmName + "_FG", img_foreground);
+    cv::imshow(algorithmName + "_BG", img_background);
   }
 #endif
 
@@ -58,31 +57,20 @@ void LBFuzzyGaussian::process(const cv::Mat &img_input, cv::Mat &img_output, cv:
   firstTime = false;
 }
 
-void LBFuzzyGaussian::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void LBFuzzyGaussian::save_config(cv::FileStorage &fs) {
   fs << "sensitivity" << sensitivity;
   fs << "bgThreshold" << bgThreshold;
   fs << "learningRate" << learningRate;
   fs << "noiseVariance" << noiseVariance;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void LBFuzzyGaussian::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void LBFuzzyGaussian::load_config(cv::FileStorage &fs) {
   fs["sensitivity"] >> sensitivity;
   fs["bgThreshold"] >> bgThreshold;
   fs["learningRate"] >> learningRate;
   fs["noiseVariance"] >> noiseVariance;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/LBFuzzyGaussian.h b/src/algorithms/LBFuzzyGaussian.h
similarity index 72%
rename from src/package_bgs/LBFuzzyGaussian.h
rename to src/algorithms/LBFuzzyGaussian.h
index 3d8c054dce2dda0913b96c3bb2ee32ddd872773e..7a48b71b650353c69ffebe86577c04def7df7a8b 100644
--- a/src/package_bgs/LBFuzzyGaussian.h
+++ b/src/algorithms/LBFuzzyGaussian.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 #include "opencv2/core/version.hpp"
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
@@ -15,7 +14,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class LBFuzzyGaussian : public IBGS, public ILoadSaveConfig
+    class LBFuzzyGaussian : public IBGS
     {
     private:
       BGModel* m_pBGModel;
@@ -31,11 +30,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<LBFuzzyGaussian> register_LBFuzzyGaussian("LBFuzzyGaussian");
+    bgs_register(LBFuzzyGaussian);
   }
 }
 
diff --git a/src/package_bgs/LBMixtureOfGaussians.cpp b/src/algorithms/LBMixtureOfGaussians.cpp
similarity index 68%
rename from src/package_bgs/LBMixtureOfGaussians.cpp
rename to src/algorithms/LBMixtureOfGaussians.cpp
index a18dad1a5c6da2d41c300353fc15e033bcddbf88..b04e0f63fb166584605aaf5b3e6d9b7efc56f257 100644
--- a/src/package_bgs/LBMixtureOfGaussians.cpp
+++ b/src/algorithms/LBMixtureOfGaussians.cpp
@@ -5,16 +5,17 @@
 using namespace bgslibrary::algorithms;
 
 LBMixtureOfGaussians::LBMixtureOfGaussians() :
-  sensitivity(81), bgThreshold(83), learningRate(59), noiseVariance(206)
+  IBGS(quote(LBMixtureOfGaussians)),
+  sensitivity(81), bgThreshold(83), 
+  learningRate(59), noiseVariance(206)
 {
-  std::cout << "LBMixtureOfGaussians()" << std::endl;
-  setup("./config/LBMixtureOfGaussians.xml");
+  debug_construction(LBMixtureOfGaussians);
+  initLoadSaveConfig(algorithmName);
 }
 
-LBMixtureOfGaussians::~LBMixtureOfGaussians()
-{
+LBMixtureOfGaussians::~LBMixtureOfGaussians() {
+  debug_destruction(LBMixtureOfGaussians);
   delete m_pBGModel;
-  std::cout << "~LBMixtureOfGaussians()" << std::endl;
 }
 
 void LBMixtureOfGaussians::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -23,8 +24,7 @@ void LBMixtureOfGaussians::process(const cv::Mat &img_input, cv::Mat &img_output
 
   IplImage *frame = new IplImage(img_input);
 
-  if (firstTime)
-  {
+  if (firstTime) {
     int w = cvGetSize(frame).width;
     int h = cvGetSize(frame).height;
 
@@ -43,10 +43,9 @@ void LBMixtureOfGaussians::process(const cv::Mat &img_input, cv::Mat &img_output
   img_background = cv::cvarrToMat(m_pBGModel->GetBG());
 
 #ifndef MEX_COMPILE_FLAG
-  if (showOutput)
-  {
-    cv::imshow("MOG Mask", img_foreground);
-    cv::imshow("MOG Model", img_background);
+  if (showOutput) {
+    cv::imshow(algorithmName + "_FG", img_foreground);
+    cv::imshow(algorithmName + "_BG", img_background);
   }
 #endif
 
@@ -58,31 +57,20 @@ void LBMixtureOfGaussians::process(const cv::Mat &img_input, cv::Mat &img_output
   firstTime = false;
 }
 
-void LBMixtureOfGaussians::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void LBMixtureOfGaussians::save_config(cv::FileStorage &fs) {
   fs << "sensitivity" << sensitivity;
   fs << "bgThreshold" << bgThreshold;
   fs << "learningRate" << learningRate;
   fs << "noiseVariance" << noiseVariance;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void LBMixtureOfGaussians::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void LBMixtureOfGaussians::load_config(cv::FileStorage &fs) {
   fs["sensitivity"] >> sensitivity;
   fs["bgThreshold"] >> bgThreshold;
   fs["learningRate"] >> learningRate;
   fs["noiseVariance"] >> noiseVariance;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/LBMixtureOfGaussians.h b/src/algorithms/LBMixtureOfGaussians.h
similarity index 71%
rename from src/package_bgs/LBMixtureOfGaussians.h
rename to src/algorithms/LBMixtureOfGaussians.h
index a78d3bba7d70495cc33aca1ecbd74ebdb1626571..0a5cf76c88a14a17c5fe2c109b0d73c459452fc3 100644
--- a/src/package_bgs/LBMixtureOfGaussians.h
+++ b/src/algorithms/LBMixtureOfGaussians.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 #include "opencv2/core/version.hpp"
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
@@ -15,7 +14,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class LBMixtureOfGaussians : public IBGS, public ILoadSaveConfig
+    class LBMixtureOfGaussians : public IBGS
     {
     private:
       BGModel* m_pBGModel;
@@ -31,11 +30,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<LBMixtureOfGaussians> register_LBMixtureOfGaussians("LBMixtureOfGaussians");
+    bgs_register(LBMixtureOfGaussians);
   }
 }
 
diff --git a/src/package_bgs/LBP_MRF.cpp b/src/algorithms/LBP_MRF.cpp
similarity index 74%
rename from src/package_bgs/LBP_MRF.cpp
rename to src/algorithms/LBP_MRF.cpp
index 2f4945b9cb1087908086b5c9f7fab8c386f08c80..1b2266e1adb3a49e06d4e234f2a1bb8696f490ff 100644
--- a/src/package_bgs/LBP_MRF.cpp
+++ b/src/algorithms/LBP_MRF.cpp
@@ -5,17 +5,17 @@
 using namespace bgslibrary::algorithms;
 
 LBP_MRF::LBP_MRF() :
+  IBGS(quote(LBP_MRF)),
   Detector(nullptr)
 {
-  std::cout << "LBP_MRF()" << std::endl;
-  setup("./config/LBP_MRF.xml");
+  debug_construction(LBP_MRF);
+  initLoadSaveConfig(algorithmName);
   Detector = new MotionDetection();
   Detector->SetMode(MotionDetection::md_LBPHistograms);
 }
 
-LBP_MRF::~LBP_MRF()
-{
-  std::cout << "~LBP_MRF()" << std::endl;
+LBP_MRF::~LBP_MRF() {
+  debug_destruction(LBP_MRF);
   delete Detector;
   Detector = nullptr;
 }
@@ -38,7 +38,7 @@ void LBP_MRF::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &im
 
 #ifndef MEX_COMPILE_FLAG
   if (showOutput)
-    cv::imshow("LBP-MRF FG", img_foreground);
+    cv::imshow(algorithmName + "_FG", img_foreground);
 #endif
 
   img_foreground.copyTo(img_output);
@@ -47,23 +47,12 @@ void LBP_MRF::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &im
   firstTime = false;
 }
 
-void LBP_MRF::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void LBP_MRF::save_config(cv::FileStorage &fs) {
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void LBP_MRF::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void LBP_MRF::load_config(cv::FileStorage &fs) {
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/LBP_MRF.h b/src/algorithms/LBP_MRF.h
similarity index 70%
rename from src/package_bgs/LBP_MRF.h
rename to src/algorithms/LBP_MRF.h
index 216b1489d4bd6694695d5375aa075a16a3c7a329..5e199a1c3211c30ec72b8c2ba6a9d7bd790fbc1f 100644
--- a/src/package_bgs/LBP_MRF.h
+++ b/src/algorithms/LBP_MRF.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 #include "opencv2/core/version.hpp"
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
@@ -12,7 +11,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class LBP_MRF : public IBGS, public ILoadSaveConfig
+    class LBP_MRF : public IBGS
     {
     private:
       MotionDetection* Detector;
@@ -25,11 +24,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<LBP_MRF> register_LBP_MRF("LBP_MRF");
+    bgs_register(LBP_MRF);
   }
 }
 
diff --git a/src/package_bgs/LBP_MRF/MEDefs.cpp b/src/algorithms/LBP_MRF/MEDefs.cpp
similarity index 100%
rename from src/package_bgs/LBP_MRF/MEDefs.cpp
rename to src/algorithms/LBP_MRF/MEDefs.cpp
diff --git a/src/package_bgs/LBP_MRF/MEDefs.hpp b/src/algorithms/LBP_MRF/MEDefs.hpp
similarity index 100%
rename from src/package_bgs/LBP_MRF/MEDefs.hpp
rename to src/algorithms/LBP_MRF/MEDefs.hpp
diff --git a/src/package_bgs/LBP_MRF/MEHistogram.cpp b/src/algorithms/LBP_MRF/MEHistogram.cpp
similarity index 100%
rename from src/package_bgs/LBP_MRF/MEHistogram.cpp
rename to src/algorithms/LBP_MRF/MEHistogram.cpp
diff --git a/src/package_bgs/LBP_MRF/MEHistogram.hpp b/src/algorithms/LBP_MRF/MEHistogram.hpp
similarity index 100%
rename from src/package_bgs/LBP_MRF/MEHistogram.hpp
rename to src/algorithms/LBP_MRF/MEHistogram.hpp
diff --git a/src/package_bgs/LBP_MRF/MEImage.cpp b/src/algorithms/LBP_MRF/MEImage.cpp
similarity index 100%
rename from src/package_bgs/LBP_MRF/MEImage.cpp
rename to src/algorithms/LBP_MRF/MEImage.cpp
diff --git a/src/package_bgs/LBP_MRF/MEImage.hpp b/src/algorithms/LBP_MRF/MEImage.hpp
similarity index 100%
rename from src/package_bgs/LBP_MRF/MEImage.hpp
rename to src/algorithms/LBP_MRF/MEImage.hpp
diff --git a/src/package_bgs/LBP_MRF/MotionDetection.cpp b/src/algorithms/LBP_MRF/MotionDetection.cpp
similarity index 100%
rename from src/package_bgs/LBP_MRF/MotionDetection.cpp
rename to src/algorithms/LBP_MRF/MotionDetection.cpp
diff --git a/src/package_bgs/LBP_MRF/MotionDetection.hpp b/src/algorithms/LBP_MRF/MotionDetection.hpp
similarity index 100%
rename from src/package_bgs/LBP_MRF/MotionDetection.hpp
rename to src/algorithms/LBP_MRF/MotionDetection.hpp
diff --git a/src/package_bgs/LBP_MRF/block.h b/src/algorithms/LBP_MRF/block.h
similarity index 100%
rename from src/package_bgs/LBP_MRF/block.h
rename to src/algorithms/LBP_MRF/block.h
diff --git a/src/package_bgs/LBP_MRF/graph.cpp b/src/algorithms/LBP_MRF/graph.cpp
similarity index 100%
rename from src/package_bgs/LBP_MRF/graph.cpp
rename to src/algorithms/LBP_MRF/graph.cpp
diff --git a/src/package_bgs/LBP_MRF/graph.h b/src/algorithms/LBP_MRF/graph.h
similarity index 100%
rename from src/package_bgs/LBP_MRF/graph.h
rename to src/algorithms/LBP_MRF/graph.h
diff --git a/src/package_bgs/LBP_MRF/maxflow.cpp b/src/algorithms/LBP_MRF/maxflow.cpp
similarity index 100%
rename from src/package_bgs/LBP_MRF/maxflow.cpp
rename to src/algorithms/LBP_MRF/maxflow.cpp
diff --git a/src/package_bgs/LBSP/BackgroundSubtractorLBSP.cpp b/src/algorithms/LBSP/BackgroundSubtractorLBSP.cpp
similarity index 100%
rename from src/package_bgs/LBSP/BackgroundSubtractorLBSP.cpp
rename to src/algorithms/LBSP/BackgroundSubtractorLBSP.cpp
diff --git a/src/package_bgs/LBSP/BackgroundSubtractorLBSP.h b/src/algorithms/LBSP/BackgroundSubtractorLBSP.h
similarity index 100%
rename from src/package_bgs/LBSP/BackgroundSubtractorLBSP.h
rename to src/algorithms/LBSP/BackgroundSubtractorLBSP.h
diff --git a/src/package_bgs/LBSP/BackgroundSubtractorLBSP_.cpp b/src/algorithms/LBSP/BackgroundSubtractorLBSP_.cpp
similarity index 100%
rename from src/package_bgs/LBSP/BackgroundSubtractorLBSP_.cpp
rename to src/algorithms/LBSP/BackgroundSubtractorLBSP_.cpp
diff --git a/src/package_bgs/LBSP/BackgroundSubtractorLBSP_.h b/src/algorithms/LBSP/BackgroundSubtractorLBSP_.h
similarity index 100%
rename from src/package_bgs/LBSP/BackgroundSubtractorLBSP_.h
rename to src/algorithms/LBSP/BackgroundSubtractorLBSP_.h
diff --git a/src/package_bgs/LBSP/BackgroundSubtractorLOBSTER.cpp b/src/algorithms/LBSP/BackgroundSubtractorLOBSTER.cpp
similarity index 100%
rename from src/package_bgs/LBSP/BackgroundSubtractorLOBSTER.cpp
rename to src/algorithms/LBSP/BackgroundSubtractorLOBSTER.cpp
diff --git a/src/package_bgs/LBSP/BackgroundSubtractorLOBSTER.h b/src/algorithms/LBSP/BackgroundSubtractorLOBSTER.h
similarity index 100%
rename from src/package_bgs/LBSP/BackgroundSubtractorLOBSTER.h
rename to src/algorithms/LBSP/BackgroundSubtractorLOBSTER.h
diff --git a/src/package_bgs/LBSP/BackgroundSubtractorPAWCS.cpp b/src/algorithms/LBSP/BackgroundSubtractorPAWCS.cpp
similarity index 100%
rename from src/package_bgs/LBSP/BackgroundSubtractorPAWCS.cpp
rename to src/algorithms/LBSP/BackgroundSubtractorPAWCS.cpp
diff --git a/src/package_bgs/LBSP/BackgroundSubtractorPAWCS.h b/src/algorithms/LBSP/BackgroundSubtractorPAWCS.h
similarity index 100%
rename from src/package_bgs/LBSP/BackgroundSubtractorPAWCS.h
rename to src/algorithms/LBSP/BackgroundSubtractorPAWCS.h
diff --git a/src/package_bgs/LBSP/BackgroundSubtractorSuBSENSE.cpp b/src/algorithms/LBSP/BackgroundSubtractorSuBSENSE.cpp
similarity index 100%
rename from src/package_bgs/LBSP/BackgroundSubtractorSuBSENSE.cpp
rename to src/algorithms/LBSP/BackgroundSubtractorSuBSENSE.cpp
diff --git a/src/package_bgs/LBSP/BackgroundSubtractorSuBSENSE.h b/src/algorithms/LBSP/BackgroundSubtractorSuBSENSE.h
similarity index 100%
rename from src/package_bgs/LBSP/BackgroundSubtractorSuBSENSE.h
rename to src/algorithms/LBSP/BackgroundSubtractorSuBSENSE.h
diff --git a/src/package_bgs/LBSP/DistanceUtils.h b/src/algorithms/LBSP/DistanceUtils.h
similarity index 100%
rename from src/package_bgs/LBSP/DistanceUtils.h
rename to src/algorithms/LBSP/DistanceUtils.h
diff --git a/src/package_bgs/LBSP/LBSP.cpp b/src/algorithms/LBSP/LBSP.cpp
similarity index 100%
rename from src/package_bgs/LBSP/LBSP.cpp
rename to src/algorithms/LBSP/LBSP.cpp
diff --git a/src/package_bgs/LBSP/LBSP.h b/src/algorithms/LBSP/LBSP.h
similarity index 100%
rename from src/package_bgs/LBSP/LBSP.h
rename to src/algorithms/LBSP/LBSP.h
diff --git a/src/package_bgs/LBSP/LBSP_.cpp b/src/algorithms/LBSP/LBSP_.cpp
similarity index 100%
rename from src/package_bgs/LBSP/LBSP_.cpp
rename to src/algorithms/LBSP/LBSP_.cpp
diff --git a/src/package_bgs/LBSP/LBSP_.h b/src/algorithms/LBSP/LBSP_.h
similarity index 100%
rename from src/package_bgs/LBSP/LBSP_.h
rename to src/algorithms/LBSP/LBSP_.h
diff --git a/src/package_bgs/LBSP/LBSP_16bits_dbcross_1ch.i b/src/algorithms/LBSP/LBSP_16bits_dbcross_1ch.i
similarity index 100%
rename from src/package_bgs/LBSP/LBSP_16bits_dbcross_1ch.i
rename to src/algorithms/LBSP/LBSP_16bits_dbcross_1ch.i
diff --git a/src/package_bgs/LBSP/LBSP_16bits_dbcross_3ch1t.i b/src/algorithms/LBSP/LBSP_16bits_dbcross_3ch1t.i
similarity index 100%
rename from src/package_bgs/LBSP/LBSP_16bits_dbcross_3ch1t.i
rename to src/algorithms/LBSP/LBSP_16bits_dbcross_3ch1t.i
diff --git a/src/package_bgs/LBSP/LBSP_16bits_dbcross_3ch3t.i b/src/algorithms/LBSP/LBSP_16bits_dbcross_3ch3t.i
similarity index 100%
rename from src/package_bgs/LBSP/LBSP_16bits_dbcross_3ch3t.i
rename to src/algorithms/LBSP/LBSP_16bits_dbcross_3ch3t.i
diff --git a/src/package_bgs/LBSP/LBSP_16bits_dbcross_s3ch.i b/src/algorithms/LBSP/LBSP_16bits_dbcross_s3ch.i
similarity index 100%
rename from src/package_bgs/LBSP/LBSP_16bits_dbcross_s3ch.i
rename to src/algorithms/LBSP/LBSP_16bits_dbcross_s3ch.i
diff --git a/src/package_bgs/LBSP/RandUtils.h b/src/algorithms/LBSP/RandUtils.h
similarity index 100%
rename from src/package_bgs/LBSP/RandUtils.h
rename to src/algorithms/LBSP/RandUtils.h
diff --git a/src/package_bgs/LBSimpleGaussian.cpp b/src/algorithms/LBSimpleGaussian.cpp
similarity index 71%
rename from src/package_bgs/LBSimpleGaussian.cpp
rename to src/algorithms/LBSimpleGaussian.cpp
index 0ce5d934b055214baa7814ac8adcb767fcb5a262..368af80c8102faec5659f008cdf49b4e8891f236 100644
--- a/src/package_bgs/LBSimpleGaussian.cpp
+++ b/src/algorithms/LBSimpleGaussian.cpp
@@ -5,16 +5,16 @@
 using namespace bgslibrary::algorithms;
 
 LBSimpleGaussian::LBSimpleGaussian() :
+  IBGS(quote(LBSimpleGaussian)),
   sensitivity(66), noiseVariance(162), learningRate(18)
 {
-  std::cout << "LBSimpleGaussian()" << std::endl;
-  setup("./config/LBSimpleGaussian.xml");
+  debug_construction(LBSimpleGaussian);
+  initLoadSaveConfig(algorithmName);
 }
 
-LBSimpleGaussian::~LBSimpleGaussian()
-{
+LBSimpleGaussian::~LBSimpleGaussian() {
+  debug_destruction(LBSimpleGaussian);
   delete m_pBGModel;
-  std::cout << "~LBSimpleGaussian()" << std::endl;
 }
 
 void LBSimpleGaussian::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -23,8 +23,7 @@ void LBSimpleGaussian::process(const cv::Mat &img_input, cv::Mat &img_output, cv
 
   IplImage *frame = new IplImage(img_input);
 
-  if (firstTime)
-  {
+  if (firstTime) {
     int w = cvGetSize(frame).width;
     int h = cvGetSize(frame).height;
 
@@ -42,10 +41,9 @@ void LBSimpleGaussian::process(const cv::Mat &img_input, cv::Mat &img_output, cv
   img_background = cv::cvarrToMat(m_pBGModel->GetBG());
 
 #ifndef MEX_COMPILE_FLAG
-  if (showOutput)
-  {
-    cv::imshow("SG Mask", img_foreground);
-    cv::imshow("SG Model", img_background);
+  if (showOutput) {
+    cv::imshow(algorithmName + "_FG", img_foreground);
+    cv::imshow(algorithmName + "_BG", img_background);
   }
 #endif
 
@@ -57,29 +55,18 @@ void LBSimpleGaussian::process(const cv::Mat &img_input, cv::Mat &img_output, cv
   firstTime = false;
 }
 
-void LBSimpleGaussian::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void LBSimpleGaussian::save_config(cv::FileStorage &fs) {
   fs << "sensitivity" << sensitivity;
   fs << "noiseVariance" << noiseVariance;
   fs << "learningRate" << learningRate;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void LBSimpleGaussian::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void LBSimpleGaussian::load_config(cv::FileStorage &fs) {
   fs["sensitivity"] >> sensitivity;
   fs["noiseVariance"] >> noiseVariance;
   fs["learningRate"] >> learningRate;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/LBSimpleGaussian.h b/src/algorithms/LBSimpleGaussian.h
similarity index 71%
rename from src/package_bgs/LBSimpleGaussian.h
rename to src/algorithms/LBSimpleGaussian.h
index 27eec9e9b158dfc72d16c65fe7409fcd03aa4aac..990751cf5214771b3f2daa0694687f7f776d7dd3 100644
--- a/src/package_bgs/LBSimpleGaussian.h
+++ b/src/algorithms/LBSimpleGaussian.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 #include "opencv2/core/version.hpp"
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
@@ -15,7 +14,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class LBSimpleGaussian : public IBGS, public ILoadSaveConfig
+    class LBSimpleGaussian : public IBGS
     {
     private:
       BGModel* m_pBGModel;
@@ -30,11 +29,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<LBSimpleGaussian> register_LBSimpleGaussian("LBSimpleGaussian");
+    bgs_register(LBSimpleGaussian);
   }
 }
 
diff --git a/src/package_bgs/LOBSTER.cpp b/src/algorithms/LOBSTER.cpp
similarity index 78%
rename from src/package_bgs/LOBSTER.cpp
rename to src/algorithms/LOBSTER.cpp
index 6b8178d9efebbcaaed46ab3b2231bb3bfa0ef6a1..937c31e75a10b214921a21861607714f519199d0 100644
--- a/src/package_bgs/LOBSTER.cpp
+++ b/src/algorithms/LOBSTER.cpp
@@ -3,6 +3,7 @@
 using namespace bgslibrary::algorithms;
 
 LOBSTER::LOBSTER() :
+  IBGS(quote(LOBSTER)),
   pLOBSTER(nullptr),
   fRelLBSPThreshold(BGSLOBSTER_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD),
   nLBSPThresholdOffset(BGSLOBSTER_DEFAULT_LBSP_OFFSET_SIMILARITY_THRESHOLD),
@@ -11,23 +12,21 @@ LOBSTER::LOBSTER() :
   nBGSamples(BGSLOBSTER_DEFAULT_NB_BG_SAMPLES),
   nRequiredBGSamples(BGSLOBSTER_DEFAULT_REQUIRED_NB_BG_SAMPLES)
 {
-  std::cout << "LOBSTER()" << std::endl;
-  setup("./config/LOBSTER.xml");
+  debug_construction(LOBSTER);
+  initLoadSaveConfig(algorithmName);
 }
 
-LOBSTER::~LOBSTER()
-{
+LOBSTER::~LOBSTER() {
+  debug_destruction(LOBSTER);
   if (pLOBSTER)
     delete pLOBSTER;
-  std::cout << "~LOBSTER()" << std::endl;
 }
 
 void LOBSTER::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
   init(img_input, img_output, img_bgmodel);
 
-  if (firstTime)
-  {
+  if (firstTime) {
     pLOBSTER = new BackgroundSubtractorLOBSTER(
       fRelLBSPThreshold, nLBSPThresholdOffset, nDescDistThreshold,
       nColorDistThreshold, nBGSamples, nRequiredBGSamples);
@@ -40,10 +39,9 @@ void LOBSTER::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &im
   pLOBSTER->getBackgroundImage(img_background);
 
 #ifndef MEX_COMPILE_FLAG
-  if (showOutput)
-  {
-    imshow("LOBSTER FG", img_foreground);
-    imshow("LOBSTER BG", img_background);
+  if (showOutput) {
+    cv::imshow(algorithmName + "_FG", img_foreground);
+    cv::imshow(algorithmName + "_BG", img_background);
   }
 #endif
 
@@ -51,10 +49,7 @@ void LOBSTER::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &im
   img_background.copyTo(img_bgmodel);
 }
 
-void LOBSTER::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void LOBSTER::save_config(cv::FileStorage &fs) {
   fs << "fRelLBSPThreshold" << fRelLBSPThreshold;
   fs << "nLBSPThresholdOffset" << nLBSPThresholdOffset;
   fs << "nDescDistThreshold" << nDescDistThreshold;
@@ -62,15 +57,9 @@ void LOBSTER::saveConfig()
   fs << "nBGSamples" << nBGSamples;
   fs << "nRequiredBGSamples" << nRequiredBGSamples;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void LOBSTER::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void LOBSTER::load_config(cv::FileStorage &fs) {
   fs["fRelLBSPThreshold"] >> fRelLBSPThreshold;
   fs["nLBSPThresholdOffset"] >> nLBSPThresholdOffset;
   fs["nDescDistThreshold"] >> nDescDistThreshold;
@@ -78,6 +67,4 @@ void LOBSTER::loadConfig()
   fs["nBGSamples"] >> nBGSamples;
   fs["nRequiredBGSamples"] >> nRequiredBGSamples;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
diff --git a/src/package_bgs/LOBSTER.h b/src/algorithms/LOBSTER.h
similarity index 73%
rename from src/package_bgs/LOBSTER.h
rename to src/algorithms/LOBSTER.h
index 36e39d6686db348e72cb151d29a2c41e54b9cfb9..324cd5230010e7796fa6015010a90ba56f7ff7a0 100644
--- a/src/package_bgs/LOBSTER.h
+++ b/src/algorithms/LOBSTER.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 #include "LBSP/BackgroundSubtractorLOBSTER.h"
 
@@ -9,7 +8,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class LOBSTER : public IBGS, public ILoadSaveConfig
+    class LOBSTER : public IBGS
     {
     private:
       BackgroundSubtractorLOBSTER* pLOBSTER;
@@ -27,10 +26,10 @@ namespace bgslibrary
 
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<LOBSTER> register_LOBSTER("LOBSTER");
+    bgs_register(LOBSTER);
   }
 }
diff --git a/src/package_bgs/MixtureOfGaussianV1.cpp b/src/algorithms/MixtureOfGaussianV1.cpp
similarity index 75%
rename from src/package_bgs/MixtureOfGaussianV1.cpp
rename to src/algorithms/MixtureOfGaussianV1.cpp
index 4094f393eb44556c570f12b54a94b55a61692514..d2cb1bb128dcd17bb24994451feebd2aaadce095 100644
--- a/src/package_bgs/MixtureOfGaussianV1.cpp
+++ b/src/algorithms/MixtureOfGaussianV1.cpp
@@ -5,15 +5,15 @@
 using namespace bgslibrary::algorithms;
 
 MixtureOfGaussianV1::MixtureOfGaussianV1() :
+  IBGS(quote(MixtureOfGaussianV1)),
   alpha(0.05), enableThreshold(true), threshold(15)
 {
-  std::cout << "MixtureOfGaussianV1()" << std::endl;
-  setup("./config/MixtureOfGaussianV1.xml");
+  debug_construction(MixtureOfGaussianV1);
+  initLoadSaveConfig(algorithmName);
 }
 
-MixtureOfGaussianV1::~MixtureOfGaussianV1()
-{
-  std::cout << "~MixtureOfGaussianV1()" << std::endl;
+MixtureOfGaussianV1::~MixtureOfGaussianV1() {
+  debug_destruction(MixtureOfGaussianV1);
 }
 
 void MixtureOfGaussianV1::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -45,10 +45,9 @@ void MixtureOfGaussianV1::process(const cv::Mat &img_input, cv::Mat &img_output,
     img_background = cv::Mat::zeros(img_input.size(), img_input.type());
 
 #ifndef MEX_COMPILE_FLAG
-  if (showOutput)
-  {
-    cv::imshow("GMM FG (KadewTraKuPong&Bowden)", img_foreground);
-    cv::imshow("GMM BG (KadewTraKuPong&Bowden)", img_background);
+  if (showOutput) {
+    cv::imshow(algorithmName + "_FG", img_foreground);
+    cv::imshow(algorithmName + "_BG", img_background);
   }
 #endif
 
@@ -58,29 +57,18 @@ void MixtureOfGaussianV1::process(const cv::Mat &img_input, cv::Mat &img_output,
   firstTime = false;
 }
 
-void MixtureOfGaussianV1::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void MixtureOfGaussianV1::save_config(cv::FileStorage &fs) {
   fs << "alpha" << alpha;
   fs << "enableThreshold" << enableThreshold;
   fs << "threshold" << threshold;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void MixtureOfGaussianV1::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void MixtureOfGaussianV1::load_config(cv::FileStorage &fs) {
   fs["alpha"] >> alpha;
   fs["enableThreshold"] >> enableThreshold;
   fs["threshold"] >> threshold;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/MixtureOfGaussianV1.h b/src/algorithms/MixtureOfGaussianV1.h
similarity index 69%
rename from src/package_bgs/MixtureOfGaussianV1.h
rename to src/algorithms/MixtureOfGaussianV1.h
index 8c2ba86c8b035e7efd17c1c1d5591297cf67e9ee..42c59774757add3871d2f2d1dad2d816e20437a5 100644
--- a/src/package_bgs/MixtureOfGaussianV1.h
+++ b/src/algorithms/MixtureOfGaussianV1.h
@@ -8,13 +8,12 @@
 #include <opencv2/video/background_segm.hpp>
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 namespace bgslibrary
 {
   namespace algorithms
   {
-    class MixtureOfGaussianV1 : public IBGS, public ILoadSaveConfig
+    class MixtureOfGaussianV1 : public IBGS
     {
     private:
       cv::BackgroundSubtractorMOG mog;
@@ -29,11 +28,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<MixtureOfGaussianV1> register_MixtureOfGaussianV1("MixtureOfGaussianV1");
+    bgs_register(MixtureOfGaussianV1);
   }
 }
 
diff --git a/src/package_bgs/MixtureOfGaussianV2.cpp b/src/algorithms/MixtureOfGaussianV2.cpp
similarity index 80%
rename from src/package_bgs/MixtureOfGaussianV2.cpp
rename to src/algorithms/MixtureOfGaussianV2.cpp
index a68e495c87f0d6883387fd4c5ddaccde321dcecc..50244fb1f04841c4fc2db430acd505cff0e64cdf 100644
--- a/src/package_bgs/MixtureOfGaussianV2.cpp
+++ b/src/algorithms/MixtureOfGaussianV2.cpp
@@ -3,15 +3,15 @@
 using namespace bgslibrary::algorithms;
 
 MixtureOfGaussianV2::MixtureOfGaussianV2() :
+  IBGS(quote(MixtureOfGaussianV2)),
   alpha(0.05), enableThreshold(true), threshold(15)
 {
-  std::cout << "MixtureOfGaussianV2()" << std::endl;
-  setup("./config/MixtureOfGaussianV2.xml");
+  debug_construction(MixtureOfGaussianV2);
+  initLoadSaveConfig(algorithmName);
 }
 
-MixtureOfGaussianV2::~MixtureOfGaussianV2()
-{
-  std::cout << "~MixtureOfGaussianV2()" << std::endl;
+MixtureOfGaussianV2::~MixtureOfGaussianV2() {
+  debug_destruction(MixtureOfGaussianV2);
 }
 
 void MixtureOfGaussianV2::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -53,10 +53,9 @@ void MixtureOfGaussianV2::process(const cv::Mat &img_input, cv::Mat &img_output,
     cv::threshold(img_foreground, img_foreground, threshold, 255, cv::THRESH_BINARY);
 
 #ifndef MEX_COMPILE_FLAG
-  if (showOutput)
-  {
-    cv::imshow("GMM FG (Zivkovic&Heijden)", img_foreground);
-    cv::imshow("GMM BG (Zivkovic&Heijden)", img_background);
+  if (showOutput) {
+    cv::imshow(algorithmName + "_FG", img_foreground);
+    cv::imshow(algorithmName + "_BG", img_background);
   }
 #endif
 
@@ -66,27 +65,16 @@ void MixtureOfGaussianV2::process(const cv::Mat &img_input, cv::Mat &img_output,
   firstTime = false;
 }
 
-void MixtureOfGaussianV2::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void MixtureOfGaussianV2::save_config(cv::FileStorage &fs) {
   fs << "alpha" << alpha;
   fs << "enableThreshold" << enableThreshold;
   fs << "threshold" << threshold;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void MixtureOfGaussianV2::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void MixtureOfGaussianV2::load_config(cv::FileStorage &fs) {
   fs["alpha"] >> alpha;
   fs["enableThreshold"] >> enableThreshold;
   fs["threshold"] >> threshold;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
diff --git a/src/package_bgs/MixtureOfGaussianV2.h b/src/algorithms/MixtureOfGaussianV2.h
similarity index 71%
rename from src/package_bgs/MixtureOfGaussianV2.h
rename to src/algorithms/MixtureOfGaussianV2.h
index 7d60729335a32bec38ab0b0fcaf4b2546e9c9e88..5bd0d445c3d1da8b07367d745e546bf50a260130 100644
--- a/src/package_bgs/MixtureOfGaussianV2.h
+++ b/src/algorithms/MixtureOfGaussianV2.h
@@ -5,13 +5,12 @@
 #include <opencv2/video/background_segm.hpp>
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 namespace bgslibrary
 {
   namespace algorithms
   {
-    class MixtureOfGaussianV2 : public IBGS, public ILoadSaveConfig
+    class MixtureOfGaussianV2 : public IBGS
     {
     private:
 #if CV_MAJOR_VERSION == 2
@@ -30,10 +29,10 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<MixtureOfGaussianV2> register_MixtureOfGaussianV2("MixtureOfGaussianV2");
+    bgs_register(MixtureOfGaussianV2);
   }
 }
diff --git a/src/package_bgs/MultiCue.cpp b/src/algorithms/MultiCue.cpp
similarity index 99%
rename from src/package_bgs/MultiCue.cpp
rename to src/algorithms/MultiCue.cpp
index de5016d81b708deac74b422db0203dbbdefd7ac3..a961678e32f645455668348fef05586fbdb6df33 100644
--- a/src/package_bgs/MultiCue.cpp
+++ b/src/algorithms/MultiCue.cpp
@@ -5,8 +5,10 @@
 using namespace bgslibrary::algorithms::libMultiCue;
 using namespace bgslibrary::algorithms;
 
-MultiCue::MultiCue()
+MultiCue::MultiCue() :
+  IBGS(quote(MultiCue))
 {
+  debug_construction(MultiCue);
   //----------------------------------
   //	User adjustable parameters
   //----------------------------------
@@ -41,14 +43,12 @@ MultiCue::MultiCue()
   g_bModelMemAllocated = FALSE;									//To handle memory..
   g_bNonModelMemAllocated = FALSE;								//To handle memory..
 
-  std::cout << "MultiCue()" << std::endl;
-  setup("./config/MultiCue.xml");
+  initLoadSaveConfig(algorithmName);
 }
 
-MultiCue::~MultiCue(void)
-{
+MultiCue::~MultiCue() {
+  debug_destruction(MultiCue);
   Destroy();
-  std::cout << "~MultiCue()" << std::endl;
 }
 
 //-----------------------------------------------------------------------------------------------------------------------------------------//
@@ -63,14 +63,12 @@ void MultiCue::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &i
   IplImage* frame = new IplImage(img_input);
   IplImage* result_image = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 3);
   cvSetZero(result_image);
-  if (g_iFrameCount <= g_iTrainingPeriod)
-  {
+  if (g_iFrameCount <= g_iTrainingPeriod) {
     BackgroundModeling_Par(frame);
     g_iFrameCount++;
   }
   //--Step2: Background Subtraction--//
-  else
-  {
+  else {
     g_bForegroundMapEnable = FALSE;
 
     ForegroundExtraction(frame);
@@ -87,7 +85,7 @@ void MultiCue::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &i
 
 #ifndef MEX_COMPILE_FLAG
   if (showOutput)
-    cv::imshow("MultiCue FG", img_foreground);
+    cv::imshow(algorithmName + "_FG", img_foreground);
 #endif
 
   img_foreground.copyTo(img_output);
@@ -96,10 +94,7 @@ void MultiCue::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &i
   firstTime = false;
 }
 
-void MultiCue::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void MultiCue::save_config(cv::FileStorage &fs) {
   fs << "g_fLearningRate" << g_fLearningRate;
   fs << "g_iAbsortionPeriod" << g_iAbsortionPeriod;
   fs << "g_iC_ModelThreshold" << g_iC_ModelThreshold;
@@ -114,15 +109,9 @@ void MultiCue::saveConfig()
   fs << "g_iRWidth" << g_iRWidth;
   fs << "g_iRHeight" << g_iRHeight;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void MultiCue::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void MultiCue::load_config(cv::FileStorage &fs) {
   fs["g_fLearningRate"] >> g_fLearningRate;
   fs["g_iAbsortionPeriod"] >> g_iAbsortionPeriod;
   fs["g_iC_ModelThreshold"] >> g_iC_ModelThreshold;
@@ -137,8 +126,6 @@ void MultiCue::loadConfig()
   fs["g_iRWidth"] >> g_iRWidth;
   fs["g_iRHeight"] >> g_iRHeight;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 //-----------------------------------------------------------------------------------------------------------------------------------------//
diff --git a/src/package_bgs/MultiCue.h b/src/algorithms/MultiCue.h
similarity index 98%
rename from src/package_bgs/MultiCue.h
rename to src/algorithms/MultiCue.h
index 08900abdc3542ebc3542007653a63f5fbe1d4095..31e31b16b82df8af9cfa6bb3925627e831038557 100644
--- a/src/package_bgs/MultiCue.h
+++ b/src/algorithms/MultiCue.h
@@ -30,7 +30,6 @@ typedef int BOOL;
 #include <opencv2/opencv.hpp>
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 //------------------------------------Structure Lists-------------------------------------//
 namespace bgslibrary
@@ -109,11 +108,11 @@ namespace bgslibrary
   {
     using namespace bgslibrary::algorithms::libMultiCue;
 
-    class MultiCue : public IBGS, public ILoadSaveConfig
+    class MultiCue : public IBGS
     {
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
 
     public:
       MultiCue();
@@ -239,7 +238,7 @@ namespace bgslibrary
       short** g_aCContinuousCnt;					//To handle cache-book
     };
 
-    static BGS_Register<MultiCue> register_MultiCue("MultiCue");
+    bgs_register(MultiCue);
   }
 }
 
diff --git a/src/package_bgs/MultiLayer.cpp b/src/algorithms/MultiLayer.cpp
similarity index 79%
rename from src/package_bgs/MultiLayer.cpp
rename to src/algorithms/MultiLayer.cpp
index caf409c340040cfee576427362c3564e44abd5eb..89aa30a2fc2e60d1afbe5652225f38b2993b7f4a 100644
--- a/src/package_bgs/MultiLayer.cpp
+++ b/src/algorithms/MultiLayer.cpp
@@ -5,35 +5,32 @@
 using namespace bgslibrary::algorithms;
 
 MultiLayer::MultiLayer() :
-  frameNumber(0), saveModel(false), disableDetectMode(true), disableLearning(false),
+  IBGS(quote(MultiLayer)),
+  frameNumber(0), saveModel(false),
+  disableDetectMode(true), disableLearning(false),
   detectAfter(0), bg_model_preload(""), loadDefaultParams(true)
 {
-  std::cout << "MultiLayer()" << std::endl;
-  setup("./config/MultiLayer.xml");
+  debug_construction(MultiLayer);
+  initLoadSaveConfig(algorithmName);
 }
 
-MultiLayer::~MultiLayer()
-{
+MultiLayer::~MultiLayer() {
+  debug_destruction(MultiLayer);
   finish();
-  std::cout << "~MultiLayer()" << std::endl;
 }
 
-void MultiLayer::setStatus(Status _status)
-{
+void MultiLayer::setStatus(Status _status) {
   status = _status;
 }
 
-void MultiLayer::finish()
-{
-  if (bg_model_preload.empty())
-  {
-    bg_model_preload = "./MultiLayerModel.yml";
+void MultiLayer::finish() {
+  if (bg_model_preload.empty()) {
+    bg_model_preload = "./" + algorithmName + ".yml";
     saveConfig();
   }
 
-  if (status == MLBGS_LEARN && saveModel == true)
-  {
-    std::cout << "MultiLayer saving background model: " << bg_model_preload << std::endl;
+  if (status == MLBGS_LEARN && saveModel == true) {
+    std::cout << algorithmName + " saving background model: " << bg_model_preload << std::endl;
     BGS->Save(bg_model_preload.c_str());
   }
 
@@ -52,16 +49,15 @@ void MultiLayer::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat
   init(img_input, img_output, img_bgmodel);
   CvSize img_size = cvSize(cvCeil((double)img_input.size().width), cvCeil((double)img_input.size().height));
 
-  if (firstTime)
-  {
+  if (firstTime) {
     if (disableDetectMode)
       status = MLBGS_LEARN;
 
     if (status == MLBGS_LEARN)
-      std::cout << "MultiLayer in LEARN mode" << std::endl;
+      std::cout << algorithmName + " in LEARN mode" << std::endl;
 
     if (status == MLBGS_DETECT)
-      std::cout << "MultiLayer in DETECT mode" << std::endl;
+      std::cout << algorithmName + " in DETECT mode" << std::endl;
 
     org_img = new IplImage(img_input);
 
@@ -77,26 +73,22 @@ void MultiLayer::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat
     BGS->SetForegroundMaskImage(fg_mask_img);
     BGS->SetForegroundProbImage(fg_prob_img);
 
-    if (bg_model_preload.empty() == false)
-    {
-      std::cout << "MultiLayer loading background model: " << bg_model_preload << std::endl;
+    if (bg_model_preload.empty() == false) {
+      std::cout << algorithmName + " loading background model: " << bg_model_preload << std::endl;
       BGS->Load(bg_model_preload.c_str());
     }
 
-    if (status == MLBGS_DETECT)
-    {
+    if (status == MLBGS_DETECT) {
       BGS->m_disableLearning = disableLearning;
 
       if (disableLearning)
-        std::cout << "MultiLayer disabled learning in DETECT mode" << std::endl;
+        std::cout << algorithmName + " disabled learning in DETECT mode" << std::endl;
       else
-        std::cout << "MultiLayer enabled learning in DETECT mode" << std::endl;
+        std::cout << algorithmName + " enabled learning in DETECT mode" << std::endl;
     }
 
-    if (loadDefaultParams)
-    {
-      std::cout << "MultiLayer loading default params" << std::endl;
-
+    if (loadDefaultParams) {
+      std::cout << algorithmName + " loading default params" << std::endl;
       max_mode_num = 5;
       weight_updating_constant = 5.0;
       texture_weight = 0.5;
@@ -113,7 +105,7 @@ void MultiLayer::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat
       bilater_filter_sigma_r = 0.1f;
     }
     else
-      std::cout << "MultiLayer loading config params" << std::endl;
+      std::cout << algorithmName + " loading config params" << std::endl;
 
     BGS->m_nMaxLBPModeNum = max_mode_num;
     BGS->m_fWeightUpdatingConstant = weight_updating_constant;
@@ -130,8 +122,7 @@ void MultiLayer::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat
     BGS->m_fSigmaS = bilater_filter_sigma_s;
     BGS->m_fSigmaR = bilater_filter_sigma_r;
 
-    if (loadDefaultParams)
-    {
+    if (loadDefaultParams) {
       //frame_duration = 1.0 / 30.0;
       //frame_duration = 1.0 / 25.0;
       frame_duration = 1.0f / 10.0f;
@@ -139,32 +130,26 @@ void MultiLayer::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat
 
     BGS->SetFrameRate(frame_duration);
 
-    if (status == MLBGS_LEARN)
-    {
-      if (loadDefaultParams)
-      {
+    if (status == MLBGS_LEARN) {
+      if (loadDefaultParams) {
         mode_learn_rate_per_second = 0.5;
         weight_learn_rate_per_second = 0.5;
         init_mode_weight = 0.05f;
       }
-      else
-      {
+      else {
         mode_learn_rate_per_second = learn_mode_learn_rate_per_second;
         weight_learn_rate_per_second = learn_weight_learn_rate_per_second;
         init_mode_weight = learn_init_mode_weight;
       }
     }
 
-    if (status == MLBGS_DETECT)
-    {
-      if (loadDefaultParams)
-      {
+    if (status == MLBGS_DETECT) {
+      if (loadDefaultParams) {
         mode_learn_rate_per_second = 0.01f;
         weight_learn_rate_per_second = 0.01f;
         init_mode_weight = 0.001f;
       }
-      else
-      {
+      else {
         mode_learn_rate_per_second = detect_mode_learn_rate_per_second;
         weight_learn_rate_per_second = detect_weight_learn_rate_per_second;
         init_mode_weight = detect_init_mode_weight;
@@ -180,10 +165,8 @@ void MultiLayer::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat
   //cvCopy(inputImage, img);
   //delete inputImage;
 
-  if (detectAfter > 0 && detectAfter == frameNumber)
-  {
-    std::cout << "MultiLayer in DETECT mode" << std::endl;
-
+  if (detectAfter > 0 && detectAfter == frameNumber) {
+    std::cout << algorithmName + " in DETECT mode" << std::endl;
     status = MLBGS_DETECT;
 
     mode_learn_rate_per_second = 0.01f;
@@ -191,13 +174,12 @@ void MultiLayer::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat
     init_mode_weight = 0.001f;
 
     BGS->SetParameters(max_mode_num, mode_learn_rate_per_second, weight_learn_rate_per_second, init_mode_weight);
-
     BGS->m_disableLearning = disableLearning;
 
     if (disableLearning)
-      std::cout << "MultiLayer disabled learning in DETECT mode" << std::endl;
+      std::cout << algorithmName + " disabled learning in DETECT mode" << std::endl;
     else
-      std::cout << "MultiLayer enabled learning in DETECT mode" << std::endl;
+      std::cout << algorithmName + " enabled learning in DETECT mode" << std::endl;
   }
 
   IplImage* img = new IplImage(img_input);
@@ -216,10 +198,9 @@ void MultiLayer::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat
   img_background = cv::cvarrToMat(bg_img);
 
 #ifndef MEX_COMPILE_FLAG
-  if (showOutput)
-  {
-    cv::imshow("MLBGS Layers", img_merged);
-    cv::imshow("MLBGS FG Mask", img_foreground);
+  if (showOutput) {
+    cv::imshow(algorithmName + "_LAYERS", img_merged);
+    cv::imshow(algorithmName + "_FG", img_foreground);
   }
 #endif
 
@@ -233,10 +214,7 @@ void MultiLayer::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat
   frameNumber++;
 }
 
-void MultiLayer::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void MultiLayer::save_config(cv::FileStorage &fs) {
   fs << "preloadModel" << bg_model_preload;
   fs << "saveModel" << saveModel;
   fs << "detectAfter" << detectAfter;
@@ -244,7 +222,6 @@ void MultiLayer::saveConfig()
   fs << "disableLearningInDetecMode" << disableLearning;
   fs << "loadDefaultParams" << loadDefaultParams;
   fs << "frame_duration" << frame_duration;
-  
   fs << "max_mode_num" << max_mode_num;
   fs << "weight_updating_constant" << weight_updating_constant;
   fs << "texture_weight" << texture_weight;
@@ -259,25 +236,16 @@ void MultiLayer::saveConfig()
   fs << "highlight_rate" << highlight_rate;
   fs << "bilater_filter_sigma_s" << bilater_filter_sigma_s;
   fs << "bilater_filter_sigma_r" << bilater_filter_sigma_r;
-  
   fs << "learn_mode_learn_rate_per_second" << learn_mode_learn_rate_per_second;
   fs << "learn_weight_learn_rate_per_second" << learn_weight_learn_rate_per_second;
   fs << "learn_init_mode_weight" << learn_init_mode_weight;
-  
   fs << "detect_mode_learn_rate_per_second" << detect_mode_learn_rate_per_second;
   fs << "detect_weight_learn_rate_per_second" << detect_weight_learn_rate_per_second;
   fs << "detect_init_mode_weight" << detect_init_mode_weight;
-  
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void MultiLayer::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void MultiLayer::load_config(cv::FileStorage &fs) {
   fs["preloadModel"] >> bg_model_preload;
   fs["saveModel"] >> saveModel;
   fs["detectAfter"] >> detectAfter;
@@ -285,7 +253,6 @@ void MultiLayer::loadConfig()
   fs["disableLearningInDetecMode"] >> disableLearning;
   fs["loadDefaultParams"] >> loadDefaultParams;
   fs["frame_duration"] >> frame_duration;
-  
   fs["max_mode_num"] >> max_mode_num;
   fs["weight_updating_constant"] >> weight_updating_constant;
   fs["texture_weight"] >> texture_weight;
@@ -300,18 +267,13 @@ void MultiLayer::loadConfig()
   fs["highlight_rate"] >> highlight_rate;
   fs["bilater_filter_sigma_s"] >> bilater_filter_sigma_s;
   fs["bilater_filter_sigma_r"] >> bilater_filter_sigma_r;
-  
   fs["learn_mode_learn_rate_per_second"] >> learn_mode_learn_rate_per_second;
   fs["learn_weight_learn_rate_per_second"] >> learn_weight_learn_rate_per_second;
   fs["learn_init_mode_weight"] >> learn_init_mode_weight;
-  
   fs["detect_mode_learn_rate_per_second"] >> detect_mode_learn_rate_per_second;
   fs["detect_weight_learn_rate_per_second"] >> detect_weight_learn_rate_per_second;
   fs["detect_init_mode_weight"] >> detect_init_mode_weight;
-  
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/MultiLayer.h b/src/algorithms/MultiLayer.h
similarity index 90%
rename from src/package_bgs/MultiLayer.h
rename to src/algorithms/MultiLayer.h
index 0acc79ff98677f63a8ee79d058905ab1279403ba..26e33286d592c7e921f57f4f497f06f194a90bac 100644
--- a/src/package_bgs/MultiLayer.h
+++ b/src/algorithms/MultiLayer.h
@@ -4,14 +4,13 @@
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 #include "MultiLayer/CMultiLayerBGS.h"
 
 namespace bgslibrary
 {
   namespace algorithms
   {
-    class MultiLayer : public IBGS, public ILoadSaveConfig
+    class MultiLayer : public IBGS
     {
     public:
       enum Status
@@ -80,11 +79,11 @@ namespace bgslibrary
 
     private:
       void finish();
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<MultiLayer> register_MultiLayer("MultiLayer");
+    bgs_register(MultiLayer);
   }
 }
 
diff --git a/src/package_bgs/MultiLayer/BGS.h b/src/algorithms/MultiLayer/BGS.h
similarity index 99%
rename from src/package_bgs/MultiLayer/BGS.h
rename to src/algorithms/MultiLayer/BGS.h
index f1a478a65ad3e8478a7e8932fbff5fc8b0162f76..2ae1280a827f33b097c8e30ba1688398fd6e988e 100644
--- a/src/package_bgs/MultiLayer/BGS.h
+++ b/src/algorithms/MultiLayer/BGS.h
@@ -1,5 +1,6 @@
 #pragma once
 
+// opencv legacy includes
 #include "OpenCvLegacyIncludes.h"
 
 #define MAX_LBP_MODE_NUM	5
diff --git a/src/package_bgs/MultiLayer/BackgroundSubtractionAPI.h b/src/algorithms/MultiLayer/BackgroundSubtractionAPI.h
similarity index 99%
rename from src/package_bgs/MultiLayer/BackgroundSubtractionAPI.h
rename to src/algorithms/MultiLayer/BackgroundSubtractionAPI.h
index 0462d4056c5d71c25bfa6178a8e5eb70d0d7139a..39223986b73c3710cf1bd3c966ee6415771cdb82 100644
--- a/src/package_bgs/MultiLayer/BackgroundSubtractionAPI.h
+++ b/src/algorithms/MultiLayer/BackgroundSubtractionAPI.h
@@ -1,5 +1,6 @@
 #pragma once
 
+// opencv legacy includes
 #include "OpenCvLegacyIncludes.h"
 
 class CBackgroundSubtractionAPI
diff --git a/src/package_bgs/MultiLayer/BlobExtraction.cpp b/src/algorithms/MultiLayer/BlobExtraction.cpp
similarity index 100%
rename from src/package_bgs/MultiLayer/BlobExtraction.cpp
rename to src/algorithms/MultiLayer/BlobExtraction.cpp
diff --git a/src/package_bgs/MultiLayer/BlobExtraction.h b/src/algorithms/MultiLayer/BlobExtraction.h
similarity index 100%
rename from src/package_bgs/MultiLayer/BlobExtraction.h
rename to src/algorithms/MultiLayer/BlobExtraction.h
diff --git a/src/package_bgs/MultiLayer/BlobLibraryConfiguration.h b/src/algorithms/MultiLayer/BlobLibraryConfiguration.h
similarity index 100%
rename from src/package_bgs/MultiLayer/BlobLibraryConfiguration.h
rename to src/algorithms/MultiLayer/BlobLibraryConfiguration.h
diff --git a/src/package_bgs/MultiLayer/BlobResult.cpp b/src/algorithms/MultiLayer/BlobResult.cpp
similarity index 100%
rename from src/package_bgs/MultiLayer/BlobResult.cpp
rename to src/algorithms/MultiLayer/BlobResult.cpp
diff --git a/src/package_bgs/MultiLayer/BlobResult.h b/src/algorithms/MultiLayer/BlobResult.h
similarity index 99%
rename from src/package_bgs/MultiLayer/BlobResult.h
rename to src/algorithms/MultiLayer/BlobResult.h
index 5ce3bd23f229ce92827efc82d194b96dbce0cce6..62ec48551cac4c82d2ae9e96e3c13a7142fe462d 100644
--- a/src/package_bgs/MultiLayer/BlobResult.h
+++ b/src/algorithms/MultiLayer/BlobResult.h
@@ -5,6 +5,7 @@
 #include <functional>
 
 #include "BlobLibraryConfiguration.h"
+// opencv legacy includes
 #include "OpenCvLegacyIncludes.h"
 #include "blob.h"
 
diff --git a/src/package_bgs/MultiLayer/CMultiLayerBGS.cpp b/src/algorithms/MultiLayer/CMultiLayerBGS.cpp
similarity index 100%
rename from src/package_bgs/MultiLayer/CMultiLayerBGS.cpp
rename to src/algorithms/MultiLayer/CMultiLayerBGS.cpp
diff --git a/src/package_bgs/MultiLayer/CMultiLayerBGS.h b/src/algorithms/MultiLayer/CMultiLayerBGS.h
similarity index 100%
rename from src/package_bgs/MultiLayer/CMultiLayerBGS.h
rename to src/algorithms/MultiLayer/CMultiLayerBGS.h
diff --git a/src/package_bgs/MultiLayer/LocalBinaryPattern.cpp b/src/algorithms/MultiLayer/LocalBinaryPattern.cpp
similarity index 100%
rename from src/package_bgs/MultiLayer/LocalBinaryPattern.cpp
rename to src/algorithms/MultiLayer/LocalBinaryPattern.cpp
diff --git a/src/package_bgs/MultiLayer/LocalBinaryPattern.h b/src/algorithms/MultiLayer/LocalBinaryPattern.h
similarity index 100%
rename from src/package_bgs/MultiLayer/LocalBinaryPattern.h
rename to src/algorithms/MultiLayer/LocalBinaryPattern.h
diff --git a/src/package_bgs/MultiLayer/OpenCvDataConversion.h b/src/algorithms/MultiLayer/OpenCvDataConversion.h
similarity index 99%
rename from src/package_bgs/MultiLayer/OpenCvDataConversion.h
rename to src/algorithms/MultiLayer/OpenCvDataConversion.h
index 660443c0e6ef7c6cecf91f3a79f7274fa926d675..5280b8ad93955f49a3885f1a87be93b6760e194e 100644
--- a/src/package_bgs/MultiLayer/OpenCvDataConversion.h
+++ b/src/algorithms/MultiLayer/OpenCvDataConversion.h
@@ -1,6 +1,7 @@
 #pragma once
 
 #include <stdio.h>
+// opencv legacy includes
 #include "OpenCvLegacyIncludes.h"
 
 template <class TI, class TM>		/* class TI - the type of image data, class TM - the type of matrix data */
diff --git a/src/package_bgs/MultiLayer/OpenCvLegacyIncludes.h b/src/algorithms/MultiLayer/OpenCvLegacyIncludes.h
similarity index 82%
rename from src/package_bgs/MultiLayer/OpenCvLegacyIncludes.h
rename to src/algorithms/MultiLayer/OpenCvLegacyIncludes.h
index 32151c2be48be058766437dd84ef1615e28589fa..f930b75dff378492abd7b8ffe5300e15bdb3dee4 100644
--- a/src/package_bgs/MultiLayer/OpenCvLegacyIncludes.h
+++ b/src/algorithms/MultiLayer/OpenCvLegacyIncludes.h
@@ -1,5 +1,5 @@
 #pragma once
-
+// opencv legacy includes
 #include "opencv2/core/core_c.h"
 #include "opencv2/core/types_c.h"
 #include "opencv2/imgproc/imgproc_c.h"
diff --git a/src/package_bgs/MultiLayer/blob.cpp b/src/algorithms/MultiLayer/blob.cpp
similarity index 100%
rename from src/package_bgs/MultiLayer/blob.cpp
rename to src/algorithms/MultiLayer/blob.cpp
diff --git a/src/package_bgs/MultiLayer/blob.h b/src/algorithms/MultiLayer/blob.h
similarity index 99%
rename from src/package_bgs/MultiLayer/blob.h
rename to src/algorithms/MultiLayer/blob.h
index 624f17750fc65063af6032ee9db978b71b4458b2..acad398e188d643eb71c6c6915938a176f5fb71e 100644
--- a/src/package_bgs/MultiLayer/blob.h
+++ b/src/algorithms/MultiLayer/blob.h
@@ -5,6 +5,7 @@
 #include <algorithm>
 
 #include "BlobLibraryConfiguration.h"
+// opencv legacy includes
 #include "OpenCvLegacyIncludes.h"
 
 //! Factor de conversió de graus a radians
diff --git a/src/package_bgs/PAWCS.cpp b/src/algorithms/PAWCS.cpp
similarity index 61%
rename from src/package_bgs/PAWCS.cpp
rename to src/algorithms/PAWCS.cpp
index 8456b2b19e0c2dc671b798742964ca2225f6c327..e9f82d2fa322fea5177228339bf6fde334c16f98 100644
--- a/src/package_bgs/PAWCS.cpp
+++ b/src/algorithms/PAWCS.cpp
@@ -2,29 +2,30 @@
 
 using namespace bgslibrary::algorithms;
 
-PAWCS::PAWCS() : pPAWCS(nullptr),
-fRelLBSPThreshold(BGSPAWCS_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD),
-nDescDistThresholdOffset(BGSPAWCS_DEFAULT_DESC_DIST_THRESHOLD_OFFSET),
-nMinColorDistThreshold(BGSPAWCS_DEFAULT_MIN_COLOR_DIST_THRESHOLD),
-nMaxNbWords(BGSPAWCS_DEFAULT_MAX_NB_WORDS),
-nSamplesForMovingAvgs(BGSPAWCS_DEFAULT_N_SAMPLES_FOR_MV_AVGS)
+PAWCS::PAWCS() : 
+  IBGS(quote(PAWCS)),
+  pPAWCS(nullptr),
+  fRelLBSPThreshold(BGSPAWCS_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD),
+  nDescDistThresholdOffset(BGSPAWCS_DEFAULT_DESC_DIST_THRESHOLD_OFFSET),
+  nMinColorDistThreshold(BGSPAWCS_DEFAULT_MIN_COLOR_DIST_THRESHOLD),
+  nMaxNbWords(BGSPAWCS_DEFAULT_MAX_NB_WORDS),
+  nSamplesForMovingAvgs(BGSPAWCS_DEFAULT_N_SAMPLES_FOR_MV_AVGS)
 {
-  std::cout << "PAWCS()" << std::endl;
-  setup("./config/PAWCS.xml");
+  debug_construction(PAWCS);
+  initLoadSaveConfig(algorithmName);
 }
-PAWCS::~PAWCS()
-{
+
+PAWCS::~PAWCS() {
+  debug_destruction(PAWCS);
   if (pPAWCS)
     delete pPAWCS;
-  std::cout << "~PAWCS()" << std::endl;
 }
 
 void PAWCS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
   init(img_input, img_output, img_bgmodel);
 
-  if (firstTime)
-  {
+  if (firstTime) {
     pPAWCS = new BackgroundSubtractorPAWCS(
       fRelLBSPThreshold, nDescDistThresholdOffset, nMinColorDistThreshold,
       nMaxNbWords, nSamplesForMovingAvgs);
@@ -37,10 +38,9 @@ void PAWCS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_
   pPAWCS->getBackgroundImage(img_background);
 
 #ifndef MEX_COMPILE_FLAG
-  if (showOutput)
-  {
-    imshow("PAWCS FG", img_foreground);
-    imshow("PAWCS BG", img_background);
+  if (showOutput) {
+    cv::imshow(algorithmName + "_FG", img_foreground);
+    cv::imshow(algorithmName + "_BG", img_background);
   }
 #endif
 
@@ -48,31 +48,20 @@ void PAWCS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_
   img_background.copyTo(img_bgmodel);
 }
 
-void PAWCS::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void PAWCS::save_config(cv::FileStorage &fs) {
   fs << "fRelLBSPThreshold" << fRelLBSPThreshold;
   fs << "nDescDistThresholdOffset" << nDescDistThresholdOffset;
   fs << "nMinColorDistThreshold" << nMinColorDistThreshold;
   fs << "nMaxNbWords" << nMaxNbWords;
   fs << "nSamplesForMovingAvgs" << nSamplesForMovingAvgs;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void PAWCS::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void PAWCS::load_config(cv::FileStorage &fs) {
   fs["fRelLBSPThreshold"] >> fRelLBSPThreshold;
   fs["nDescDistThresholdOffset"] >> nDescDistThresholdOffset;
   fs["nMinColorDistThreshold"] >> nMinColorDistThreshold;
   fs["nMaxNbWords"] >> nMaxNbWords;
   fs["nSamplesForMovingAvgs"] >> nSamplesForMovingAvgs;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
diff --git a/src/package_bgs/PAWCS.h b/src/algorithms/PAWCS.h
similarity index 72%
rename from src/package_bgs/PAWCS.h
rename to src/algorithms/PAWCS.h
index 5644de709779ad7234bdb368844a8a14530fda38..48d8286a2fb5f9875445d769d70c541e5a557d12 100644
--- a/src/package_bgs/PAWCS.h
+++ b/src/algorithms/PAWCS.h
@@ -1,14 +1,13 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 #include "LBSP/BackgroundSubtractorPAWCS.h"
 
 namespace bgslibrary
 {
   namespace algorithms
   {
-    class PAWCS : public IBGS, public ILoadSaveConfig
+    class PAWCS : public IBGS
     {
     private:
       BackgroundSubtractorPAWCS* pPAWCS;
@@ -26,10 +25,10 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<PAWCS> register_PAWCS("PAWCS");
+    bgs_register(PAWCS);
   }
 }
diff --git a/src/package_bgs/PBAS/PBAS.cpp b/src/algorithms/PBAS/PBAS.cpp
similarity index 100%
rename from src/package_bgs/PBAS/PBAS.cpp
rename to src/algorithms/PBAS/PBAS.cpp
diff --git a/src/package_bgs/PBAS/PBAS.h b/src/algorithms/PBAS/PBAS.h
similarity index 100%
rename from src/package_bgs/PBAS/PBAS.h
rename to src/algorithms/PBAS/PBAS.h
diff --git a/src/package_bgs/PixelBasedAdaptiveSegmenter.cpp b/src/algorithms/PixelBasedAdaptiveSegmenter.cpp
similarity index 80%
rename from src/package_bgs/PixelBasedAdaptiveSegmenter.cpp
rename to src/algorithms/PixelBasedAdaptiveSegmenter.cpp
index 90860de68bca87b329998e4a7dd6f88b7a96b394..c03f734c5256bacee482ad96d38bba41b6cf610d 100644
--- a/src/package_bgs/PixelBasedAdaptiveSegmenter.cpp
+++ b/src/algorithms/PixelBasedAdaptiveSegmenter.cpp
@@ -3,25 +3,24 @@
 using namespace bgslibrary::algorithms;
 
 PixelBasedAdaptiveSegmenter::PixelBasedAdaptiveSegmenter() :
+  IBGS(quote(PixelBasedAdaptiveSegmenter)),
   enableInputBlur(true), enableOutputBlur(true),
   alpha(7.0), beta(1.0), N(20), Raute_min(2), R_incdec(0.05), R_lower(18),
   R_scale(5), T_dec(0.05), T_inc(1), T_init(18), T_lower(2), T_upper(200)
 {
-  std::cout << "PixelBasedAdaptiveSegmenter()" << std::endl;
-  setup("./config/PixelBasedAdaptiveSegmenter.xml");
+  debug_construction(PixelBasedAdaptiveSegmenter);
+  initLoadSaveConfig(algorithmName);
 }
 
-PixelBasedAdaptiveSegmenter::~PixelBasedAdaptiveSegmenter()
-{
-  std::cout << "~PixelBasedAdaptiveSegmenter()" << std::endl;
+PixelBasedAdaptiveSegmenter::~PixelBasedAdaptiveSegmenter() {
+  debug_destruction(PixelBasedAdaptiveSegmenter);
 }
 
 void PixelBasedAdaptiveSegmenter::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
   init(img_input, img_output, img_bgmodel);
 
-  if (firstTime)
-  {
+  if (firstTime) {
     pbas.setAlpha(alpha);
     pbas.setBeta(beta);
     pbas.setN(N);
@@ -50,7 +49,7 @@ void PixelBasedAdaptiveSegmenter::process(const cv::Mat &img_input, cv::Mat &img
 
 #ifndef MEX_COMPILE_FLAG
   if (showOutput)
-    cv::imshow("PBAS", img_foreground);
+    cv::imshow(algorithmName + "_FG", img_foreground);
 #endif
 
   img_foreground.copyTo(img_output);
@@ -59,13 +58,9 @@ void PixelBasedAdaptiveSegmenter::process(const cv::Mat &img_input, cv::Mat &img
   firstTime = false;
 }
 
-void PixelBasedAdaptiveSegmenter::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void PixelBasedAdaptiveSegmenter::save_config(cv::FileStorage &fs) {
   fs << "enableInputBlur" << enableInputBlur;
   fs << "enableOutputBlur" << enableOutputBlur;
-  
   fs << "alpha" << alpha;
   fs << "beta" << beta;
   fs << "N" << N;
@@ -78,18 +73,12 @@ void PixelBasedAdaptiveSegmenter::saveConfig()
   fs << "T_init" << T_init;
   fs << "T_lower" << T_lower;
   fs << "T_upper" << T_upper;
-  
   fs << "showOutput" << showOutput;
 }
 
-void PixelBasedAdaptiveSegmenter::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void PixelBasedAdaptiveSegmenter::load_config(cv::FileStorage &fs) {
   fs["enableInputBlur"] >> enableInputBlur;
   fs["enableOutputBlur"] >> enableOutputBlur;
-  
   fs["alpha"] >> alpha;
   fs["beta"] >> beta;
   fs["N"] >> N;
@@ -102,8 +91,5 @@ void PixelBasedAdaptiveSegmenter::loadConfig()
   fs["T_init"] >> T_init;
   fs["T_lower"] >> T_lower;
   fs["T_upper"] >> T_upper;
-  
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
diff --git a/src/package_bgs/PixelBasedAdaptiveSegmenter.h b/src/algorithms/PixelBasedAdaptiveSegmenter.h
similarity index 69%
rename from src/package_bgs/PixelBasedAdaptiveSegmenter.h
rename to src/algorithms/PixelBasedAdaptiveSegmenter.h
index 9e072bfc5e923abbb32ea4ef3d836d9b58e34109..65209b010823aebf5665a293963b9ff84c0747e7 100644
--- a/src/package_bgs/PixelBasedAdaptiveSegmenter.h
+++ b/src/algorithms/PixelBasedAdaptiveSegmenter.h
@@ -1,14 +1,13 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 #include "PBAS/PBAS.h"
 
 namespace bgslibrary
 {
   namespace algorithms
   {
-    class PixelBasedAdaptiveSegmenter : public IBGS, public ILoadSaveConfig
+    class PixelBasedAdaptiveSegmenter : public IBGS
     {
     private:
       PBAS pbas;
@@ -36,10 +35,10 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<PixelBasedAdaptiveSegmenter> register_PixelBasedAdaptiveSegmenter("PixelBasedAdaptiveSegmenter");
+    bgs_register(PixelBasedAdaptiveSegmenter);
   }
 }
diff --git a/src/package_bgs/SigmaDelta.cpp b/src/algorithms/SigmaDelta.cpp
similarity index 72%
rename from src/package_bgs/SigmaDelta.cpp
rename to src/algorithms/SigmaDelta.cpp
index 65a94b6f6fe08f8a32fb9999310aa81ffd32f194..72aae943af06b928015369e0b52a928cfba33c53 100644
--- a/src/package_bgs/SigmaDelta.cpp
+++ b/src/algorithms/SigmaDelta.cpp
@@ -3,32 +3,31 @@
 using namespace bgslibrary::algorithms;
 
 SigmaDelta::SigmaDelta() :
-  ampFactor(1), minVar(15), maxVar(255), algorithm(sdLaMa091New())
+  IBGS(quote(SigmaDelta)),
+  ampFactor(1), minVar(15), maxVar(255), 
+  algorithm(sdLaMa091New())
 {
+  debug_construction(SigmaDelta);
+  initLoadSaveConfig(algorithmName);
   applyParams();
-  std::cout << "SigmaDelta()" << std::endl;
-  setup("./config/SigmaDelta.xml");
 }
 
-SigmaDelta::~SigmaDelta()
-{
+SigmaDelta::~SigmaDelta() {
+  debug_destruction(SigmaDelta);
   sdLaMa091Free(algorithm);
-  std::cout << "~SigmaDelta()" << std::endl;
 }
 
 void SigmaDelta::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
   init(img_input, img_output, img_bgmodel);
 
-  if (firstTime)
-  {
+  if (firstTime) {
     sdLaMa091AllocInit_8u_C3R(algorithm, img_input.data, img_input.cols, img_input.rows, img_input.step);
     img_foreground = cv::Mat(img_input.size(), CV_8UC1);
     img_background = cv::Mat(img_input.size(), CV_8UC3);
     firstTime = false;
   }
-  else
-  {
+  else {
     cv::Mat img_output_tmp(img_input.rows, img_input.cols, CV_8UC3);
     sdLaMa091Update_8u_C3R(algorithm, img_input.data, img_output_tmp.data);
 
@@ -44,42 +43,28 @@ void SigmaDelta::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat
 
 #ifndef MEX_COMPILE_FLAG
   if (showOutput)
-    cv::imshow("Sigma-Delta", img_foreground);
+    cv::imshow(algorithmName + "_FG", img_foreground);
 #endif
 
   img_foreground.copyTo(img_output);
   img_background.copyTo(img_bgmodel);
 }
 
-void SigmaDelta::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void SigmaDelta::save_config(cv::FileStorage &fs) {
   fs << "ampFactor" << ampFactor;
   fs << "minVar" << minVar;
   fs << "maxVar" << maxVar;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void SigmaDelta::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void SigmaDelta::load_config(cv::FileStorage &fs) {
   fs["ampFactor"] >> ampFactor;
   fs["minVar"] >> minVar;
   fs["maxVar"] >> maxVar;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
-  
-  applyParams();
 }
 
-void SigmaDelta::applyParams()
-{
+void SigmaDelta::applyParams() {
   sdLaMa091SetAmplificationFactor(algorithm, ampFactor);
   sdLaMa091SetMinimalVariance(algorithm, minVar);
   sdLaMa091SetMaximalVariance(algorithm, maxVar);
diff --git a/src/package_bgs/SigmaDelta.h b/src/algorithms/SigmaDelta.h
similarity index 67%
rename from src/package_bgs/SigmaDelta.h
rename to src/algorithms/SigmaDelta.h
index 6ddd35db6232c8f7174216d73811febab93e020c..f1fb89073296a120a084a1e3e43c025ee8d039c0 100644
--- a/src/package_bgs/SigmaDelta.h
+++ b/src/algorithms/SigmaDelta.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 //extern "C" {
 #include "SigmaDelta/sdLaMa091.h"
@@ -11,7 +10,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class SigmaDelta : public IBGS, public ILoadSaveConfig
+    class SigmaDelta : public IBGS
     {
     private:
       int ampFactor;
@@ -26,11 +25,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
       void applyParams();
     };
 
-    static BGS_Register<SigmaDelta> register_SigmaDelta("SigmaDelta");
+    bgs_register(SigmaDelta);
   }
 }
diff --git a/src/package_bgs/SigmaDelta/sdLaMa091.cpp b/src/algorithms/SigmaDelta/sdLaMa091.cpp
similarity index 100%
rename from src/package_bgs/SigmaDelta/sdLaMa091.cpp
rename to src/algorithms/SigmaDelta/sdLaMa091.cpp
diff --git a/src/package_bgs/SigmaDelta/sdLaMa091.h b/src/algorithms/SigmaDelta/sdLaMa091.h
similarity index 100%
rename from src/package_bgs/SigmaDelta/sdLaMa091.h
rename to src/algorithms/SigmaDelta/sdLaMa091.h
diff --git a/src/package_bgs/StaticFrameDifference.cpp b/src/algorithms/StaticFrameDifference.cpp
similarity index 66%
rename from src/package_bgs/StaticFrameDifference.cpp
rename to src/algorithms/StaticFrameDifference.cpp
index df46e6ec4fe878065337893a7cba0efd3b870612..54dbc07411b5199176d605a989d9f69c267e161a 100644
--- a/src/package_bgs/StaticFrameDifference.cpp
+++ b/src/algorithms/StaticFrameDifference.cpp
@@ -3,15 +3,15 @@
 using namespace bgslibrary::algorithms;
 
 StaticFrameDifference::StaticFrameDifference() :
+  IBGS(quote(StaticFrameDifference)),
   enableThreshold(true), threshold(15)
 {
-  std::cout << "StaticFrameDifference()" << std::endl;
-  setup("./config/StaticFrameDifference.xml");
+  debug_construction(StaticFrameDifference);
+  initLoadSaveConfig(algorithmName);
 }
 
-StaticFrameDifference::~StaticFrameDifference()
-{
-  std::cout << "~StaticFrameDifference()" << std::endl;
+StaticFrameDifference::~StaticFrameDifference() {
+  debug_destruction(StaticFrameDifference);
 }
 
 void StaticFrameDifference::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -31,7 +31,7 @@ void StaticFrameDifference::process(const cv::Mat &img_input, cv::Mat &img_outpu
 
 #ifndef MEX_COMPILE_FLAG
   if (showOutput)
-    cv::imshow("Static Frame Difference", img_foreground);
+    cv::imshow(algorithmName + "_FG", img_foreground);
 #endif
 
   img_foreground.copyTo(img_output);
@@ -40,25 +40,14 @@ void StaticFrameDifference::process(const cv::Mat &img_input, cv::Mat &img_outpu
   firstTime = false;
 }
 
-void StaticFrameDifference::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void StaticFrameDifference::save_config(cv::FileStorage &fs) {
   fs << "enableThreshold" << enableThreshold;
   fs << "threshold" << threshold;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void StaticFrameDifference::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void StaticFrameDifference::load_config(cv::FileStorage &fs) {
   fs["enableThreshold"] >> enableThreshold;
   fs["threshold"] >> threshold;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
diff --git a/src/package_bgs/StaticFrameDifference.h b/src/algorithms/StaticFrameDifference.h
similarity index 57%
rename from src/package_bgs/StaticFrameDifference.h
rename to src/algorithms/StaticFrameDifference.h
index a08c8a114e735d97bd75f8059510244d55bdd4b3..f3b62346ab5900eb8655aaa94688455c7a338779 100644
--- a/src/package_bgs/StaticFrameDifference.h
+++ b/src/algorithms/StaticFrameDifference.h
@@ -1,13 +1,12 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 namespace bgslibrary
 {
   namespace algorithms
   {
-    class StaticFrameDifference : public IBGS, public ILoadSaveConfig
+    class StaticFrameDifference : public IBGS
     {
     private:
       bool enableThreshold;
@@ -20,10 +19,10 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<StaticFrameDifference> register_StaticFrameDifference("StaticFrameDifference");
+    bgs_register(StaticFrameDifference);
   }
 }
diff --git a/src/package_bgs/SuBSENSE.cpp b/src/algorithms/SuBSENSE.cpp
similarity index 81%
rename from src/package_bgs/SuBSENSE.cpp
rename to src/algorithms/SuBSENSE.cpp
index fe3aeac81d5a775163f1e4f058aeab4e6314ddd3..f753a8dbb67a4a540f5000a641875235c204a7a7 100644
--- a/src/package_bgs/SuBSENSE.cpp
+++ b/src/algorithms/SuBSENSE.cpp
@@ -3,6 +3,7 @@
 using namespace bgslibrary::algorithms;
 
 SuBSENSE::SuBSENSE() :
+  IBGS(quote(SuBSENSE)),
   pSubsense(0),
   fRelLBSPThreshold(BGSSUBSENSE_DEFAULT_LBSP_REL_SIMILARITY_THRESHOLD),
   nDescDistThresholdOffset(BGSSUBSENSE_DEFAULT_DESC_DIST_THRESHOLD_OFFSET),
@@ -11,21 +12,21 @@ SuBSENSE::SuBSENSE() :
   nRequiredBGSamples(BGSSUBSENSE_DEFAULT_REQUIRED_NB_BG_SAMPLES),
   nSamplesForMovingAvgs(BGSSUBSENSE_DEFAULT_N_SAMPLES_FOR_MV_AVGS)
 {
-  std::cout << "SuBSENSE()" << std::endl;
+  debug_construction(SuBSENSE);
+  initLoadSaveConfig(algorithmName);
 }
 
 SuBSENSE::~SuBSENSE() {
+  debug_destruction(SuBSENSE);
   if (pSubsense)
     delete pSubsense;
-  std::cout << "~SuBSENSE()" << std::endl;
 }
 
 void SuBSENSE::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
   init(img_input, img_output, img_bgmodel);
 
-  if (firstTime)
-  {
+  if (firstTime) {
     pSubsense = new BackgroundSubtractorSuBSENSE(
       fRelLBSPThreshold, nDescDistThresholdOffset, nMinColorDistThreshold,
       nBGSamples, nRequiredBGSamples, nSamplesForMovingAvgs);
@@ -38,10 +39,9 @@ void SuBSENSE::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &i
   pSubsense->getBackgroundImage(img_background);
 
 #ifndef MEX_COMPILE_FLAG
-  if (showOutput)
-  {
-    imshow("SuBSENSE FG", img_foreground);
-    imshow("SuBSENSE BG", img_background);
+  if (showOutput) {
+    cv::imshow(algorithmName + "_FG", img_foreground);
+    cv::imshow(algorithmName + "_BG", img_background);
   }
 #endif
 
@@ -49,10 +49,7 @@ void SuBSENSE::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &i
   img_background.copyTo(img_bgmodel);
 }
 
-void SuBSENSE::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void SuBSENSE::save_config(cv::FileStorage &fs) {
   fs << "fRelLBSPThreshold" << fRelLBSPThreshold;
   fs << "nDescDistThresholdOffset" << nDescDistThresholdOffset;
   fs << "nMinColorDistThreshold" << nMinColorDistThreshold;
@@ -60,15 +57,9 @@ void SuBSENSE::saveConfig()
   fs << "nRequiredBGSamples" << nRequiredBGSamples;
   fs << "nSamplesForMovingAvgs" << nSamplesForMovingAvgs;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void SuBSENSE::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void SuBSENSE::load_config(cv::FileStorage &fs) {
   fs["fRelLBSPThreshold"] >> fRelLBSPThreshold;
   fs["nDescDistThresholdOffset"] >> nDescDistThresholdOffset;
   fs["nMinColorDistThreshold"] >> nMinColorDistThreshold;
@@ -76,6 +67,4 @@ void SuBSENSE::loadConfig()
   fs["nRequiredBGSamples"] >> nRequiredBGSamples;
   fs["nSamplesForMovingAvgs"] >> nSamplesForMovingAvgs;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
diff --git a/src/package_bgs/SuBSENSE.h b/src/algorithms/SuBSENSE.h
similarity index 73%
rename from src/package_bgs/SuBSENSE.h
rename to src/algorithms/SuBSENSE.h
index 754072ec6efff8f3cd1c58f2c539c1e4e75131dc..73edc268061553410046b6684e946b7799ba023f 100644
--- a/src/package_bgs/SuBSENSE.h
+++ b/src/algorithms/SuBSENSE.h
@@ -1,14 +1,13 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 #include "LBSP/BackgroundSubtractorSuBSENSE.h"
 
 namespace bgslibrary
 {
   namespace algorithms
   {
-    class SuBSENSE : public IBGS, public ILoadSaveConfig
+    class SuBSENSE : public IBGS
     {
     private:
       BackgroundSubtractorSuBSENSE* pSubsense;
@@ -27,10 +26,10 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<SuBSENSE> register_SuBSENSE("SuBSENSE");
+    bgs_register(SuBSENSE);
   }
 }
diff --git a/src/package_bgs/T2F/FuzzyUtils.cpp b/src/algorithms/T2F/FuzzyUtils.cpp
similarity index 100%
rename from src/package_bgs/T2F/FuzzyUtils.cpp
rename to src/algorithms/T2F/FuzzyUtils.cpp
diff --git a/src/package_bgs/T2F/FuzzyUtils.h b/src/algorithms/T2F/FuzzyUtils.h
similarity index 95%
rename from src/package_bgs/T2F/FuzzyUtils.h
rename to src/algorithms/T2F/FuzzyUtils.h
index 608b01d461e1496307af480ce7b2264408415035..43918535957ddb34827eb8f8ecfad3b8c7c62663 100644
--- a/src/package_bgs/T2F/FuzzyUtils.h
+++ b/src/algorithms/T2F/FuzzyUtils.h
@@ -1,6 +1,6 @@
 #pragma once
 
-#include "../../package_analysis/PixelUtils.h"
+#include "../../tools/PixelUtils.h"
 
 class FuzzyUtils
 {
diff --git a/src/package_bgs/T2F/MRF.cpp b/src/algorithms/T2F/MRF.cpp
similarity index 100%
rename from src/package_bgs/T2F/MRF.cpp
rename to src/algorithms/T2F/MRF.cpp
diff --git a/src/package_bgs/T2F/MRF.h b/src/algorithms/T2F/MRF.h
similarity index 100%
rename from src/package_bgs/T2F/MRF.h
rename to src/algorithms/T2F/MRF.h
diff --git a/src/package_bgs/T2F/T2FGMM.cpp b/src/algorithms/T2F/T2FGMM.cpp
similarity index 100%
rename from src/package_bgs/T2F/T2FGMM.cpp
rename to src/algorithms/T2F/T2FGMM.cpp
diff --git a/src/package_bgs/T2F/T2FGMM.h b/src/algorithms/T2F/T2FGMM.h
similarity index 100%
rename from src/package_bgs/T2F/T2FGMM.h
rename to src/algorithms/T2F/T2FGMM.h
diff --git a/src/package_bgs/T2F/T2FMRF.cpp b/src/algorithms/T2F/T2FMRF.cpp
similarity index 100%
rename from src/package_bgs/T2F/T2FMRF.cpp
rename to src/algorithms/T2F/T2FMRF.cpp
diff --git a/src/package_bgs/T2F/T2FMRF.h b/src/algorithms/T2F/T2FMRF.h
similarity index 100%
rename from src/package_bgs/T2F/T2FMRF.h
rename to src/algorithms/T2F/T2FMRF.h
diff --git a/src/package_bgs/T2FGMM_UM.cpp b/src/algorithms/T2FGMM_UM.cpp
similarity index 79%
rename from src/package_bgs/T2FGMM_UM.cpp
rename to src/algorithms/T2FGMM_UM.cpp
index b9526f9377424f7dd37d839ce213474588358066..44904da8079e30cb3a74b1407ff5f6d9a4204606 100644
--- a/src/package_bgs/T2FGMM_UM.cpp
+++ b/src/algorithms/T2FGMM_UM.cpp
@@ -5,15 +5,16 @@
 using namespace bgslibrary::algorithms;
 
 T2FGMM_UM::T2FGMM_UM() :
-  frameNumber(0), threshold(9.0), alpha(0.01), km(1.5f), kv(0.6f), gaussians(3)
+  IBGS(quote(T2FGMM_UM)),
+  frameNumber(0), threshold(9.0), alpha(0.01), 
+  km(1.5f), kv(0.6f), gaussians(3)
 {
-  std::cout << "T2FGMM_UM()" << std::endl;
-  setup("./config/T2FGMM_UM.xml");
+  debug_construction(T2FGMM_UM);
+  initLoadSaveConfig(algorithmName);
 }
 
-T2FGMM_UM::~T2FGMM_UM()
-{
-  std::cout << "~T2FGMM_UM()" << std::endl;
+T2FGMM_UM::~T2FGMM_UM() {
+  debug_destruction(T2FGMM_UM);
 }
 
 void T2FGMM_UM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -25,8 +26,7 @@ void T2FGMM_UM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
     frame_data.ReleaseMemory(false);
   frame_data = frame;
 
-  if (firstTime)
-  {
+  if (firstTime) {
     int width = img_input.size().width;
     int height = img_input.size().height;
 
@@ -59,7 +59,7 @@ void T2FGMM_UM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
 
 #ifndef MEX_COMPILE_FLAG
   if (showOutput)
-    cv::imshow("T2FGMM-UM", img_foreground);
+    cv::imshow(algorithmName + "_FG", img_foreground);
 #endif
 
   img_foreground.copyTo(img_output);
@@ -70,33 +70,22 @@ void T2FGMM_UM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
   frameNumber++;
 }
 
-void T2FGMM_UM::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void T2FGMM_UM::save_config(cv::FileStorage &fs) {
   fs << "threshold" << threshold;
   fs << "alpha" << alpha;
   fs << "km" << km;
   fs << "kv" << kv;
   fs << "gaussians" << gaussians;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void T2FGMM_UM::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void T2FGMM_UM::load_config(cv::FileStorage &fs) {
   fs["threshold"] >> threshold;
   fs["alpha"] >> alpha;
   fs["km"] >> km;
   fs["kv"] >> kv;
   fs["gaussians"] >> gaussians;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/T2FGMM_UM.h b/src/algorithms/T2FGMM_UM.h
similarity index 78%
rename from src/package_bgs/T2FGMM_UM.h
rename to src/algorithms/T2FGMM_UM.h
index 8cf40bb8d573d1e23cbbaa323cde25e60c25de0b..c5a6ebd0e91c0024ee147816cae203dc23a11c2b 100644
--- a/src/package_bgs/T2FGMM_UM.h
+++ b/src/algorithms/T2FGMM_UM.h
@@ -4,7 +4,6 @@
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 #include "T2F/T2FGMM.h"
 
 using namespace Algorithms::BackgroundSubtraction;
@@ -13,7 +12,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class T2FGMM_UM : public IBGS, public ILoadSaveConfig
+    class T2FGMM_UM : public IBGS
     {
     private:
       long frameNumber;
@@ -38,11 +37,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<T2FGMM_UM> register_T2FGMM_UM("T2FGMM_UM");
+    bgs_register(T2FGMM_UM);
   }
 }
 
diff --git a/src/package_bgs/T2FGMM_UV.cpp b/src/algorithms/T2FGMM_UV.cpp
similarity index 79%
rename from src/package_bgs/T2FGMM_UV.cpp
rename to src/algorithms/T2FGMM_UV.cpp
index 56e9dad1a8de16b82570d916bfc50f215f04bda4..3b411351b7fd26697f08810ded00ad44e3916be3 100644
--- a/src/package_bgs/T2FGMM_UV.cpp
+++ b/src/algorithms/T2FGMM_UV.cpp
@@ -5,15 +5,16 @@
 using namespace bgslibrary::algorithms;
 
 T2FGMM_UV::T2FGMM_UV() :
-  frameNumber(0), threshold(9.0), alpha(0.01), km(1.5f), kv(0.6f), gaussians(3)
+  IBGS(quote(T2FGMM_UV)),
+  frameNumber(0), threshold(9.0), alpha(0.01), 
+  km(1.5f), kv(0.6f), gaussians(3)
 {
-  std::cout << "T2FGMM_UV()" << std::endl;
-  setup("./config/T2FGMM_UV.xml");
+  debug_construction(T2FGMM_UV);
+  initLoadSaveConfig(algorithmName);
 }
 
-T2FGMM_UV::~T2FGMM_UV()
-{
-  std::cout << "~T2FGMM_UV()" << std::endl;
+T2FGMM_UV::~T2FGMM_UV() {
+  debug_destruction(T2FGMM_UV);
 }
 
 void T2FGMM_UV::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -25,8 +26,7 @@ void T2FGMM_UV::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
     frame_data.ReleaseMemory(false);
   frame_data = frame;
 
-  if (firstTime)
-  {
+  if (firstTime) {
     int width = img_input.size().width;
     int height = img_input.size().height;
 
@@ -59,7 +59,7 @@ void T2FGMM_UV::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
 
 #ifndef MEX_COMPILE_FLAG
   if (showOutput)
-    cv::imshow("T2FGMM-UV", img_foreground);
+    cv::imshow(algorithmName + "_FG", img_foreground);
 #endif
 
   img_foreground.copyTo(img_output);
@@ -70,33 +70,22 @@ void T2FGMM_UV::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
   frameNumber++;
 }
 
-void T2FGMM_UV::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void T2FGMM_UV::save_config(cv::FileStorage &fs) {
   fs << "threshold" << threshold;
   fs << "alpha" << alpha;
   fs << "km" << km;
   fs << "kv" << kv;
   fs << "gaussians" << gaussians;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void T2FGMM_UV::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void T2FGMM_UV::load_config(cv::FileStorage &fs) {
   fs["threshold"] >> threshold;
   fs["alpha"] >> alpha;
   fs["km"] >> km;
   fs["kv"] >> kv;
   fs["gaussians"] >> gaussians;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/T2FGMM_UV.h b/src/algorithms/T2FGMM_UV.h
similarity index 78%
rename from src/package_bgs/T2FGMM_UV.h
rename to src/algorithms/T2FGMM_UV.h
index 5dcc83ab39142af45ee01965c6cbf32cfe66d6d2..75f931f4aa94ffa57eba17bc59b266a5fbaeafc1 100644
--- a/src/package_bgs/T2FGMM_UV.h
+++ b/src/algorithms/T2FGMM_UV.h
@@ -4,7 +4,6 @@
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 #include "T2F/T2FGMM.h"
 
 using namespace Algorithms::BackgroundSubtraction;
@@ -13,7 +12,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class T2FGMM_UV : public IBGS, public ILoadSaveConfig
+    class T2FGMM_UV : public IBGS
     {
     private:
       long frameNumber;
@@ -38,11 +37,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<T2FGMM_UV> register_T2FGMM_UV("T2FGMM_UV");
+    bgs_register(T2FGMM_UV);
   }
 }
 
diff --git a/src/package_bgs/T2FMRF_UM.cpp b/src/algorithms/T2FMRF_UM.cpp
similarity index 85%
rename from src/package_bgs/T2FMRF_UM.cpp
rename to src/algorithms/T2FMRF_UM.cpp
index a81cf37af4421de0e8d465938815bf9b30487856..487b72e6b973c1da899a38ae91707e7b8006513d 100644
--- a/src/package_bgs/T2FMRF_UM.cpp
+++ b/src/algorithms/T2FMRF_UM.cpp
@@ -5,15 +5,16 @@
 using namespace bgslibrary::algorithms;
 
 T2FMRF_UM::T2FMRF_UM() :
-  frameNumber(0), threshold(9.0), alpha(0.01), km(2.f), kv(0.9f), gaussians(3)
+  IBGS(quote(T2FMRF_UM)),
+  frameNumber(0), threshold(9.0), alpha(0.01), 
+  km(2.f), kv(0.9f), gaussians(3)
 {
-  std::cout << "T2FMRF_UM()" << std::endl;
-  setup("./config/DPMean.xml");
+  debug_construction(T2FMRF_UM);
+  initLoadSaveConfig(algorithmName);
 }
 
-T2FMRF_UM::~T2FMRF_UM()
-{
-  std::cout << "~T2FMRF_UM()" << std::endl;
+T2FMRF_UM::~T2FMRF_UM() {
+  debug_destruction(T2FMRF_UM);
 }
 
 void T2FMRF_UM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -25,8 +26,7 @@ void T2FMRF_UM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
     frame_data.ReleaseMemory(false);
   frame_data = frame;
 
-  if (firstTime)
-  {
+  if (firstTime) {
     int width = img_input.size().width;
     int height = img_input.size().height;
 
@@ -88,7 +88,7 @@ void T2FMRF_UM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
 
 #ifndef MEX_COMPILE_FLAG
   if (showOutput)
-    cv::imshow("T2FMRF-UM", img_foreground);
+    cv::imshow(algorithmName + "_FG", img_foreground);
 #endif
 
   img_foreground.copyTo(img_output);
@@ -98,33 +98,22 @@ void T2FMRF_UM::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
   frameNumber++;
 }
 
-void T2FMRF_UM::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void T2FMRF_UM::save_config(cv::FileStorage &fs) {
   fs << "threshold" << threshold;
   fs << "alpha" << alpha;
   fs << "km" << km;
   fs << "kv" << kv;
   fs << "gaussians" << gaussians;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void T2FMRF_UM::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void T2FMRF_UM::load_config(cv::FileStorage &fs) {
   fs["threshold"] >> threshold;
   fs["alpha"] >> alpha;
   fs["km"] >> km;
   fs["kv"] >> kv;
   fs["gaussians"] >> gaussians;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/T2FMRF_UM.h b/src/algorithms/T2FMRF_UM.h
similarity index 80%
rename from src/package_bgs/T2FMRF_UM.h
rename to src/algorithms/T2FMRF_UM.h
index bab22b02dcf316a486b87a894053c4804672e23c..ba27e6e67f8e4c67f8f1088e1b1a4d6145079f7c 100644
--- a/src/package_bgs/T2FMRF_UM.h
+++ b/src/algorithms/T2FMRF_UM.h
@@ -4,7 +4,6 @@
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 #include "T2F/MRF.h"
 
 using namespace Algorithms::BackgroundSubtraction;
@@ -13,7 +12,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class T2FMRF_UM : public IBGS, public ILoadSaveConfig
+    class T2FMRF_UM : public IBGS
     {
     private:
       long frameNumber;
@@ -45,11 +44,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<T2FMRF_UM> register_T2FMRF_UM("T2FMRF_UM");
+    bgs_register(T2FMRF_UM);
   }
 }
 
diff --git a/src/package_bgs/T2FMRF_UV.cpp b/src/algorithms/T2FMRF_UV.cpp
similarity index 85%
rename from src/package_bgs/T2FMRF_UV.cpp
rename to src/algorithms/T2FMRF_UV.cpp
index 0d3e6373cdf35d682123acb6dcd4857a81d559b8..5c96be89b3a49fac9650afd0787b12885ce46e2e 100644
--- a/src/package_bgs/T2FMRF_UV.cpp
+++ b/src/algorithms/T2FMRF_UV.cpp
@@ -5,15 +5,16 @@
 using namespace bgslibrary::algorithms;
 
 T2FMRF_UV::T2FMRF_UV() :
-  frameNumber(0), threshold(9.0), alpha(0.01), km(2.f), kv(0.9f), gaussians(3)
+  IBGS(quote(T2FMRF_UV)),
+  frameNumber(0), threshold(9.0), alpha(0.01), 
+  km(2.f), kv(0.9f), gaussians(3)
 {
-  std::cout << "T2FMRF_UV()" << std::endl;
-  setup("./config/T2FMRF_UV.xml");
+  debug_construction(T2FMRF_UV);
+  initLoadSaveConfig(algorithmName);
 }
 
-T2FMRF_UV::~T2FMRF_UV()
-{
-  std::cout << "~T2FMRF_UV()" << std::endl;
+T2FMRF_UV::~T2FMRF_UV() {
+  debug_destruction(T2FMRF_UV);
 }
 
 void T2FMRF_UV::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -25,8 +26,7 @@ void T2FMRF_UV::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
     frame_data.ReleaseMemory(false);
   frame_data = frame;
 
-  if (firstTime)
-  {
+  if (firstTime) {
     int width = img_input.size().width;
     int height = img_input.size().height;
 
@@ -88,7 +88,7 @@ void T2FMRF_UV::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
 
 #ifndef MEX_COMPILE_FLAG
   if (showOutput)
-    cv::imshow("T2FMRF-UV", img_foreground);
+    cv::imshow(algorithmName + "_FG", img_foreground);
 #endif
 
   img_foreground.copyTo(img_output);
@@ -98,33 +98,22 @@ void T2FMRF_UV::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
   frameNumber++;
 }
 
-void T2FMRF_UV::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void T2FMRF_UV::save_config(cv::FileStorage &fs) {
   fs << "threshold" << threshold;
   fs << "alpha" << alpha;
   fs << "km" << km;
   fs << "kv" << kv;
   fs << "gaussians" << gaussians;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void T2FMRF_UV::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void T2FMRF_UV::load_config(cv::FileStorage &fs) {
   fs["threshold"] >> threshold;
   fs["alpha"] >> alpha;
   fs["km"] >> km;
   fs["kv"] >> kv;
   fs["gaussians"] >> gaussians;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/T2FMRF_UV.h b/src/algorithms/T2FMRF_UV.h
similarity index 80%
rename from src/package_bgs/T2FMRF_UV.h
rename to src/algorithms/T2FMRF_UV.h
index 4ffd7c11ef5565f472f0a3e4220f1d872b415c4f..f9b6e0f9a6075a618ef59f642059b76b27f7af92 100644
--- a/src/package_bgs/T2FMRF_UV.h
+++ b/src/algorithms/T2FMRF_UV.h
@@ -4,7 +4,6 @@
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 #include "T2F/MRF.h"
 
 using namespace Algorithms::BackgroundSubtraction;
@@ -13,7 +12,7 @@ namespace bgslibrary
 {
   namespace algorithms
   {
-    class T2FMRF_UV : public IBGS, public ILoadSaveConfig
+    class T2FMRF_UV : public IBGS
     {
     private:
       long frameNumber;
@@ -45,11 +44,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<T2FMRF_UV> register_T2FMRF_UV("T2FMRF_UV");
+    bgs_register(T2FMRF_UV);
   }
 }
 
diff --git a/src/package_bgs/TwoPoints.cpp b/src/algorithms/TwoPoints.cpp
similarity index 76%
rename from src/package_bgs/TwoPoints.cpp
rename to src/algorithms/TwoPoints.cpp
index ba8b1f1e48baefa2c367f5f181bcef22539a165f..ec2c134e1222e56712fbdd926c7fd105c39cce5e 100644
--- a/src/package_bgs/TwoPoints.cpp
+++ b/src/algorithms/TwoPoints.cpp
@@ -3,18 +3,18 @@
 using namespace bgslibrary::algorithms;
 
 TwoPoints::TwoPoints() :
+  IBGS(quote(TwoPoints)),
   matchingThreshold(DEFAULT_MATCH_THRESH),
   updateFactor(DEFAULT_UPDATE_FACTOR), model(nullptr)
 {
-  std::cout << "TwoPoints()" << std::endl;
+  debug_construction(TwoPoints);
+  initLoadSaveConfig(algorithmName);
   //model = static_cast<twopointsModel_t*>(libtwopointsModel_New());
   model = libtwopointsModel_New();
-  setup("./config/TwoPoints.xml");
 }
 
-TwoPoints::~TwoPoints()
-{
-  std::cout << "~TwoPoints()" << std::endl;
+TwoPoints::~TwoPoints() {
+  debug_destruction(TwoPoints);
   libtwopointsModel_Free(model);
 }
 
@@ -31,8 +31,7 @@ void TwoPoints::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
   // Convert input image to a grayscale image
   cvtColor(img_input, img_input_grayscale, CV_BGR2GRAY);
 
-  if (firstTime)
-  {
+  if (firstTime) {
     // Create a buffer for the output image.
     //img_output = Mat(img_input.rows, img_input.cols, CV_8UC1);
 
@@ -48,15 +47,12 @@ void TwoPoints::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
 
   updatingMask = cv::Mat(img_input.rows, img_input.cols, CV_8UC1);
   // Work on the output and define the updating mask
-  for (int i = 0; i < img_input.cols * img_input.rows; i++)
-  {
-    if (img_output.data[i] == 0) // Foreground pixel
-    {
+  for (int i = 0; i < img_input.cols * img_input.rows; i++) {
+    if (img_output.data[i] == 0) { // Foreground pixel
       updatingMask.data[i] = 0;
       img_output.data[i] = 255;
     }
-    else // Background
-    {
+    else { // Background
       updatingMask.data[i] = 255;
       img_output.data[i] = 0;
     }
@@ -66,31 +62,20 @@ void TwoPoints::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &
 
 #ifndef MEX_COMPILE_FLAG
   if (showOutput)
-    imshow("Two points", img_output);
+    cv::imshow(algorithmName + "_FG", img_output);
 #endif
 
   firstTime = false;
 }
 
-void TwoPoints::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void TwoPoints::save_config(cv::FileStorage &fs) {
   fs << "matchingThreshold" << matchingThreshold;
   fs << "updateFactor" << updateFactor;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void TwoPoints::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void TwoPoints::load_config(cv::FileStorage &fs) {
   fs["matchingThreshold"] >> matchingThreshold;
   fs["updateFactor"] >> updateFactor;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
diff --git a/src/package_bgs/TwoPoints.h b/src/algorithms/TwoPoints.h
similarity index 70%
rename from src/package_bgs/TwoPoints.h
rename to src/algorithms/TwoPoints.h
index 133c1600e74756353a255919805031d195ff73b3..65cff47eb97cab995c34972a10a60883cb4f8d6a 100644
--- a/src/package_bgs/TwoPoints.h
+++ b/src/algorithms/TwoPoints.h
@@ -1,14 +1,13 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 #include "TwoPoints/two_points.h"
 
 namespace bgslibrary
 {
   namespace algorithms
   {
-    class TwoPoints : public IBGS, public ILoadSaveConfig
+    class TwoPoints : public IBGS
     {
     private:
       static const int DEFAULT_MATCH_THRESH = 20;
@@ -24,10 +23,10 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<TwoPoints> register_TwoPoints("TwoPoints");
+    bgs_register(TwoPoints);
   }
 }
diff --git a/src/package_bgs/TwoPoints/two_points.cpp b/src/algorithms/TwoPoints/two_points.cpp
similarity index 100%
rename from src/package_bgs/TwoPoints/two_points.cpp
rename to src/algorithms/TwoPoints/two_points.cpp
diff --git a/src/package_bgs/TwoPoints/two_points.h b/src/algorithms/TwoPoints/two_points.h
similarity index 100%
rename from src/package_bgs/TwoPoints/two_points.h
rename to src/algorithms/TwoPoints/two_points.h
diff --git a/src/package_bgs/ViBe.cpp b/src/algorithms/ViBe.cpp
similarity index 82%
rename from src/package_bgs/ViBe.cpp
rename to src/algorithms/ViBe.cpp
index c72f81817c066b53e87e6dcc01c10865dd3bdcc8..16b9df1ccfb90283baa21fc593155d7f4518c30e 100644
--- a/src/package_bgs/ViBe.cpp
+++ b/src/algorithms/ViBe.cpp
@@ -3,20 +3,20 @@
 using namespace bgslibrary::algorithms;
 
 ViBe::ViBe() :
+  IBGS(quote(ViBe)),
   //numberOfSamples(DEFAULT_NUM_SAMPLES),
   matchingThreshold(DEFAULT_MATCH_THRESH),
   matchingNumber(DEFAULT_MATCH_NUM),
   updateFactor(DEFAULT_UPDATE_FACTOR),
   model(nullptr)
 {
-  std::cout << "ViBe()" << std::endl;
+  debug_construction(ViBe);
+  initLoadSaveConfig(algorithmName);
   model = libvibeModel_Sequential_New();
-  setup("./config/ViBe.xml");
 }
 
-ViBe::~ViBe()
-{
-  std::cout << "~ViBe()" << std::endl;
+ViBe::~ViBe() {
+  debug_destruction(ViBe);
   libvibeModel_Sequential_Free(model);
 }
 
@@ -27,8 +27,7 @@ void ViBe::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_b
   if (img_input.empty())
     return;
 
-  if (firstTime)
-  {
+  if (firstTime) {
     /* Create a buffer for the output image. */
     //img_output = cv::Mat(img_input.rows, img_input.cols, CV_8UC1);
 
@@ -48,35 +47,24 @@ void ViBe::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_b
 
 #ifndef MEX_COMPILE_FLAG
   if (showOutput)
-    imshow("ViBe", img_output);
+    cv::imshow(algorithmName + "_FG", img_output);
 #endif
 
   firstTime = false;
 }
 
-void ViBe::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void ViBe::save_config(cv::FileStorage &fs) {
   //fs << "numberOfSamples" << numberOfSamples;
   fs << "matchingThreshold" << matchingThreshold;
   fs << "matchingNumber" << matchingNumber;
   fs << "updateFactor" << updateFactor;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void ViBe::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void ViBe::load_config(cv::FileStorage &fs) {
   //fs["numberOfSamples"] >> numberOfSamples;
   fs["matchingThreshold"] >> matchingThreshold;
   fs["matchingNumber"] >> matchingNumber;
   fs["updateFactor"] >> updateFactor;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
diff --git a/src/package_bgs/ViBe.h b/src/algorithms/ViBe.h
similarity index 78%
rename from src/package_bgs/ViBe.h
rename to src/algorithms/ViBe.h
index 0b38852c5356ae1f433ad5f9921120ac97b1f60d..84f000e3c3aa543edce3469b7fe9e80c8ee6a631 100644
--- a/src/package_bgs/ViBe.h
+++ b/src/algorithms/ViBe.h
@@ -1,14 +1,13 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 #include "ViBe/vibe-background-sequential.h"
 
 namespace bgslibrary
 {
   namespace algorithms
   {
-    class ViBe : public IBGS, public ILoadSaveConfig
+    class ViBe : public IBGS
     {
     private:
       static const int DEFAULT_NUM_SAMPLES = 20;
@@ -30,10 +29,10 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<ViBe> register_ViBe("ViBe");
+    bgs_register(ViBe);
   }
 }
diff --git a/src/package_bgs/ViBe/LICENSE b/src/algorithms/ViBe/LICENSE
similarity index 100%
rename from src/package_bgs/ViBe/LICENSE
rename to src/algorithms/ViBe/LICENSE
diff --git a/src/package_bgs/ViBe/vibe-background-sequential.cpp b/src/algorithms/ViBe/vibe-background-sequential.cpp
similarity index 100%
rename from src/package_bgs/ViBe/vibe-background-sequential.cpp
rename to src/algorithms/ViBe/vibe-background-sequential.cpp
diff --git a/src/package_bgs/ViBe/vibe-background-sequential.h b/src/algorithms/ViBe/vibe-background-sequential.h
similarity index 100%
rename from src/package_bgs/ViBe/vibe-background-sequential.h
rename to src/algorithms/ViBe/vibe-background-sequential.h
diff --git a/src/package_bgs/VuMeter.cpp b/src/algorithms/VuMeter.cpp
similarity index 72%
rename from src/package_bgs/VuMeter.cpp
rename to src/algorithms/VuMeter.cpp
index d080b39553edb1ac6954da82c29e588824533e11..c83d6b8f1f0046287f3403a8efacfb4459cb8f4a 100644
--- a/src/package_bgs/VuMeter.cpp
+++ b/src/algorithms/VuMeter.cpp
@@ -5,19 +5,19 @@
 using namespace bgslibrary::algorithms;
 
 VuMeter::VuMeter() :
-  enableFilter(true), binSize(8), alpha(0.995), threshold(0.03)
+  IBGS(quote(VuMeter)),
+  enableFilter(true), binSize(8), 
+  alpha(0.995), threshold(0.03)
 {
-  std::cout << "VuMeter()" << std::endl;
-  setup("./config/VuMeter.xml");
+  debug_construction(VuMeter);
+  initLoadSaveConfig(algorithmName);
 }
 
-VuMeter::~VuMeter()
-{
+VuMeter::~VuMeter() {
+  debug_destruction(VuMeter);
   cvReleaseImage(&mask);
   cvReleaseImage(&background);
   cvReleaseImage(&gray);
-
-  std::cout << "~VuMeter()" << std::endl;
 }
 
 void VuMeter::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -25,8 +25,7 @@ void VuMeter::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &im
   init(img_input, img_output, img_bgmodel);
   frame = new IplImage(img_input);
 
-  if (firstTime)
-  {
+  if (firstTime) {
     bgs.SetAlpha(alpha);
     bgs.SetBinSize(binSize);
     bgs.SetThreshold(threshold);
@@ -47,17 +46,15 @@ void VuMeter::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &im
   img_foreground = cv::cvarrToMat(mask);
   img_background = cv::cvarrToMat(background);
 
-  if (enableFilter)
-  {
+  if (enableFilter) {
     cv::erode(img_foreground, img_foreground, cv::Mat());
     cv::medianBlur(img_foreground, img_foreground, 5);
   }
 
 #ifndef MEX_COMPILE_FLAG
-  if (showOutput)
-  {
-    cv::imshow("VuMeter", img_foreground);
-    cv::imshow("VuMeter Bkg Model", img_background);
+  if (showOutput) {
+    cv::imshow(algorithmName + "_FG", img_foreground);
+    cv::imshow(algorithmName + "_BG", img_background);
   }
 #endif
 
@@ -68,31 +65,20 @@ void VuMeter::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &im
   firstTime = false;
 }
 
-void VuMeter::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void VuMeter::save_config(cv::FileStorage &fs) {
   fs << "enableFilter" << enableFilter;
   fs << "binSize" << binSize;
   fs << "alpha" << alpha;
   fs << "threshold" << threshold;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void VuMeter::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void VuMeter::load_config(cv::FileStorage &fs) {
   fs["enableFilter"] >> enableFilter;
   fs["binSize"] >> binSize;
   fs["alpha"] >> alpha;
   fs["threshold"] >> threshold;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
 
 #endif
diff --git a/src/package_bgs/VuMeter.h b/src/algorithms/VuMeter.h
similarity index 75%
rename from src/package_bgs/VuMeter.h
rename to src/algorithms/VuMeter.h
index 6cb67ff54115b6783aea9913937fe6c6d4aad9c1..d10591400ecf1ff04929deb70633c9d4c2ae6908 100644
--- a/src/package_bgs/VuMeter.h
+++ b/src/algorithms/VuMeter.h
@@ -4,14 +4,13 @@
 #if CV_MAJOR_VERSION >= 2 && CV_MAJOR_VERSION <= 3
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 #include "VuMeter/TBackgroundVuMeter.h"
 
 namespace bgslibrary
 {
   namespace algorithms
   {
-    class VuMeter : public IBGS, public ILoadSaveConfig
+    class VuMeter : public IBGS
     {
     private:
       TBackgroundVuMeter bgs;
@@ -33,11 +32,11 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<VuMeter> register_VuMeter("VuMeter");
+    bgs_register(VuMeter);
   }
 }
 
diff --git a/src/package_bgs/VuMeter/TBackground.cpp b/src/algorithms/VuMeter/TBackground.cpp
similarity index 100%
rename from src/package_bgs/VuMeter/TBackground.cpp
rename to src/algorithms/VuMeter/TBackground.cpp
diff --git a/src/package_bgs/VuMeter/TBackground.h b/src/algorithms/VuMeter/TBackground.h
similarity index 97%
rename from src/package_bgs/VuMeter/TBackground.h
rename to src/algorithms/VuMeter/TBackground.h
index b2f4ebd89552705f531cb3704d76cf934e220cda..8f66fe2506e72f5db94cc41f7a959928c7b01599 100644
--- a/src/package_bgs/VuMeter/TBackground.h
+++ b/src/algorithms/VuMeter/TBackground.h
@@ -2,6 +2,7 @@
 
 #include <iostream>
 #include <opencv2/opencv.hpp>
+// opencv legacy includes
 #include <opencv2/core/core_c.h>
 #include <opencv2/imgproc/imgproc_c.h>
 
diff --git a/src/package_bgs/VuMeter/TBackgroundVuMeter.cpp b/src/algorithms/VuMeter/TBackgroundVuMeter.cpp
similarity index 100%
rename from src/package_bgs/VuMeter/TBackgroundVuMeter.cpp
rename to src/algorithms/VuMeter/TBackgroundVuMeter.cpp
diff --git a/src/package_bgs/VuMeter/TBackgroundVuMeter.h b/src/algorithms/VuMeter/TBackgroundVuMeter.h
similarity index 100%
rename from src/package_bgs/VuMeter/TBackgroundVuMeter.h
rename to src/algorithms/VuMeter/TBackgroundVuMeter.h
diff --git a/src/package_bgs/WeightedMovingMean.cpp b/src/algorithms/WeightedMovingMean.cpp
similarity index 78%
rename from src/package_bgs/WeightedMovingMean.cpp
rename to src/algorithms/WeightedMovingMean.cpp
index fcbe38dbda1d70f8bff3bf8fece3ba9a67af9146..3d7d961523d589ff3a697fec37d6364f12220278 100644
--- a/src/package_bgs/WeightedMovingMean.cpp
+++ b/src/algorithms/WeightedMovingMean.cpp
@@ -3,15 +3,15 @@
 using namespace bgslibrary::algorithms;
 
 WeightedMovingMean::WeightedMovingMean() :
+  IBGS(quote(WeightedMovingMean)),
   enableWeight(true), enableThreshold(true), threshold(15)
 {
-  std::cout << "WeightedMovingMean()" << std::endl;
-  setup("./config/WeightedMovingMean.xml");
+  debug_construction(WeightedMovingMean);
+  initLoadSaveConfig(algorithmName);
 }
 
-WeightedMovingMean::~WeightedMovingMean()
-{
-  std::cout << "~WeightedMovingMean()" << std::endl;
+WeightedMovingMean::~WeightedMovingMean() {
+  debug_destruction(WeightedMovingMean);
 }
 
 void WeightedMovingMean::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -58,10 +58,9 @@ void WeightedMovingMean::process(const cv::Mat &img_input, cv::Mat &img_output,
     cv::threshold(img_foreground, img_foreground, threshold, 255, cv::THRESH_BINARY);
 
 #ifndef MEX_COMPILE_FLAG
-  if (showOutput)
-  {
-    cv::imshow("W Moving Mean FG Mask", img_foreground);
-    cv::imshow("W Moving Mean BG Model", img_background);
+  if (showOutput) {
+    cv::imshow(algorithmName + "_FG", img_foreground);
+    cv::imshow(algorithmName + "_BG", img_background);
   }
 #endif
 
@@ -74,27 +73,16 @@ void WeightedMovingMean::process(const cv::Mat &img_input, cv::Mat &img_output,
   firstTime = false;
 }
 
-void WeightedMovingMean::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void WeightedMovingMean::save_config(cv::FileStorage &fs) {
   fs << "enableWeight" << enableWeight;
   fs << "enableThreshold" << enableThreshold;
   fs << "threshold" << threshold;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void WeightedMovingMean::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void WeightedMovingMean::load_config(cv::FileStorage &fs) {
   fs["enableWeight"] >> enableWeight;
   fs["enableThreshold"] >> enableThreshold;
   fs["threshold"] >> threshold;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
diff --git a/src/package_bgs/WeightedMovingMean.h b/src/algorithms/WeightedMovingMean.h
similarity index 63%
rename from src/package_bgs/WeightedMovingMean.h
rename to src/algorithms/WeightedMovingMean.h
index 90309dc7c016ad6011181ccaf5bcd766b7dc5ed0..f31905c65c9ac5426560396dc44afc6c73c1fa20 100644
--- a/src/package_bgs/WeightedMovingMean.h
+++ b/src/algorithms/WeightedMovingMean.h
@@ -1,13 +1,12 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 namespace bgslibrary
 {
   namespace algorithms
   {
-    class WeightedMovingMean : public IBGS, public ILoadSaveConfig
+    class WeightedMovingMean : public IBGS
     {
     private:
       cv::Mat img_input_prev_1;
@@ -23,10 +22,10 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<WeightedMovingMean> register_WeightedMovingMean("WeightedMovingMean");
+    bgs_register(WeightedMovingMean);
   }
 }
diff --git a/src/package_bgs/WeightedMovingVariance.cpp b/src/algorithms/WeightedMovingVariance.cpp
similarity index 87%
rename from src/package_bgs/WeightedMovingVariance.cpp
rename to src/algorithms/WeightedMovingVariance.cpp
index a3cbcb358f8a7ecf38e0db3f56d1094d25706622..d9273c88ae8cb05e32938ca3263646ffe50b7cf1 100644
--- a/src/package_bgs/WeightedMovingVariance.cpp
+++ b/src/algorithms/WeightedMovingVariance.cpp
@@ -3,15 +3,15 @@
 using namespace bgslibrary::algorithms;
 
 WeightedMovingVariance::WeightedMovingVariance() :
+  IBGS(quote(WeightedMovingVariance)),
   enableWeight(true), enableThreshold(true), threshold(15)
 {
-  std::cout << "WeightedMovingVariance()" << std::endl;
-  setup("./config/WeightedMovingVariance.xml");
+  debug_construction(WeightedMovingVariance);
+  initLoadSaveConfig(algorithmName);
 }
 
-WeightedMovingVariance::~WeightedMovingVariance()
-{
-  std::cout << "~WeightedMovingVariance()" << std::endl;
+WeightedMovingVariance::~WeightedMovingVariance() {
+  debug_destruction(WeightedMovingVariance);
 }
 
 void WeightedMovingVariance::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
@@ -84,7 +84,7 @@ void WeightedMovingVariance::process(const cv::Mat &img_input, cv::Mat &img_outp
 
 #ifndef MEX_COMPILE_FLAG
   if (showOutput)
-    cv::imshow("W Moving Variance", img_foreground);
+    cv::imshow(algorithmName + "_FG", img_foreground);
 #endif
 
   img_foreground.copyTo(img_output);
@@ -111,27 +111,16 @@ cv::Mat WeightedMovingVariance::computeWeightedVariance(const cv::Mat &img_input
   return img_f;
 }
 
-void WeightedMovingVariance::saveConfig()
-{
-  cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-  
+void WeightedMovingVariance::save_config(cv::FileStorage &fs) {
   fs << "enableWeight" << enableWeight;
   fs << "enableThreshold" << enableThreshold;
   fs << "threshold" << threshold;
   fs << "showOutput" << showOutput;
-  
-  fs.release();
 }
 
-void WeightedMovingVariance::loadConfig()
-{
-  cv::FileStorage fs;
-  fs.open(config_xml, cv::FileStorage::READ);
-  
+void WeightedMovingVariance::load_config(cv::FileStorage &fs) {
   fs["enableWeight"] >> enableWeight;
   fs["enableThreshold"] >> enableThreshold;
   fs["threshold"] >> threshold;
   fs["showOutput"] >> showOutput;
-  
-  fs.release();
 }
diff --git a/src/package_bgs/WeightedMovingVariance.h b/src/algorithms/WeightedMovingVariance.h
similarity index 68%
rename from src/package_bgs/WeightedMovingVariance.h
rename to src/algorithms/WeightedMovingVariance.h
index f7a0aacdb2a6df196e17fe82a307e540703d86af..e53bdfd6e1c9e50179dcc31e3fb8ac8e0fa28b94 100644
--- a/src/package_bgs/WeightedMovingVariance.h
+++ b/src/algorithms/WeightedMovingVariance.h
@@ -1,13 +1,12 @@
 #pragma once
 
 #include "IBGS.h"
-#include "ILoadSaveConfig.h"
 
 namespace bgslibrary
 {
   namespace algorithms
   {
-    class WeightedMovingVariance : public IBGS, public ILoadSaveConfig
+    class WeightedMovingVariance : public IBGS
     {
     private:
       cv::Mat img_input_prev_1;
@@ -24,10 +23,10 @@ namespace bgslibrary
       cv::Mat computeWeightedVariance(const cv::Mat &img_input_f, const cv::Mat &img_mean_f, const double weight);
 
     private:
-      void saveConfig();
-      void loadConfig();
+      void save_config(cv::FileStorage &fs);
+      void load_config(cv::FileStorage &fs);
     };
 
-    static BGS_Register<WeightedMovingVariance> register_WeightedMovingVariance("WeightedMovingVariance");
+    bgs_register(WeightedMovingVariance);
   }
 }
diff --git a/src/package_bgs/_template_/MyBGS.cpp b/src/algorithms/_template_/MyBGS.cpp
similarity index 84%
rename from src/package_bgs/_template_/MyBGS.cpp
rename to src/algorithms/_template_/MyBGS.cpp
index 5a7adece5ceac9c2dbd9338362f77067e10a22a2..402dddbb8bd8528b3236e9bee9e4437cb525d345 100644
--- a/src/package_bgs/_template_/MyBGS.cpp
+++ b/src/algorithms/_template_/MyBGS.cpp
@@ -2,8 +2,14 @@
 
 using namespace bgslibrary::algorithms;
 
-MyBGS::MyBGS() {}
-MyBGS::~MyBGS() {}
+MyBGS::MyBGS() :
+  IBGS(quote(MyBGS))
+{
+  debug_construction(MyBGS);
+}
+MyBGS::~MyBGS() {
+  debug_destruction(MyBGS);
+}
 
 void MyBGS::process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel)
 {
diff --git a/src/package_bgs/_template_/MyBGS.h b/src/algorithms/_template_/MyBGS.h
similarity index 62%
rename from src/package_bgs/_template_/MyBGS.h
rename to src/algorithms/_template_/MyBGS.h
index 5fdf7267926628a18865d23e809a8e66b8f245e7..db9b3357dd163b43d5a7badf1326d16a828a13fc 100644
--- a/src/package_bgs/_template_/MyBGS.h
+++ b/src/algorithms/_template_/MyBGS.h
@@ -3,13 +3,12 @@
 #include <opencv2/opencv.hpp>
 
 #include "../IBGS.h"
-#include "../ILoadSaveConfig.h"
 
 namespace bgslibrary
 {
   namespace algorithms
   {
-    class MyBGS : public IBGS, public ILoadSaveConfig
+    class MyBGS : public IBGS
     {
     private:
       cv::Mat img_previous;
@@ -21,10 +20,10 @@ namespace bgslibrary
       void process(const cv::Mat &img_input, cv::Mat &img_output, cv::Mat &img_bgmodel);
 
     private:
-      void saveConfig() {}
-      void loadConfig() {}
+      void save_config(cv::FileStorage &fs) {}
+      void load_config(cv::FileStorage &fs) {}
     };
 
-    static BGS_Register<MyBGS> register_MyBGS("MyBGS");
+    bgs_register(MyBGS);
   }
 }
diff --git a/src/algorithms/algorithms.cpp b/src/algorithms/algorithms.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5955368f44f381dc6693ad615b38ee68162648ba
--- /dev/null
+++ b/src/algorithms/algorithms.cpp
@@ -0,0 +1 @@
+#include "algorithms.h"
diff --git a/src/package_bgs/bgslibrary.h b/src/algorithms/algorithms.h
similarity index 94%
rename from src/package_bgs/bgslibrary.h
rename to src/algorithms/algorithms.h
index 93d00ec4ceca656b549ee4c11bd8aafcacc5fa42..0db7953baeb2624b1ad48b86c3065dbe97b03a6a 100644
--- a/src/package_bgs/bgslibrary.h
+++ b/src/algorithms/algorithms.h
@@ -1,8 +1,5 @@
 #pragma once
 
-#include "IBGS.h"
-#include "ILoadSaveConfig.h"
-
 #include "FrameDifference.h"
 #include "StaticFrameDifference.h"
 #include "WeightedMovingMean.h"
@@ -48,6 +45,5 @@
 #include "CodeBook.h"
 
 //#include "_template_/MyBGS.h"
-//#include "_template_/Amber.h"
 
 using namespace bgslibrary::algorithms;
diff --git a/src/package_bgs/dp/AdaptiveMedianBGS.cpp b/src/algorithms/dp/AdaptiveMedianBGS.cpp
similarity index 100%
rename from src/package_bgs/dp/AdaptiveMedianBGS.cpp
rename to src/algorithms/dp/AdaptiveMedianBGS.cpp
diff --git a/src/package_bgs/dp/AdaptiveMedianBGS.h b/src/algorithms/dp/AdaptiveMedianBGS.h
similarity index 100%
rename from src/package_bgs/dp/AdaptiveMedianBGS.h
rename to src/algorithms/dp/AdaptiveMedianBGS.h
diff --git a/src/package_bgs/dp/Bgs.h b/src/algorithms/dp/Bgs.h
similarity index 100%
rename from src/package_bgs/dp/Bgs.h
rename to src/algorithms/dp/Bgs.h
diff --git a/src/package_bgs/dp/BgsParams.h b/src/algorithms/dp/BgsParams.h
similarity index 100%
rename from src/package_bgs/dp/BgsParams.h
rename to src/algorithms/dp/BgsParams.h
diff --git a/src/package_bgs/dp/Eigenbackground.cpp b/src/algorithms/dp/Eigenbackground.cpp
similarity index 100%
rename from src/package_bgs/dp/Eigenbackground.cpp
rename to src/algorithms/dp/Eigenbackground.cpp
diff --git a/src/package_bgs/dp/Eigenbackground.h b/src/algorithms/dp/Eigenbackground.h
similarity index 100%
rename from src/package_bgs/dp/Eigenbackground.h
rename to src/algorithms/dp/Eigenbackground.h
diff --git a/src/package_bgs/dp/Error.cpp b/src/algorithms/dp/Error.cpp
similarity index 100%
rename from src/package_bgs/dp/Error.cpp
rename to src/algorithms/dp/Error.cpp
diff --git a/src/package_bgs/dp/Error.h b/src/algorithms/dp/Error.h
similarity index 100%
rename from src/package_bgs/dp/Error.h
rename to src/algorithms/dp/Error.h
diff --git a/src/package_bgs/dp/GrimsonGMM.cpp b/src/algorithms/dp/GrimsonGMM.cpp
similarity index 100%
rename from src/package_bgs/dp/GrimsonGMM.cpp
rename to src/algorithms/dp/GrimsonGMM.cpp
diff --git a/src/package_bgs/dp/GrimsonGMM.h b/src/algorithms/dp/GrimsonGMM.h
similarity index 100%
rename from src/package_bgs/dp/GrimsonGMM.h
rename to src/algorithms/dp/GrimsonGMM.h
diff --git a/src/package_bgs/dp/Image.cpp b/src/algorithms/dp/Image.cpp
similarity index 100%
rename from src/package_bgs/dp/Image.cpp
rename to src/algorithms/dp/Image.cpp
diff --git a/src/package_bgs/dp/Image.h b/src/algorithms/dp/Image.h
similarity index 100%
rename from src/package_bgs/dp/Image.h
rename to src/algorithms/dp/Image.h
diff --git a/src/package_bgs/dp/MeanBGS.cpp b/src/algorithms/dp/MeanBGS.cpp
similarity index 100%
rename from src/package_bgs/dp/MeanBGS.cpp
rename to src/algorithms/dp/MeanBGS.cpp
diff --git a/src/package_bgs/dp/MeanBGS.h b/src/algorithms/dp/MeanBGS.h
similarity index 100%
rename from src/package_bgs/dp/MeanBGS.h
rename to src/algorithms/dp/MeanBGS.h
diff --git a/src/package_bgs/dp/PratiMediodBGS.cpp b/src/algorithms/dp/PratiMediodBGS.cpp
similarity index 100%
rename from src/package_bgs/dp/PratiMediodBGS.cpp
rename to src/algorithms/dp/PratiMediodBGS.cpp
diff --git a/src/package_bgs/dp/PratiMediodBGS.h b/src/algorithms/dp/PratiMediodBGS.h
similarity index 100%
rename from src/package_bgs/dp/PratiMediodBGS.h
rename to src/algorithms/dp/PratiMediodBGS.h
diff --git a/src/package_bgs/dp/TextureBGS.cpp b/src/algorithms/dp/TextureBGS.cpp
similarity index 100%
rename from src/package_bgs/dp/TextureBGS.cpp
rename to src/algorithms/dp/TextureBGS.cpp
diff --git a/src/package_bgs/dp/TextureBGS.h b/src/algorithms/dp/TextureBGS.h
similarity index 100%
rename from src/package_bgs/dp/TextureBGS.h
rename to src/algorithms/dp/TextureBGS.h
diff --git a/src/package_bgs/dp/WrenGA.cpp b/src/algorithms/dp/WrenGA.cpp
similarity index 100%
rename from src/package_bgs/dp/WrenGA.cpp
rename to src/algorithms/dp/WrenGA.cpp
diff --git a/src/package_bgs/dp/WrenGA.h b/src/algorithms/dp/WrenGA.h
similarity index 100%
rename from src/package_bgs/dp/WrenGA.h
rename to src/algorithms/dp/WrenGA.h
diff --git a/src/package_bgs/dp/ZivkovicAGMM.cpp b/src/algorithms/dp/ZivkovicAGMM.cpp
similarity index 100%
rename from src/package_bgs/dp/ZivkovicAGMM.cpp
rename to src/algorithms/dp/ZivkovicAGMM.cpp
diff --git a/src/package_bgs/dp/ZivkovicAGMM.h b/src/algorithms/dp/ZivkovicAGMM.h
similarity index 100%
rename from src/package_bgs/dp/ZivkovicAGMM.h
rename to src/algorithms/dp/ZivkovicAGMM.h
diff --git a/src/package_bgs/lb/BGModel.cpp b/src/algorithms/lb/BGModel.cpp
similarity index 100%
rename from src/package_bgs/lb/BGModel.cpp
rename to src/algorithms/lb/BGModel.cpp
diff --git a/src/package_bgs/lb/BGModel.h b/src/algorithms/lb/BGModel.h
similarity index 100%
rename from src/package_bgs/lb/BGModel.h
rename to src/algorithms/lb/BGModel.h
diff --git a/src/package_bgs/lb/BGModelFuzzyGauss.cpp b/src/algorithms/lb/BGModelFuzzyGauss.cpp
similarity index 100%
rename from src/package_bgs/lb/BGModelFuzzyGauss.cpp
rename to src/algorithms/lb/BGModelFuzzyGauss.cpp
diff --git a/src/package_bgs/lb/BGModelFuzzyGauss.h b/src/algorithms/lb/BGModelFuzzyGauss.h
similarity index 100%
rename from src/package_bgs/lb/BGModelFuzzyGauss.h
rename to src/algorithms/lb/BGModelFuzzyGauss.h
diff --git a/src/package_bgs/lb/BGModelFuzzySom.cpp b/src/algorithms/lb/BGModelFuzzySom.cpp
similarity index 100%
rename from src/package_bgs/lb/BGModelFuzzySom.cpp
rename to src/algorithms/lb/BGModelFuzzySom.cpp
diff --git a/src/package_bgs/lb/BGModelFuzzySom.h b/src/algorithms/lb/BGModelFuzzySom.h
similarity index 99%
rename from src/package_bgs/lb/BGModelFuzzySom.h
rename to src/algorithms/lb/BGModelFuzzySom.h
index c77255b1457614065bccc1b7391070cf399e8d52..8469ae6e39017018abb1ce1a31482dc8445fa4ad 100644
--- a/src/package_bgs/lb/BGModelFuzzySom.h
+++ b/src/algorithms/lb/BGModelFuzzySom.h
@@ -7,7 +7,6 @@ namespace lb_library
   namespace FuzzyAdaptiveSOM
   {
     // SOM parameters
-
     const int M = 3;				// width SOM (per pixel)
     const int N = 3;				// height SOM (per pixel)
     const int KERNEL = 3; 	// size Gaussian kernel
diff --git a/src/package_bgs/lb/BGModelGauss.cpp b/src/algorithms/lb/BGModelGauss.cpp
similarity index 100%
rename from src/package_bgs/lb/BGModelGauss.cpp
rename to src/algorithms/lb/BGModelGauss.cpp
diff --git a/src/package_bgs/lb/BGModelGauss.h b/src/algorithms/lb/BGModelGauss.h
similarity index 100%
rename from src/package_bgs/lb/BGModelGauss.h
rename to src/algorithms/lb/BGModelGauss.h
diff --git a/src/package_bgs/lb/BGModelMog.cpp b/src/algorithms/lb/BGModelMog.cpp
similarity index 100%
rename from src/package_bgs/lb/BGModelMog.cpp
rename to src/algorithms/lb/BGModelMog.cpp
diff --git a/src/package_bgs/lb/BGModelMog.h b/src/algorithms/lb/BGModelMog.h
similarity index 100%
rename from src/package_bgs/lb/BGModelMog.h
rename to src/algorithms/lb/BGModelMog.h
diff --git a/src/package_bgs/lb/BGModelSom.cpp b/src/algorithms/lb/BGModelSom.cpp
similarity index 100%
rename from src/package_bgs/lb/BGModelSom.cpp
rename to src/algorithms/lb/BGModelSom.cpp
diff --git a/src/package_bgs/lb/BGModelSom.h b/src/algorithms/lb/BGModelSom.h
similarity index 99%
rename from src/package_bgs/lb/BGModelSom.h
rename to src/algorithms/lb/BGModelSom.h
index b3bf5f93f8317fb1f5bdb4a026ad23da9a32a35a..91a5ec2dba6b64595ff25602c8c05f7e4b7378fb 100644
--- a/src/package_bgs/lb/BGModelSom.h
+++ b/src/algorithms/lb/BGModelSom.h
@@ -7,7 +7,6 @@ namespace lb_library
   namespace AdaptiveSOM
   {
     // SOM parameters
-
     const int M = 3;				// width SOM (per pixel)
     const int N = 3;				// height SOM (per pixel)
     const int KERNEL = 3; 	// size Gaussian kernel
diff --git a/src/package_bgs/lb/Types.h b/src/algorithms/lb/Types.h
similarity index 100%
rename from src/package_bgs/lb/Types.h
rename to src/algorithms/lb/Types.h
diff --git a/src/package_bgs/ILoadSaveConfig.h b/src/package_bgs/ILoadSaveConfig.h
deleted file mode 100644
index 1eaf00239623ea9817c960f498fdb3ea9d0b88c8..0000000000000000000000000000000000000000
--- a/src/package_bgs/ILoadSaveConfig.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-
-#include <iostream>
-#include <fstream>
-#include <string>
-
-namespace bgslibrary
-{
-  class ILoadSaveConfig
-  {
-  public:
-    virtual ~ILoadSaveConfig() {}
-
-  protected:
-    std::string config_xml;
-    void setup(const std::string _config_xml) {
-      config_xml = _config_xml;
-      if (!config_xml.empty()) {
-        if (!std::ifstream(config_xml))
-          saveConfig();
-        loadConfig();
-      }
-    }
-
-  private:
-    virtual void saveConfig() = 0;
-    virtual void loadConfig() = 0;
-  };
-}
diff --git a/src/package_bgs/bgslibrary.cpp b/src/package_bgs/bgslibrary.cpp
deleted file mode 100644
index cbc2e7db8777fc7d9463dae05e90628111eb0850..0000000000000000000000000000000000000000
--- a/src/package_bgs/bgslibrary.cpp
+++ /dev/null
@@ -1 +0,0 @@
-#include "bgslibrary.h"
diff --git a/src/package_analysis/ForegroundMaskAnalysis.cpp b/src/tools/ForegroundMaskAnalysis.cpp
similarity index 65%
rename from src/package_analysis/ForegroundMaskAnalysis.cpp
rename to src/tools/ForegroundMaskAnalysis.cpp
index d47ae83092a97f1a9995ca9e0e26bd34cb0f57af..beff632e6ce97ae6ea1f8aba8474fa03ae7f0966 100644
--- a/src/package_analysis/ForegroundMaskAnalysis.cpp
+++ b/src/tools/ForegroundMaskAnalysis.cpp
@@ -6,13 +6,12 @@ namespace bgslibrary
     firstTime(true), showOutput(true),
     stopAt(0), img_ref_path("")
   {
-    std::cout << "ForegroundMaskAnalysis()" << std::endl;
-    setup("./config/ForegroundMaskAnalysis.xml");
+    debug_construction(ForegroundMaskAnalysis);
+    initLoadSaveConfig(quote(ForegroundMaskAnalysis));
   }
 
-  ForegroundMaskAnalysis::~ForegroundMaskAnalysis()
-  {
-    std::cout << "~ForegroundMaskAnalysis()" << std::endl;
+  ForegroundMaskAnalysis::~ForegroundMaskAnalysis() {
+    debug_destruction(ForegroundMaskAnalysis);
   }
 
   void ForegroundMaskAnalysis::process(const long &frameNumber, const std::string &name, const cv::Mat &img_input)
@@ -20,14 +19,6 @@ namespace bgslibrary
     if (img_input.empty())
       return;
 
-    if (stopAt == 0)
-    {
-      loadConfig();
-
-      if (firstTime)
-        saveConfig();
-    }
-
     if (stopAt == frameNumber && img_ref_path.empty() == false)
     {
       cv::Mat img_ref = cv::imread(img_ref_path, 0);
@@ -39,13 +30,11 @@ namespace bgslibrary
       cv::Mat i;
       cv::Mat u;
 
-      if (rn > 0)
-      {
+      if (rn > 0) {
         i = img_input & img_ref;
         u = img_input | img_ref;
       }
-      else
-      {
+      else {
         i = (~img_input) & (~img_ref);
         u = (~img_input) | (~img_ref);
       }
@@ -55,8 +44,7 @@ namespace bgslibrary
 
       double s = (((double)in) / ((double)un));
 
-      if (showOutput)
-      {
+      if (showOutput) {
         cv::imshow("A^B", i);
         cv::imshow("AvB", u);
       }
@@ -69,24 +57,13 @@ namespace bgslibrary
     firstTime = false;
   }
 
-  void ForegroundMaskAnalysis::saveConfig()
-  {
-    cv::FileStorage fs(config_xml, cv::FileStorage::WRITE);
-    
+  void ForegroundMaskAnalysis::save_config(cv::FileStorage &fs) {
     fs << "stopAt" << stopAt;
     fs << "img_ref_path" << img_ref_path;
-    
-    fs.release();
   }
 
-  void ForegroundMaskAnalysis::loadConfig()
-  {
-    cv::FileStorage fs;
-    fs.open(config_xml, cv::FileStorage::READ);
-    
+  void ForegroundMaskAnalysis::load_config(cv::FileStorage &fs) {
     fs["stopAt"] >> stopAt;
     fs["img_ref_path"] >> img_ref_path;
-    
-    fs.release();
   }
 }
diff --git a/src/package_analysis/ForegroundMaskAnalysis.h b/src/tools/ForegroundMaskAnalysis.h
similarity index 85%
rename from src/package_analysis/ForegroundMaskAnalysis.h
rename to src/tools/ForegroundMaskAnalysis.h
index 92f43cbe7030e3915f08e84b56b40f339879e954..89f46cc3298e8c5b9aa507d5103044c7591c58f5 100644
--- a/src/package_analysis/ForegroundMaskAnalysis.h
+++ b/src/tools/ForegroundMaskAnalysis.h
@@ -11,7 +11,7 @@
 #include <opencv2/imgproc/imgproc_c.h>
 #include <opencv2/highgui/highgui_c.h>
 
-#include "../package_bgs/ILoadSaveConfig.h"
+#include "../utils/ILoadSaveConfig.h"
 
 namespace bgslibrary
 {
@@ -31,7 +31,7 @@ namespace bgslibrary
     void process(const long &frameNumber, const std::string &name, const cv::Mat &img_input);
 
   private:
-    void saveConfig();
-    void loadConfig();
+    void save_config(cv::FileStorage &fs);
+    void load_config(cv::FileStorage &fs);
   };
 }
diff --git a/src/package_analysis/PerformanceUtils.cpp b/src/tools/PerformanceUtils.cpp
similarity index 84%
rename from src/package_analysis/PerformanceUtils.cpp
rename to src/tools/PerformanceUtils.cpp
index 85d34af5763d0eefd6db4a3629f08ce24e4ec368..0e70fd63d670122fe576879126bf8d8064d0513d 100644
--- a/src/package_analysis/PerformanceUtils.cpp
+++ b/src/tools/PerformanceUtils.cpp
@@ -2,12 +2,15 @@
 //#include <opencv2/legacy/compat.hpp>
 //#include <opencv2/highgui/highgui_c.h>
 
-PerformanceUtils::PerformanceUtils(void) {}
+PerformanceUtils::PerformanceUtils() {
+  //debug_construction(PerformanceUtils);
+}
 
-PerformanceUtils::~PerformanceUtils(void) {}
+PerformanceUtils::~PerformanceUtils() {
+  //debug_destruction(PerformanceUtils);
+}
 
-float PerformanceUtils::NrPixels(IplImage *image)
-{
+float PerformanceUtils::NrPixels(IplImage *image) {
   return (float)(image->width * image->height);
 }
 
@@ -21,13 +24,10 @@ float PerformanceUtils::NrAllDetectedPixNotNULL(IplImage *image, IplImage *groun
 
   PixelUtils p;
 
-  for (int y = 0; y < image->height; y++)
-  {
-    for (int x = 0; x < image->width; x++)
-    {
+  for (int y = 0; y < image->height; y++) {
+    for (int x = 0; x < image->width; x++) {
       p.GetGrayPixel(ground_truth, x, y, pixelGT);
       p.GetGrayPixel(image, x, y, pixelI);
-
       if ((pixelGT[0] != 0) || (pixelI[0] != 0))
         Union12++;
     }
@@ -48,33 +48,27 @@ float PerformanceUtils::NrTruePositives(IplImage *image, IplImage *ground_truth,
 
   IplImage *TPimage = 0;
 
-  if (debug)
-  {
+  if (debug) {
     TPimage = cvCreateImage(cvSize(image->width, image->height), image->depth, image->nChannels);
     cvSetZero(TPimage);
   }
 
   PixelUtils p;
 
-  for (int y = 0; y < image->height; y++)
-  {
-    for (int x = 0; x < image->width; x++)
-    {
+  for (int y = 0; y < image->height; y++) {
+    for (int x = 0; x < image->width; x++) {
       p.GetGrayPixel(ground_truth, x, y, pixelGT);
       p.GetGrayPixel(image, x, y, pixelI);
 
-      if ((pixelGT[0] != 0) && (pixelI[0] != 0))
-      {
+      if ((pixelGT[0] != 0) && (pixelI[0] != 0)) {
         if (debug)
           p.PutGrayPixel(TPimage, x, y, *pixelI);
-
         nTP++;
       }
     }
   }
 
-  if (debug)
-  {
+  if (debug) {
     cvNamedWindow("TPImage", 0);
     cvShowImage("TPImage", TPimage);
     //std::cout << "True Positives: " << nTP << std::endl;
@@ -98,35 +92,28 @@ float PerformanceUtils::NrTrueNegatives(IplImage* image, IplImage* ground_truth,
 
   IplImage *TNimage = 0;
 
-  if (debug)
-  {
+  if (debug) {
     TNimage = cvCreateImage(cvSize(image->width, image->height), image->depth, image->nChannels);
     cvSetZero(TNimage);
   }
 
   PixelUtils p;
 
-  for (int y = 0; y < image->height; y++)
-  {
-    for (int x = 0; x < image->width; x++)
-    {
+  for (int y = 0; y < image->height; y++) {
+    for (int x = 0; x < image->width; x++) {
       p.GetGrayPixel(ground_truth, x, y, pixelGT);
       p.GetGrayPixel(image, x, y, pixelI);
 
-      if ((pixelGT[0] == 0) && (pixelI[0] == 0.0))
-      {
+      if ((pixelGT[0] == 0) && (pixelI[0] == 0.0)) {
         *pixelI = 255;
-
         if (debug)
           p.PutGrayPixel(TNimage, x, y, *pixelI);
-
         nTN++;
       }
     }
   }
 
-  if (debug)
-  {
+  if (debug) {
     cvNamedWindow("TNImage", 0);
     cvShowImage("TNImage", TNimage);
     //std::cout << "True Negatives: " << nTN << std::endl;
@@ -150,33 +137,27 @@ float PerformanceUtils::NrFalsePositives(IplImage *image, IplImage *ground_truth
 
   IplImage *FPimage = 0;
 
-  if (debug)
-  {
+  if (debug) {
     FPimage = cvCreateImage(cvSize(image->width, image->height), image->depth, image->nChannels);
     cvSetZero(FPimage);
   }
 
   PixelUtils p;
 
-  for (int y = 0; y < image->height; y++)
-  {
-    for (int x = 0; x < image->width; x++)
-    {
+  for (int y = 0; y < image->height; y++) {
+    for (int x = 0; x < image->width; x++) {
       p.GetGrayPixel(ground_truth, x, y, pixelGT);
       p.GetGrayPixel(image, x, y, pixelI);
 
-      if ((pixelGT[0] == 0) && (pixelI[0] != 0))
-      {
+      if ((pixelGT[0] == 0) && (pixelI[0] != 0)) {
         if (debug)
           p.PutGrayPixel(FPimage, x, y, *pixelI);
-
         nFP++;
       }
     }
   }
 
-  if (debug)
-  {
+  if (debug) {
     cvNamedWindow("FPImage", 0);
     cvShowImage("FPImage", FPimage);
     //std::cout << "False Positives: " << nFP << std::endl;
@@ -200,33 +181,27 @@ float PerformanceUtils::NrFalseNegatives(IplImage * image, IplImage *ground_trut
 
   IplImage *FNimage = 0;
 
-  if (debug)
-  {
+  if (debug) {
     FNimage = cvCreateImage(cvSize(image->width, image->height), image->depth, image->nChannels);
     cvSetZero(FNimage);
   }
 
   PixelUtils p;
 
-  for (int y = 0; y < image->height; y++)
-  {
-    for (int x = 0; x < image->width; x++)
-    {
+  for (int y = 0; y < image->height; y++) {
+    for (int x = 0; x < image->width; x++) {
       p.GetGrayPixel(ground_truth, x, y, pixelGT);
       p.GetGrayPixel(image, x, y, pixelI);
 
-      if ((pixelGT[0] != 0) && (pixelI[0] == 0))
-      {
+      if ((pixelGT[0] != 0) && (pixelI[0] == 0)) {
         if (debug)
           p.PutGrayPixel(FNimage, x, y, *pixelGT);
-
         nFN++;
       }
     }
   }
 
-  if (debug)
-  {
+  if (debug) {
     cvNamedWindow("FNImage", 0);
     cvShowImage("FNImage", FNimage);
     //std::cout << "False Negatives: " << nFN << std::endl;
@@ -250,13 +225,11 @@ float PerformanceUtils::SimilarityMeasure(IplImage *image, IplImage *ground_trut
   cv::Mat i;
   cv::Mat u;
 
-  if (rn > 0)
-  {
+  if (rn > 0) {
     i = img_input & img_ref;
     u = img_input | img_ref;
   }
-  else
-  {
+  else {
     i = (~img_input) & (~img_ref);
     u = (~img_input) | (~img_ref);
   }
@@ -266,8 +239,7 @@ float PerformanceUtils::SimilarityMeasure(IplImage *image, IplImage *ground_trut
 
   double s = (((double)in) / ((double)un));
 
-  if (debug)
-  {
+  if (debug) {
     cv::imshow("A^B", i);
     cv::imshow("AvB", u);
 
@@ -290,33 +262,27 @@ void PerformanceUtils::ImageROC(IplImage *image, IplImage* ground_truth, bool sa
 
   PixelUtils p;
 
-  for (int y = 0; y < image->height; y++)
-  {
-    for (int x = 0; x < image->width; x++)
-    {
+  for (int y = 0; y < image->height; y++) {
+    for (int x = 0; x < image->width; x++) {
       p.GetGrayPixel(ground_truth, x, y, pixelGT);
       p.GetGrayPixel(image, x, y, pixelI);
 
-      if ((pixelGT[0] != 0) && (pixelI[0] != 0)) // TP
-      {
+      if ((pixelGT[0] != 0) && (pixelI[0] != 0)) { // TP
         *pixelI = 30;
         p.PutGrayPixel(ROCimage, x, y, *pixelI);
       }
 
-      if ((pixelGT[0] == 0) && (pixelI[0] == 0.0)) // TN
-      {
+      if ((pixelGT[0] == 0) && (pixelI[0] == 0.0)) { // TN
         *pixelI = 0;
         p.PutGrayPixel(ROCimage, x, y, *pixelI);
       }
 
-      if ((pixelGT[0] == 0) && (pixelI[0] != 0)) // FP
-      {
+      if ((pixelGT[0] == 0) && (pixelI[0] != 0)) { // FP
         *pixelI = 255;
         p.PutGrayPixel(ROCimage, x, y, *pixelI);
       }
 
-      if ((pixelGT[0] != 0) && (pixelI[0] == 0)) // FN
-      {
+      if ((pixelGT[0] != 0) && (pixelI[0] == 0)) { // FN
         *pixelI = 100;
         p.PutGrayPixel(ROCimage, x, y, *pixelI);
       }
@@ -326,8 +292,7 @@ void PerformanceUtils::ImageROC(IplImage *image, IplImage* ground_truth, bool sa
   cvNamedWindow("ROC image", 0);
   cvShowImage("ROC image", ROCimage);
 
-  if (saveResults)
-  {
+  if (saveResults) {
     unsigned char *pixelOI = (unsigned char*)malloc(1 * sizeof(unsigned char));
     unsigned char *pixelROC = (unsigned char*)malloc(1 * sizeof(unsigned char));
 
@@ -345,38 +310,31 @@ void PerformanceUtils::ImageROC(IplImage *image, IplImage* ground_truth, bool sa
       for (int j = 0; j < 6; j++)
         freq[i][j] = 0.0;
 
-    for (int y = 0; y < image->height; y++)
-    {
-      for (int x = 0; x < image->width; x++)
-      {
-        for (int i = 0; i < 256; i++)
-        {
+    for (int y = 0; y < image->height; y++) {
+      for (int x = 0; x < image->width; x++) {
+        for (int i = 0; i < 256; i++) {
           p.GetGrayPixel(image, x, y, pixelOI);
           p.GetGrayPixel(ROCimage, x, y, pixelROC);
 
-          if ((pixelOI[0] == i) && (pixelROC[0] == 30.0)) // TP
-          {
+          if ((pixelOI[0] == i) && (pixelROC[0] == 30.0)) { // TP
             nTP++;
             freq[i][0] = nTP;
             break;
           }
 
-          if ((pixelOI[0] == i) && (pixelROC[0] == 0.0)) // TN
-          {
+          if ((pixelOI[0] == i) && (pixelROC[0] == 0.0)) { // TN
             nTN++;
             freq[i][1] = nTN;
             break;
           }
 
-          if ((pixelOI[0] == i) && (pixelROC[0] == 255.0)) // FP
-          {
+          if ((pixelOI[0] == i) && (pixelROC[0] == 255.0)) { // FP
             nFP++;
             freq[i][2] = nFP;
             break;
           }
 
-          if ((pixelOI[0] == i) && (pixelROC[0] == 100)) // FN
-          {
+          if ((pixelOI[0] == i) && (pixelROC[0] == 100)) { // FN
             nFN++;
             freq[i][3] = nFN;
             break;
@@ -396,16 +354,13 @@ void PerformanceUtils::ImageROC(IplImage *image, IplImage* ground_truth, bool sa
 
     if (!f.is_open())
       std::cout << "Failed to open file " << filename << " for writing!" << std::endl;
-    else
-    {
+    else {
       f << "  I     TP     TN     FP     FN    FPR      FNR      DR   \n" << std::endl;
 
-      for (int i = 0; i < 256; i++)
-      {
+      for (int i = 0; i < 256; i++) {
         //printf("%4d - TP:%5.0f, TN:%5.0f, FP:%5.0f, FN:%5.0f,", i, freq[i][0], freq[i][1], freq[i][2], freq[i][3]);
 
-        if ((freq[i][3] + freq[i][0] != 0.0) && (freq[i][2] + freq[i][1] != 0.0))
-        {
+        if ((freq[i][3] + freq[i][0] != 0.0) && (freq[i][2] + freq[i][1] != 0.0)) {
           freq[i][4] = freq[i][3] / (freq[i][3] + freq[i][0]);  // FNR = FN / (TP + FN);
           freq[i][5] = freq[i][2] / (freq[i][2] + freq[i][1]);	// FPR = FP / (FP + TN);
           freq[i][6] = freq[i][0] / (freq[i][0] + freq[i][3]);	// DR = TP / (TP+FN);
@@ -491,14 +446,12 @@ void PerformanceUtils::PerformanceEvaluation(IplImage *image, IplImage *ground_t
   std::string results = sstm.str();
   std::cout << results;
 
-  if (saveResults)
-  {
+  if (saveResults) {
     std::ofstream f(filename);
 
     if (!f.is_open())
       std::cout << "Failed to open file " << filename << " for writing!" << std::endl;
-    else
-    {
+    else {
       f << results;
       std::cout << "Results saved in " << filename << std::endl;
       f.close();
diff --git a/src/package_analysis/PerformanceUtils.h b/src/tools/PerformanceUtils.h
similarity index 94%
rename from src/package_analysis/PerformanceUtils.h
rename to src/tools/PerformanceUtils.h
index 064d3f17c448648052f3d3d357b3fa3d47eec132..ce4549d5b59e00a4490a285d4ff2571f78efca89 100644
--- a/src/package_analysis/PerformanceUtils.h
+++ b/src/tools/PerformanceUtils.h
@@ -9,8 +9,8 @@
 class PerformanceUtils
 {
 public:
-  PerformanceUtils(void);
-  ~PerformanceUtils(void);
+  PerformanceUtils();
+  ~PerformanceUtils();
 
   float NrPixels(IplImage *image);
   float NrAllDetectedPixNotNULL(IplImage *image, IplImage *ground_truth);
diff --git a/src/package_analysis/PixelUtils.cpp b/src/tools/PixelUtils.cpp
similarity index 98%
rename from src/package_analysis/PixelUtils.cpp
rename to src/tools/PixelUtils.cpp
index 1f7e38ff6370e7f8508c3643025cecd79b586288..3770e7eaf925d6c2fcfe86bf73bd21270c224245 100644
--- a/src/package_analysis/PixelUtils.cpp
+++ b/src/tools/PixelUtils.cpp
@@ -1,7 +1,11 @@
 #include "PixelUtils.h"
 
-PixelUtils::PixelUtils(void) {}
-PixelUtils::~PixelUtils(void) {}
+PixelUtils::PixelUtils() {
+  //debug_construction(PixelUtils);
+}
+PixelUtils::~PixelUtils() {
+  //debug_destruction(PixelUtils);
+}
 
 void PixelUtils::ColorConversion(IplImage* RGBImage, IplImage* ConvertedImage, int color_space)
 {
diff --git a/src/package_analysis/PixelUtils.h b/src/tools/PixelUtils.h
similarity index 97%
rename from src/package_analysis/PixelUtils.h
rename to src/tools/PixelUtils.h
index b48866a6719cb13ca75f9fd73b73dc14ce398be8..51aade49b62f3918b77d69faa08b1ac2dcf46cb8 100644
--- a/src/package_analysis/PixelUtils.h
+++ b/src/tools/PixelUtils.h
@@ -9,8 +9,8 @@
 class PixelUtils
 {
 public:
-  PixelUtils(void);
-  ~PixelUtils(void);
+  PixelUtils();
+  ~PixelUtils();
 
   void ColorConversion(IplImage* RGBImage, IplImage* ConvertedImage, int color_space);
   void cvttoOTHA(IplImage* RGBImage, IplImage* OthaImage);
diff --git a/src/Config.h b/src/utils/GenericKeys.h
similarity index 100%
rename from src/Config.h
rename to src/utils/GenericKeys.h
diff --git a/src/utils/GenericMacros.h b/src/utils/GenericMacros.h
new file mode 100755
index 0000000000000000000000000000000000000000..025bf72a45d4e08129888c599c3e0e3fc191ac5d
--- /dev/null
+++ b/src/utils/GenericMacros.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <iostream>
+
+#define DEBUG_OBJ_LIFE
+
+#if !defined(quote)
+#define quote(x) #x
+#endif
+
+#if !defined(debug_construction)
+#if defined(DEBUG_OBJ_LIFE)
+#define debug_construction(x) std::cout << "+" << quote(x) << "()" << std::endl
+#else
+#define debug_construction(x)
+#endif
+#endif
+
+#if !defined(debug_destruction)
+#if defined(DEBUG_OBJ_LIFE)
+#define debug_destruction(x) std::cout << "-" << quote(x) << "()" << std::endl
+#else
+#define debug_destruction(x)
+#endif
+#endif
diff --git a/src/utils/ILoadSaveConfig.h b/src/utils/ILoadSaveConfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..2d2261a1c263f3e452700789f4ca5bc55e2ab8e4
--- /dev/null
+++ b/src/utils/ILoadSaveConfig.h
@@ -0,0 +1,72 @@
+#pragma once
+
+#include <iostream>
+#include <fstream>
+#include <string>
+
+#include "GenericMacros.h"
+
+namespace bgslibrary
+{
+  const std::string DEFAULT_CONFIG_BASE_PATH = "./config";
+  const std::string DEFAULT_CONFIG_EXTENSION = ".xml";
+  
+  class ILoadSaveConfig
+  {
+  public:
+    ILoadSaveConfig() :
+    config_base_path(DEFAULT_CONFIG_BASE_PATH),
+    config_extension(DEFAULT_CONFIG_EXTENSION),
+    config_file_path("")
+    {
+      //debug_construction(ILoadSaveConfig);
+    }
+    virtual ~ILoadSaveConfig() {
+      //debug_destruction(ILoadSaveConfig);
+    }
+
+  protected:
+    std::string config_base_path;
+    std::string config_extension;
+    std::string config_file_path;
+    //static const std::string config_base_path;
+    //static const std::string config_extension;
+    virtual void save_config(cv::FileStorage &fs) = 0;
+    virtual void load_config(cv::FileStorage &fs) = 0;
+    void initLoadSaveConfig(const std::string _config_file_name) {
+      if(!_config_file_name.empty()) {
+        config_file_path = config_base_path + "/" + _config_file_name + config_extension;
+        if (!std::ifstream(config_file_path))
+          _save_config();
+        _load_config();
+      }
+    }
+    
+  private:
+    void _save_config() {
+      //std::cout << "_save_config: " << config_file_path << std::endl;
+      cv::FileStorage fs(config_file_path, cv::FileStorage::WRITE);
+      if (_is_valid(fs))
+        save_config(fs);
+      fs.release();
+    }
+    void _load_config() {
+      //std::cout << "_load_config: " << config_file_path << std::endl;
+      cv::FileStorage fs;
+      fs.open(config_file_path, cv::FileStorage::READ);
+      if (_is_valid(fs))
+        load_config(fs);
+      fs.release();
+    }
+    bool _is_valid(cv::FileStorage &fs) {
+      if (!fs.isOpened()) {
+        std::cerr << "Failed to open " << config_file_path << std::endl;
+        //std::cerr << "Please check if the path above is valid" << std::endl;
+        return false;
+      }
+      return true;
+    }
+  };
+  //const std::string ILoadSaveConfig::config_base_path = "./config";
+  //const std::string ILoadSaveConfig::config_extension = ".xml";
+}
diff --git a/wrapper/java/CMakeLists.txt b/wrapper/java/CMakeLists.txt
index 705866046b8ab63b87cda156ec06cf323d5ca8a9..fc044fa89c9151c03cdd314d58479ad018ee9d5e 100644
--- a/wrapper/java/CMakeLists.txt
+++ b/wrapper/java/CMakeLists.txt
@@ -58,16 +58,18 @@ if (OpenCV_FOUND)
   message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")
 endif()
 
-file(GLOB_RECURSE analysis_src ../../src/package_analysis/*.cpp)
-file(GLOB_RECURSE analysis_inc ../../src/package_analysis/*.h)
-file(GLOB_RECURSE bgs_src ../../src/package_bgs/*.cpp ../../src/package_bgs/*.c)
-file(GLOB_RECURSE bgs_inc ../../src/package_bgs/*.h)
+file(GLOB_RECURSE tools_src ../../src/tools/*.cpp ../../src/tools/*.c)
+file(GLOB_RECURSE tools_inc ../../src/tools/*.h ../../src/tools/*.hpp)
+file(GLOB_RECURSE utils_src ../../src/utils/*.cpp ../../src/utils/*.c)
+file(GLOB_RECURSE utils_inc ../../src/utils/*.h ../../src/utils/*.hpp)
+file(GLOB_RECURSE bgs_src ../../src/algorithms/*.cpp ../../src/algorithms/*.c)
+file(GLOB_RECURSE bgs_inc ../../src/algorithms/*.h ../../src/algorithms/*.hpp)
 
 include_directories(${CMAKE_SOURCE_DIR} ${JNI_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS})
 
-add_library(libbgs STATIC ${bgs_src} ${analysis_src})
+add_library(libbgs STATIC ${bgs_src} ${tools_src} ${utils_src})
 target_link_libraries(libbgs ${OpenCV_LIBS})
-set_property(TARGET libbgs PROPERTY PUBLIC_HEADER ${bgs_inc} ${analysis_inc})
+set_property(TARGET libbgs PROPERTY PUBLIC_HEADER ${bgs_inc} ${tools_inc} ${utils_inc})
 if(WIN32)
 	# set_property(TARGET libbgs PROPERTY SUFFIX ".lib")
 else()
diff --git a/wrapper/java/bgslibrary_java_module.hpp b/wrapper/java/bgslibrary_java_module.hpp
index b2d46eae8f2e6816322dbef0ba523687c5739dcc..1044f28cd2caa3bc95c1100a2cf6fbdec221ba20 100644
--- a/wrapper/java/bgslibrary_java_module.hpp
+++ b/wrapper/java/bgslibrary_java_module.hpp
@@ -6,7 +6,7 @@
 #include <string>
 
 #include "src/bgslibrary_BgsLib.h"
-#include "../../src/package_bgs/bgslibrary.h"
+#include "../../src/algorithms/algorithms.h"
 
 bool constructObject(std::string algorithm);
 void computeForegroundMask(const cv::Mat &img_input, cv::Mat &img_output);
diff --git a/wrapper/matlab/compile.m b/wrapper/matlab/compile.m
index 644464ec3d01b808c6519873bd5fee08487363b8..a0935bb5fe1b226cb112552035b93ddc4ba9fdab 100644
--- a/wrapper/matlab/compile.m
+++ b/wrapper/matlab/compile.m
@@ -1,95 +1,95 @@
 %% Compile
 clc;
-mexOpenCV -v -DMEX_COMPILE_FLAG -I"../../src/package_bgs" backgroundSubtractor_wrapper.cpp ...
-  "../../src/package_bgs/FrameDifference.cpp" ...
-  "../../src/package_bgs/StaticFrameDifference.cpp" ...
-  "../../src/package_bgs/WeightedMovingMean.cpp" ...
-  "../../src/package_bgs/WeightedMovingVariance.cpp" ...
-  "../../src/package_bgs/MixtureOfGaussianV1.cpp" ...
-  "../../src/package_bgs/MixtureOfGaussianV2.cpp" ...
-  "../../src/package_bgs/AdaptiveBackgroundLearning.cpp" ...
-  "../../src/package_bgs/AdaptiveSelectiveBackgroundLearning.cpp" ...
-  "../../src/package_bgs/GMG.cpp" ...
-  "../../src/package_bgs/KNN.cpp" ...
-  "../../src/package_bgs/DPAdaptiveMedian.cpp" ...
-  "../../src/package_bgs/DPGrimsonGMM.cpp" ...
-  "../../src/package_bgs/DPZivkovicAGMM.cpp" ...
-  "../../src/package_bgs/DPMean.cpp" ...
-  "../../src/package_bgs/DPWrenGA.cpp" ...
-  "../../src/package_bgs/DPPratiMediod.cpp" ...
-  "../../src/package_bgs/DPEigenbackground.cpp" ...
-  "../../src/package_bgs/DPTexture.cpp" ...
-  "../../src/package_bgs/dp/AdaptiveMedianBGS.cpp" ...
-  "../../src/package_bgs/dp/Image.cpp" ...
-  "../../src/package_bgs/dp/Error.cpp" ...
-  "../../src/package_bgs/dp/GrimsonGMM.cpp" ...
-  "../../src/package_bgs/dp/ZivkovicAGMM.cpp" ...
-  "../../src/package_bgs/dp/MeanBGS.cpp" ...
-  "../../src/package_bgs/dp/WrenGA.cpp"  ...
-  "../../src/package_bgs/dp/PratiMediodBGS.cpp" ...
-  "../../src/package_bgs/dp/Eigenbackground.cpp" ...
-  "../../src/package_bgs/dp/TextureBGS.cpp" ...
-  "../../src/package_bgs/T2FGMM_UM.cpp" ...
-  "../../src/package_bgs/T2FGMM_UV.cpp" ...
-  "../../src/package_bgs/T2FMRF_UM.cpp" ...
-  "../../src/package_bgs/T2FMRF_UV.cpp" ...
-  "../../src/package_bgs/FuzzyChoquetIntegral.cpp" ...
-  "../../src/package_bgs/FuzzySugenoIntegral.cpp" ...
-  "../../src/package_bgs/T2F/T2FGMM.cpp" ...
-  "../../src/package_bgs/T2F/T2FMRF.cpp" ...
-  "../../src/package_bgs/T2F/MRF.cpp" ...
-  "../../src/package_bgs/T2F/FuzzyUtils.cpp" ...
-  "../../src/package_analysis/PixelUtils.cpp" ...
-  "../../src/package_bgs/MultiLayer.cpp" ...
-  "../../src/package_bgs/MultiLayer/CMultiLayerBGS.cpp" ...
-  "../../src/package_bgs/MultiLayer/LocalBinaryPattern.cpp" ...
-  "../../src/package_bgs/MultiLayer/BlobResult.cpp" ...
-  "../../src/package_bgs/MultiLayer/BlobExtraction.cpp" ...
-  "../../src/package_bgs/MultiLayer/blob.cpp" ...
-  "../../src/package_bgs/LBSimpleGaussian.cpp" ...
-  "../../src/package_bgs/LBFuzzyGaussian.cpp" ...
-  "../../src/package_bgs/LBMixtureOfGaussians.cpp" ...
-  "../../src/package_bgs/LBAdaptiveSOM.cpp" ...
-  "../../src/package_bgs/LBFuzzyAdaptiveSOM.cpp" ...
-  "../../src/package_bgs/lb/BGModel.cpp" ...
-  "../../src/package_bgs/lb/BGModelFuzzyGauss.cpp" ...
-  "../../src/package_bgs/lb/BGModelFuzzySom.cpp" ...
-  "../../src/package_bgs/lb/BGModelGauss.cpp" ...
-  "../../src/package_bgs/lb/BGModelMog.cpp" ...
-  "../../src/package_bgs/lb/BGModelSom.cpp" ...
-  "../../src/package_bgs/LBP_MRF.cpp" ...
-  "../../src/package_bgs/LBP_MRF/MotionDetection.cpp" ...
-  "../../src/package_bgs/LBP_MRF/MEImage.cpp" ...
-  "../../src/package_bgs/LBP_MRF/MEHistogram.cpp" ...
-  "../../src/package_bgs/LBP_MRF/MEDefs.cpp" ...
-  "../../src/package_bgs/LBP_MRF/maxflow.cpp" ...
-  "../../src/package_bgs/LBP_MRF/graph.cpp" ...
-  "../../src/package_bgs/PixelBasedAdaptiveSegmenter.cpp" ...
-  "../../src/package_bgs/PBAS/PBAS.cpp" ...
-  "../../src/package_bgs/VuMeter.cpp" ...
-  "../../src/package_bgs/VuMeter/TBackgroundVuMeter.cpp" ...
-  "../../src/package_bgs/VuMeter/TBackground.cpp" ...
-  "../../src/package_bgs/KDE.cpp" ...
-  "../../src/package_bgs/KDE/NPBGSubtractor.cpp" ...
-  "../../src/package_bgs/KDE/NPBGmodel.cpp" ...
-  "../../src/package_bgs/KDE/KernelTable.cpp" ...
-  "../../src/package_bgs/IndependentMultimodal.cpp" ...
-  "../../src/package_bgs/IMBS/IMBS.cpp" ...
-  "../../src/package_bgs/MultiCue.cpp" ...
-  "../../src/package_bgs/SigmaDelta.cpp" ...
-  "../../src/package_bgs/SigmaDelta/sdLaMa091.cpp" ...
-  "../../src/package_bgs/SuBSENSE.cpp" ...
-  "../../src/package_bgs/LOBSTER.cpp" ...
-  "../../src/package_bgs/PAWCS.cpp" ...
-  "../../src/package_bgs/LBSP/LBSP.cpp" ...
-  "../../src/package_bgs/LBSP/LBSP_.cpp" ...
-  "../../src/package_bgs/LBSP/BackgroundSubtractorLBSP.cpp" ...
-  "../../src/package_bgs/LBSP/BackgroundSubtractorLBSP_.cpp" ...
-  "../../src/package_bgs/LBSP/BackgroundSubtractorLOBSTER.cpp" ...
-  "../../src/package_bgs/LBSP/BackgroundSubtractorPAWCS.cpp" ...
-  "../../src/package_bgs/LBSP/BackgroundSubtractorSuBSENSE.cpp" ...
-  "../../src/package_bgs/ViBe.cpp" ...
-  "../../src/package_bgs/ViBe/vibe-background-sequential.cpp" ...
-  "../../src/package_bgs/TwoPoints.cpp" ...
-  "../../src/package_bgs/TwoPoints/two_points.cpp" ...
-  "../../src/package_bgs/CodeBook.cpp"
+mexOpenCV -v -DMEX_COMPILE_FLAG -I"../../src/algorithms" backgroundSubtractor_wrapper.cpp ...
+  "../../src/algorithms/FrameDifference.cpp" ...
+  "../../src/algorithms/StaticFrameDifference.cpp" ...
+  "../../src/algorithms/WeightedMovingMean.cpp" ...
+  "../../src/algorithms/WeightedMovingVariance.cpp" ...
+  "../../src/algorithms/MixtureOfGaussianV1.cpp" ...
+  "../../src/algorithms/MixtureOfGaussianV2.cpp" ...
+  "../../src/algorithms/AdaptiveBackgroundLearning.cpp" ...
+  "../../src/algorithms/AdaptiveSelectiveBackgroundLearning.cpp" ...
+  "../../src/algorithms/GMG.cpp" ...
+  "../../src/algorithms/KNN.cpp" ...
+  "../../src/algorithms/DPAdaptiveMedian.cpp" ...
+  "../../src/algorithms/DPGrimsonGMM.cpp" ...
+  "../../src/algorithms/DPZivkovicAGMM.cpp" ...
+  "../../src/algorithms/DPMean.cpp" ...
+  "../../src/algorithms/DPWrenGA.cpp" ...
+  "../../src/algorithms/DPPratiMediod.cpp" ...
+  "../../src/algorithms/DPEigenbackground.cpp" ...
+  "../../src/algorithms/DPTexture.cpp" ...
+  "../../src/algorithms/dp/AdaptiveMedianBGS.cpp" ...
+  "../../src/algorithms/dp/Image.cpp" ...
+  "../../src/algorithms/dp/Error.cpp" ...
+  "../../src/algorithms/dp/GrimsonGMM.cpp" ...
+  "../../src/algorithms/dp/ZivkovicAGMM.cpp" ...
+  "../../src/algorithms/dp/MeanBGS.cpp" ...
+  "../../src/algorithms/dp/WrenGA.cpp"  ...
+  "../../src/algorithms/dp/PratiMediodBGS.cpp" ...
+  "../../src/algorithms/dp/Eigenbackground.cpp" ...
+  "../../src/algorithms/dp/TextureBGS.cpp" ...
+  "../../src/algorithms/T2FGMM_UM.cpp" ...
+  "../../src/algorithms/T2FGMM_UV.cpp" ...
+  "../../src/algorithms/T2FMRF_UM.cpp" ...
+  "../../src/algorithms/T2FMRF_UV.cpp" ...
+  "../../src/algorithms/FuzzyChoquetIntegral.cpp" ...
+  "../../src/algorithms/FuzzySugenoIntegral.cpp" ...
+  "../../src/algorithms/T2F/T2FGMM.cpp" ...
+  "../../src/algorithms/T2F/T2FMRF.cpp" ...
+  "../../src/algorithms/T2F/MRF.cpp" ...
+  "../../src/algorithms/T2F/FuzzyUtils.cpp" ...
+  "../../src/tools/PixelUtils.cpp" ...
+  "../../src/algorithms/MultiLayer.cpp" ...
+  "../../src/algorithms/MultiLayer/CMultiLayerBGS.cpp" ...
+  "../../src/algorithms/MultiLayer/LocalBinaryPattern.cpp" ...
+  "../../src/algorithms/MultiLayer/BlobResult.cpp" ...
+  "../../src/algorithms/MultiLayer/BlobExtraction.cpp" ...
+  "../../src/algorithms/MultiLayer/blob.cpp" ...
+  "../../src/algorithms/LBSimpleGaussian.cpp" ...
+  "../../src/algorithms/LBFuzzyGaussian.cpp" ...
+  "../../src/algorithms/LBMixtureOfGaussians.cpp" ...
+  "../../src/algorithms/LBAdaptiveSOM.cpp" ...
+  "../../src/algorithms/LBFuzzyAdaptiveSOM.cpp" ...
+  "../../src/algorithms/lb/BGModel.cpp" ...
+  "../../src/algorithms/lb/BGModelFuzzyGauss.cpp" ...
+  "../../src/algorithms/lb/BGModelFuzzySom.cpp" ...
+  "../../src/algorithms/lb/BGModelGauss.cpp" ...
+  "../../src/algorithms/lb/BGModelMog.cpp" ...
+  "../../src/algorithms/lb/BGModelSom.cpp" ...
+  "../../src/algorithms/LBP_MRF.cpp" ...
+  "../../src/algorithms/LBP_MRF/MotionDetection.cpp" ...
+  "../../src/algorithms/LBP_MRF/MEImage.cpp" ...
+  "../../src/algorithms/LBP_MRF/MEHistogram.cpp" ...
+  "../../src/algorithms/LBP_MRF/MEDefs.cpp" ...
+  "../../src/algorithms/LBP_MRF/maxflow.cpp" ...
+  "../../src/algorithms/LBP_MRF/graph.cpp" ...
+  "../../src/algorithms/PixelBasedAdaptiveSegmenter.cpp" ...
+  "../../src/algorithms/PBAS/PBAS.cpp" ...
+  "../../src/algorithms/VuMeter.cpp" ...
+  "../../src/algorithms/VuMeter/TBackgroundVuMeter.cpp" ...
+  "../../src/algorithms/VuMeter/TBackground.cpp" ...
+  "../../src/algorithms/KDE.cpp" ...
+  "../../src/algorithms/KDE/NPBGSubtractor.cpp" ...
+  "../../src/algorithms/KDE/NPBGmodel.cpp" ...
+  "../../src/algorithms/KDE/KernelTable.cpp" ...
+  "../../src/algorithms/IndependentMultimodal.cpp" ...
+  "../../src/algorithms/IMBS/IMBS.cpp" ...
+  "../../src/algorithms/MultiCue.cpp" ...
+  "../../src/algorithms/SigmaDelta.cpp" ...
+  "../../src/algorithms/SigmaDelta/sdLaMa091.cpp" ...
+  "../../src/algorithms/SuBSENSE.cpp" ...
+  "../../src/algorithms/LOBSTER.cpp" ...
+  "../../src/algorithms/PAWCS.cpp" ...
+  "../../src/algorithms/LBSP/LBSP.cpp" ...
+  "../../src/algorithms/LBSP/LBSP_.cpp" ...
+  "../../src/algorithms/LBSP/BackgroundSubtractorLBSP.cpp" ...
+  "../../src/algorithms/LBSP/BackgroundSubtractorLBSP_.cpp" ...
+  "../../src/algorithms/LBSP/BackgroundSubtractorLOBSTER.cpp" ...
+  "../../src/algorithms/LBSP/BackgroundSubtractorPAWCS.cpp" ...
+  "../../src/algorithms/LBSP/BackgroundSubtractorSuBSENSE.cpp" ...
+  "../../src/algorithms/ViBe.cpp" ...
+  "../../src/algorithms/ViBe/vibe-background-sequential.cpp" ...
+  "../../src/algorithms/TwoPoints.cpp" ...
+  "../../src/algorithms/TwoPoints/two_points.cpp" ...
+  "../../src/algorithms/CodeBook.cpp"
diff --git a/wrapper/python/bgslibrary_module.cpp b/wrapper/python/bgslibrary_module.cpp
index 5cf2f6e6e8a9245eee73a1abefa1927e41df24ad..65274bae3de31bd834155e10fb06e66308e087f3 100644
--- a/wrapper/python/bgslibrary_module.cpp
+++ b/wrapper/python/bgslibrary_module.cpp
@@ -4,7 +4,7 @@
 #include <opencv2/opencv.hpp>
 
 #include "ndarray_converter.h"
-#include "../../src/package_bgs/bgslibrary.h"
+#include "../../src/algorithms/algorithms.h"
 
 #if CV_MAJOR_VERSION >= 4
 #define CV_LOAD_IMAGE_COLOR cv::IMREAD_COLOR