diff --git a/.gitignore b/.gitignore
index d7d4599d47adc998a0d92afd718804f56edbfb3b..f64181f0e271d7eba3ba146d8dc9cbf229c5f285 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
+
+# IDE specific files
 .project
 .cproject
 .vs/
@@ -5,6 +7,12 @@
 .idea/
 .editorconfig
 
+# build directories
 build/
 cmake-build-debug/
 cmake-build-release/
+
+# VS build files and binaries
+*.exe
+*.ilk
+*.pdb
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 58669d661a0be4cfabcdab69a0639fa28d429c50..569efcf20fe84a64205b7060bbb89587cbe579da 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,6 +12,11 @@ if (CMAKE_BUILD_TYPE)
 endif()
 
 message("-- Language: [ C++ " ${CMAKE_CXX_STANDARD} " ]")
+message("-- Compiler: [ " ${CMAKE_CXX_COMPILER_ID} " " ${CMAKE_CXX_COMPILER_VERSION} " ]")
+
+if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "9.0.0"))
+	message(FATAL_ERROR "Upgrade your compiler! GCC 9.0+ is required!")
+endif()
 
 # setting up different paths
 set(vkcv_config ${PROJECT_SOURCE_DIR}/config)
@@ -36,17 +41,21 @@ if (vkcv_build_debug)
 	endif()
 endif()
 
+# add modules as targets
+add_subdirectory(modules)
+
 # add source files for compilation
 include(${vkcv_config}/Sources.cmake)
 
 # configure everything to use the required dependencies
 include(${vkcv_config}/Libraries.cmake)
 
+message("-- Libraries: [ ${vkcv_libraries} ]")
+message("-- Flags: [ ${vkcv_flags} ]")
+
 # set the compiler flags for the framework
 set(CMAKE_CXX_FLAGS ${vkcv_flags})
 
-message("-- Flags: [ ${CMAKE_CXX_FLAGS} ]")
-
 # set the compile definitions aka preprocessor variables
 add_compile_definitions(${vkcv_definitions})
 
diff --git a/config/Libraries.cmake b/config/Libraries.cmake
index ef199df6ed4d59acb87d6b0d6b4d2261081c82d4..16b1db3928800a3b421430737fdc8d97a392054e 100644
--- a/config/Libraries.cmake
+++ b/config/Libraries.cmake
@@ -2,8 +2,8 @@
 set(vkcv_config_lib ${vkcv_config}/lib)
 set(vkcv_lib_path ${PROJECT_SOURCE_DIR}/${vkcv_lib})
 
-if(NOT WIN32)
-	set(vkcv_libraries stdc++fs)
+if(NOT MSVC)
+	set(vkcv_libraries  stdc++fs)
 	
 	# optimization for loading times
 	list(APPEND vkcv_flags -pthread)
diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp
index 506e72f2363a791bff9aba59348ced3b6ac4c798..54a9cbbe922f42083b65eae4999d0802e6c2c27e 100644
--- a/include/vkcv/Core.hpp
+++ b/include/vkcv/Core.hpp
@@ -5,8 +5,8 @@
  */
 
 #include <memory>
-
 #include <vulkan/vulkan.hpp>
+
 #include "vkcv/Context.hpp"
 #include "vkcv/SwapChain.hpp"
 #include "vkcv/Window.hpp"
@@ -15,6 +15,7 @@
 #include "vkcv/PipelineConfig.hpp"
 #include "CommandResources.hpp"
 #include "SyncResources.hpp"
+#include "Result.hpp"
 #include "vkcv/QueueManager.hpp"
 
 namespace vkcv
@@ -40,7 +41,7 @@ namespace vkcv
         // explicit destruction of default constructor
         Core() = delete;
 
-		uint32_t acquireSwapchainImage();
+		Result acquireSwapchainImage();
 		void destroyTemporaryFramebuffers();
 
         Context m_Context;
diff --git a/include/vkcv/Result.hpp b/include/vkcv/Result.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b78e444de9040f2982122d9242f584c7f9c340cf
--- /dev/null
+++ b/include/vkcv/Result.hpp
@@ -0,0 +1,12 @@
+#pragma once
+
+namespace vkcv {
+	
+	enum class Result {
+		
+		SUCCESS = 0,
+		ERROR = 1
+		
+	};
+	
+}
diff --git a/include/vkcv/Window.hpp b/include/vkcv/Window.hpp
index ef5e35cc10a9983440d3d33f7d8dd93a6aef5199..87c98a9281e6081c98487c7fd314d960b818190f 100644
--- a/include/vkcv/Window.hpp
+++ b/include/vkcv/Window.hpp
@@ -4,12 +4,14 @@
  * @file src/vkcv/Window.hpp
  * @brief Window class to handle a basic rendering surface and input
  */
-#include <GLFW/glfw3.h>
 
 #define NOMINMAX
 #include <algorithm>
 
+struct GLFWwindow;
+
 namespace vkcv {
+	
     class Window final {
     private:
         GLFWwindow *m_window;
@@ -88,4 +90,5 @@ namespace vkcv {
          */
         virtual ~Window();
     };
+    
 }
\ No newline at end of file
diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3309d860b300dd378460338d9fece48066c38993
--- /dev/null
+++ b/modules/CMakeLists.txt
@@ -0,0 +1,3 @@
+
+# Add new modules here:
+add_subdirectory(testing)
diff --git a/modules/testing/CMakeLists.txt b/modules/testing/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e869c7974fb0e91894d796e045c9104564173873
--- /dev/null
+++ b/modules/testing/CMakeLists.txt
@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 3.16)
+project(vkcv_testing)
+
+# setting c++ standard for the project
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+set(vkcv_testing_source ${PROJECT_SOURCE_DIR}/src)
+set(vkcv_testing_include ${PROJECT_SOURCE_DIR}/include)
+
+set(vkcv_testing_sources
+		${vkcv_testing_include}/vkcv/testing/Test.hpp
+		${vkcv_testing_source}/vkcv/testing/Test.cpp
+)
+
+# adding source files to the project
+add_library(vkcv_testing STATIC ${vkcv_testing_sources})
+
+# add the own include directory for public headers
+target_include_directories(vkcv_testing BEFORE PUBLIC ${vkcv_testing_include})
diff --git a/modules/testing/include/vkcv/testing/Test.hpp b/modules/testing/include/vkcv/testing/Test.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..7f020ce4f9541f5ccc87ba7f1c63828aaece2014
--- /dev/null
+++ b/modules/testing/include/vkcv/testing/Test.hpp
@@ -0,0 +1,12 @@
+#pragma once
+
+namespace vkcv::testing {
+	
+	class Test {
+	private:
+	public:
+		void test(int test_value);
+		
+	};
+	
+}
diff --git a/modules/testing/src/vkcv/testing/Test.cpp b/modules/testing/src/vkcv/testing/Test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..302fe986666f9dbda3d1955fc8c6720821b2d173
--- /dev/null
+++ b/modules/testing/src/vkcv/testing/Test.cpp
@@ -0,0 +1,10 @@
+
+#include "vkcv/testing/Test.hpp"
+
+namespace vkcv::testing {
+	
+	void Test::test(int test_value) {
+		// TODO: this is an example
+	}
+
+}
diff --git a/projects/first_triangle/.gitignore b/projects/first_triangle/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..7e24fd7b853bfb0a29d8b30879ef1cb95ad141c0
--- /dev/null
+++ b/projects/first_triangle/.gitignore
@@ -0,0 +1 @@
+first_triangle
\ No newline at end of file
diff --git a/projects/first_triangle/CMakeLists.txt b/projects/first_triangle/CMakeLists.txt
index b7a2b52fcde1ec4481bb450da233aa319709c829..78c40f998d6fe1f2df032748e497429f07722778 100644
--- a/projects/first_triangle/CMakeLists.txt
+++ b/projects/first_triangle/CMakeLists.txt
@@ -5,14 +5,20 @@ project(first_triangle)
 set(CMAKE_CXX_STANDARD 17)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
 
-file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/shaders/vert.spv DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/shaders)
-file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/shaders/frag.spv DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/shaders)
+# this should fix the execution path to load local files from the project
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
 
 # adding source files to the project
 add_executable(first_triangle src/main.cpp)
 
+# this should fix the execution path to load local files from the project (for MSVC)
+if(MSVC)
+	set_target_properties(first_triangle PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
+	set_target_properties(first_triangle PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
+endif()
+
 # including headers of dependencies and the VkCV framework
-target_include_directories(first_triangle SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes})
+target_include_directories(first_triangle SYSTEM BEFORE PRIVATE ${vkcv_include} ${vkcv_includes} ${vkcv_testing_include})
 
 # linking with libraries from all dependencies and the VkCV framework
-target_link_libraries(first_triangle vkcv ${vkcv_libraries})
+target_link_libraries(first_triangle vkcv ${vkcv_libraries} vkcv_testing)
diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp
index 7e6d87ca71e294d4f7df9b6373a002e704c68325..5e23fe2b564b10998945960ad840c56ddf97b690 100644
--- a/src/vkcv/Core.cpp
+++ b/src/vkcv/Core.cpp
@@ -4,6 +4,8 @@
  * @brief Handling of global states regarding dependencies
  */
 
+#include <GLFW/glfw3.h>
+
 #include "vkcv/Core.hpp"
 #include "PassManager.hpp"
 #include "PipelineManager.hpp"
@@ -317,19 +319,31 @@ namespace vkcv
         return m_PassManager->createPass(config);
     }
 
-	uint32_t Core::acquireSwapchainImage() {
-		uint32_t index;
-		m_Context.getDevice().acquireNextImageKHR(m_swapchain.getSwapchain(), 0, nullptr,
-			m_SyncResources.swapchainImageAcquired, &index, {});
-		const uint64_t timeoutPeriodNs = 1000;	// TODO: think if is adequate
-		const auto& result = m_Context.getDevice().waitForFences(m_SyncResources.swapchainImageAcquired, true, timeoutPeriodNs);
+	Result Core::acquireSwapchainImage() {
+    	uint32_t imageIndex;
+    	
+		const auto& acquireResult = m_Context.getDevice().acquireNextImageKHR(
+				m_swapchain.getSwapchain(), std::numeric_limits<uint64_t>::max(), nullptr,
+				m_SyncResources.swapchainImageAcquired, &imageIndex, {}
+		);
+		
+		if (acquireResult != vk::Result::eSuccess) {
+			return Result::ERROR;
+		}
+		
+		const auto& result = m_Context.getDevice().waitForFences(
+				m_SyncResources.swapchainImageAcquired, true,
+				std::numeric_limits<uint64_t>::max()
+		);
+		
 		m_Context.getDevice().resetFences(m_SyncResources.swapchainImageAcquired);
 		
-		if (result == vk::Result::eTimeout) {
-			index = std::numeric_limits<uint32_t>::max();
+		if (result != vk::Result::eSuccess) {
+			return Result::ERROR;
 		}
 		
-		return index;
+		m_currentSwapchainImageIndex = imageIndex;
+		return Result::SUCCESS;
 	}
 
 	void Core::destroyTemporaryFramebuffers() {
@@ -340,12 +354,9 @@ namespace vkcv
 	}
 
 	void Core::beginFrame() {
-		m_currentSwapchainImageIndex = acquireSwapchainImage();
-		
-		if (m_currentSwapchainImageIndex == std::numeric_limits<uint32_t>::max()) {
-			std::cerr << "Drop frame!" << std::endl;
- 			return;
-		}
+    	if (acquireSwapchainImage() != Result::SUCCESS) {
+    		return;
+    	}
 		
 		m_Context.getDevice().waitIdle();	// FIMXE: this is a sin against graphics programming, but its getting late - Alex
 		destroyTemporaryFramebuffers();
diff --git a/src/vkcv/QueueManager.cpp b/src/vkcv/QueueManager.cpp
index c6c9dda42e1fdfacdde8e7174307cbbcd38ff24d..6f46e61ad5b658ca38749565309ae06646b9090a 100644
--- a/src/vkcv/QueueManager.cpp
+++ b/src/vkcv/QueueManager.cpp
@@ -1,5 +1,8 @@
-#include "vkcv/QueueManager.hpp"
+
 #include <unordered_set>
+#include <limits>
+
+#include "vkcv/QueueManager.hpp"
 
 namespace vkcv {
 
diff --git a/src/vkcv/Window.cpp b/src/vkcv/Window.cpp
index ce05d67cb216215c625b468acdb85be2fc2a8b2e..376f363a95c1e873c435825ba97e155205851347 100644
--- a/src/vkcv/Window.cpp
+++ b/src/vkcv/Window.cpp
@@ -4,8 +4,9 @@
  * @brief Window class to handle a basic rendering surface and input
  */
 
-#include "vkcv/Window.hpp"
+#include <GLFW/glfw3.h>
 
+#include "vkcv/Window.hpp"
 
 namespace vkcv {