Merge pull request #2 in MM/mpin-sdk-core from feature/remove_v1 to master

* commit '5099bc253cccc98bd894e7a83eab9c7b09a21115':
  Remove v1 code
diff --git a/project/unit_tests_v2/Makefile b/project/unit_tests_v2/Makefile
deleted file mode 100644
index 483fe60..0000000
--- a/project/unit_tests_v2/Makefile
+++ /dev/null
@@ -1,112 +0,0 @@
-# Standard variables
-CC = gcc
-CXX = g++
-
-# Directories: SRC_DIR - root of all sources, BUILD_DIR - temporary build files, OUTPUT_DIR - final binaries dir
-SRC_DIR = ../..
-BUILD_DIR = build
-OUTPUT_DIR = dist
-# Output file
-EXECUTABLE = $(OUTPUT_DIR)/unit_tests_v2
-
-# Includes
-INCLUDE_DIRS = -I $(SRC_DIR)/src -I$(SRC_DIR)/ext/cvshared/cpp/include -I$(SRC_DIR)/ext/boost
-
-# Additional library search paths
-LIB_DIRS =
-
-# Additional libraries
-LDLIBS = -lcurl -lcrypto -lpthread
-
-# C and C++ flags
-CXXFLAGS = -g -MMD -MP $(INCLUDE_DIRS)
-CFLAGS = $(CXXFLAGS)
-
-# Linker flags
-LDFLAGS = $(LIB_DIRS)
-
-# Utility functions, used later in build
-# rfind
-define rfind
-$(shell find $(1) -name '$(2)')
-endef
-# add_src_dir
-define add_src_dir
-$(sort $(call rfind,$(SRC_DIR)/$(strip $(1)),*.c) $(call rfind,$(SRC_DIR)/$(strip $(1)),*.cpp))
-endef
-# filter_src
-define filter_src
-$(call $(1),$(3),$(call add_src_dir,$(2)))
-endef
-# add_src_dir_excluding
-define add_src_dir_excluding
-$(call filter_src,filter-out,$(1),$(2))
-endef
-# add_src_dir_including
-define add_src_dir_including
-$(call filter_src,filter,$(1),$(2))
-endef
-# c_to_obj
-define c_to_obj
-$(patsubst $(SRC_DIR)/%.c, $(BUILD_DIR)/%.o, $(1))
-endef
-# cpp_to_obj
-define cpp_to_obj
-$(patsubst $(SRC_DIR)/%.cpp, $(BUILD_DIR)/%.o, $(1))
-endef
-# generate_c_rule
-define generate_c_rule
-$(2): $(1)
-	$$(shell mkdir -p $(dir $(2)))
-	$$(CC) $$(CPPFLAGS) $$(CFLAGS) -c $$< -o $$@
-endef
-# generate_cpp_rule
-define generate_cpp_rule
-$(2): $(1)
-	$$(shell mkdir -p $(dir $(2)))
-	$$(CXX) $$(CPPFLAGS) $$(CXXFLAGS) -c $$< -o $$@
-endef
-
-# Source files - modify this part if you want to add new source files (*.c *.cpp).
-# To recursively add all files in a directory, use:
-# $(call add_src_dir, <a directory>)
-# To recursively add all files in a directory, except some files, use:
-# $(call add_src_dir_excluding, <a directory>, <exclude pattern>)
-# To recursively add only some files in a directory, use:
-# $(call add_src_dir_including, <a directory>, <include pattern>)
-# All directories are specified relatively to $(SRC_DIR).
-# The patterns must contain the % character to match a portion of the full file pathname.
-SRC = $(call add_src_dir, src)
-SRC += $(call add_src_dir_including, ext/cvshared/cpp, \
-		%linux/CvHttpRequest.cpp %linux/CvThread.cpp %linux/CvLogger.cpp %linux/CvMutex.cpp %CvString.cpp %CvTime.cpp %CvXcode.cpp)
-SRC += $(call add_src_dir_including, tests, \
-        %auto_context_v2.cpp %access_number_thread.cpp %memory_storage.cpp %http_request.cpp %unit_tests_v2.cpp)
-
-# Generate a list of object files
-OBJ = $(call cpp_to_obj, $(call c_to_obj, $(SRC)))
-
-# Separate .c and .cpp files
-C_SRC = $(filter %.c, $(SRC))
-CPP_SRC = $(filter %.cpp, $(SRC))
-
-# The default target
-all: $(EXECUTABLE)
-
-# Rule for building the executable - depends on all object files
-$(EXECUTABLE): $(OBJ)
-	$(shell mkdir -p $(dir $(EXECUTABLE)))
-	$(CXX) -o $@ $(OBJ) $(LDFLAGS) $(LDLIBS)
-
-# Generate rules for each object file that depends on the corresponding .c file
-$(foreach cfile, $(C_SRC), $(eval $(call generate_c_rule, $(cfile), $(call c_to_obj, $(cfile)))))
-
-# Generate rules for each object file that depends on the corresponding .cpp file
-$(foreach cppfile, $(CPP_SRC), $(eval $(call generate_cpp_rule, $(cppfile), $(call cpp_to_obj, $(cppfile)))))
-
-# Clean target
-clean:
-	rm -f -R build/** $(EXECUTABLE)
-
-# Include all the .d files (generated by the -MMD -MP option) corresponding to each of the object files
-# This adds to each object target a dependency on all the header files, included in the corresponding c/cpp file
--include $(OBJ:%.o=%.d)
diff --git a/project/visual_studio_2012/mpin_sdk.sln b/project/visual_studio_2012/mpin_sdk.sln
index be75d5e..b4a1c59 100644
--- a/project/visual_studio_2012/mpin_sdk.sln
+++ b/project/visual_studio_2012/mpin_sdk.sln
@@ -10,13 +10,6 @@
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mpin_sdk_test", "mpin_sdk_test.vcxproj", "{39536C4B-3293-4AD4-951F-0C4D5BCE7219}"
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mpin_sdk_v2_test", "mpin_sdk_v2_test.vcxproj", "{CCBAA571-C783-41A4-B0B8-0A0281D61482}"
-	ProjectSection(ProjectDependencies) = postProject
-		{C47BB154-F9DF-4C88-81C0-A27510A16840} = {C47BB154-F9DF-4C88-81C0-A27510A16840}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unit_tests_v2", "unit_tests_v2.vcxproj", "{49FCDC79-74F4-4FC9-ACE7-D8605F5DD50B}"
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mpin_sdk_test_common", "mpin_sdk_test_common.vcxproj", "{AB7741C8-A26B-4D8D-A0BC-806B5AC86CD9}"
 EndProject
 Global
@@ -37,14 +30,6 @@
 		{39536C4B-3293-4AD4-951F-0C4D5BCE7219}.Debug|Win32.Build.0 = Debug|Win32
 		{39536C4B-3293-4AD4-951F-0C4D5BCE7219}.Release|Win32.ActiveCfg = Release|Win32
 		{39536C4B-3293-4AD4-951F-0C4D5BCE7219}.Release|Win32.Build.0 = Release|Win32
-		{CCBAA571-C783-41A4-B0B8-0A0281D61482}.Debug|Win32.ActiveCfg = Debug|Win32
-		{CCBAA571-C783-41A4-B0B8-0A0281D61482}.Debug|Win32.Build.0 = Debug|Win32
-		{CCBAA571-C783-41A4-B0B8-0A0281D61482}.Release|Win32.ActiveCfg = Release|Win32
-		{CCBAA571-C783-41A4-B0B8-0A0281D61482}.Release|Win32.Build.0 = Release|Win32
-		{49FCDC79-74F4-4FC9-ACE7-D8605F5DD50B}.Debug|Win32.ActiveCfg = Debug|Win32
-		{49FCDC79-74F4-4FC9-ACE7-D8605F5DD50B}.Debug|Win32.Build.0 = Debug|Win32
-		{49FCDC79-74F4-4FC9-ACE7-D8605F5DD50B}.Release|Win32.ActiveCfg = Release|Win32
-		{49FCDC79-74F4-4FC9-ACE7-D8605F5DD50B}.Release|Win32.Build.0 = Release|Win32
 		{AB7741C8-A26B-4D8D-A0BC-806B5AC86CD9}.Debug|Win32.ActiveCfg = Debug|Win32
 		{AB7741C8-A26B-4D8D-A0BC-806B5AC86CD9}.Debug|Win32.Build.0 = Debug|Win32
 		{AB7741C8-A26B-4D8D-A0BC-806B5AC86CD9}.Release|Win32.ActiveCfg = Release|Win32
diff --git a/project/visual_studio_2012/mpin_sdk.vcxproj b/project/visual_studio_2012/mpin_sdk.vcxproj
index 2065ea2..ddf71eb 100644
--- a/project/visual_studio_2012/mpin_sdk.vcxproj
+++ b/project/visual_studio_2012/mpin_sdk.vcxproj
@@ -101,7 +101,6 @@
     <ClCompile Include="..\..\src\crypto\version.c" />
     <ClCompile Include="..\..\src\mpin_crypto_non_tee.cpp" />
     <ClCompile Include="..\..\src\mpin_sdk.cpp" />
-    <ClCompile Include="..\..\src\mpin_sdk_v2.cpp" />
     <ClCompile Include="..\..\src\utils.cpp" />
   </ItemGroup>
   <ItemGroup>
@@ -127,7 +126,6 @@
     <ClInclude Include="..\..\src\mpin_crypto.h" />
     <ClInclude Include="..\..\src\mpin_crypto_non_tee.h" />
     <ClInclude Include="..\..\src\mpin_sdk.h" />
-    <ClInclude Include="..\..\src\mpin_sdk_v2.h" />
     <ClInclude Include="..\..\src\utf8.h" />
     <ClInclude Include="..\..\src\utf8\checked.h" />
     <ClInclude Include="..\..\src\utf8\core.h" />
diff --git a/project/visual_studio_2012/mpin_sdk.vcxproj.filters b/project/visual_studio_2012/mpin_sdk.vcxproj.filters
index 4b73672..ee68199 100644
--- a/project/visual_studio_2012/mpin_sdk.vcxproj.filters
+++ b/project/visual_studio_2012/mpin_sdk.vcxproj.filters
@@ -102,9 +102,6 @@
     <ClCompile Include="..\..\src\utils.cpp">
       <Filter>src</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\mpin_sdk_v2.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\src\mpin_crypto.h">
@@ -191,9 +188,6 @@
     <ClInclude Include="..\..\src\utils.h">
       <Filter>src</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\mpin_sdk_v2.h">
-      <Filter>src</Filter>
-    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\..\src\json\elements.inl">
diff --git a/project/visual_studio_2012/mpin_sdk_v2_test.vcxproj b/project/visual_studio_2012/mpin_sdk_v2_test.vcxproj
deleted file mode 100644
index 5041b2d..0000000
--- a/project/visual_studio_2012/mpin_sdk_v2_test.vcxproj
+++ /dev/null
@@ -1,93 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{CCBAA571-C783-41A4-B0B8-0A0281D61482}</ProjectGuid>
-    <RootNamespace>mpin_sdk_v2_test</RootNamespace>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v110</PlatformToolset>
-    <CharacterSet>MultiByte</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v110</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>MultiByte</CharacterSet>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <OutDir>$(SolutionDir)bin\$(ProjectName)\$(Configuration)\</OutDir>
-    <IntDir>bin\$(ProjectName)\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <OutDir>$(SolutionDir)bin\$(ProjectName)\$(Configuration)\</OutDir>
-    <IntDir>bin\$(ProjectName)\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>../../src; ../../ext/cvshared/cpp/include</AdditionalIncludeDirectories>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;WinHttp.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <AdditionalIncludeDirectories>../../src; ../../ext/cvshared/cpp/include</AdditionalIncludeDirectories>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;WinHttp.lib;%(AdditionalDependencies)</AdditionalDependencies>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\tests\cmdline_v2_test.cpp" />
-    <ClCompile Include="..\..\tests\contexts\cmdline_context_v2.cpp" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\tests\contexts\cmdline_context_v2.h" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="mpin_sdk.vcxproj">
-      <Project>{c47bb154-f9df-4c88-81c0-a27510a16840}</Project>
-    </ProjectReference>
-    <ProjectReference Include="mpin_sdk_test_common.vcxproj">
-      <Project>{ab7741c8-a26b-4d8d-a0bc-806b5ac86cd9}</Project>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
-</Project>
\ No newline at end of file
diff --git a/project/visual_studio_2012/mpin_sdk_v2_test.vcxproj.filters b/project/visual_studio_2012/mpin_sdk_v2_test.vcxproj.filters
deleted file mode 100644
index e0a2d8a..0000000
--- a/project/visual_studio_2012/mpin_sdk_v2_test.vcxproj.filters
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="src">
-      <UniqueIdentifier>{f0800569-8d73-468a-a179-94750573d847}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\contexts">
-      <UniqueIdentifier>{058c4121-8c2c-4a5b-bc26-4d48818fb42f}</UniqueIdentifier>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\tests\cmdline_v2_test.cpp">
-      <Filter>src</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\tests\contexts\cmdline_context_v2.cpp">
-      <Filter>src\contexts</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\tests\contexts\cmdline_context_v2.h">
-      <Filter>src\contexts</Filter>
-    </ClInclude>
-  </ItemGroup>
-</Project>
\ No newline at end of file
diff --git a/project/visual_studio_2012/unit_tests_v2.vcxproj b/project/visual_studio_2012/unit_tests_v2.vcxproj
deleted file mode 100644
index f0689ea..0000000
--- a/project/visual_studio_2012/unit_tests_v2.vcxproj
+++ /dev/null
@@ -1,95 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup Label="ProjectConfigurations">
-    <ProjectConfiguration Include="Debug|Win32">
-      <Configuration>Debug</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-    <ProjectConfiguration Include="Release|Win32">
-      <Configuration>Release</Configuration>
-      <Platform>Win32</Platform>
-    </ProjectConfiguration>
-  </ItemGroup>
-  <PropertyGroup Label="Globals">
-    <ProjectGuid>{49FCDC79-74F4-4FC9-ACE7-D8605F5DD50B}</ProjectGuid>
-    <RootNamespace>unit_tests_v2</RootNamespace>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>true</UseDebugLibraries>
-    <PlatformToolset>v110</PlatformToolset>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-    <ConfigurationType>Application</ConfigurationType>
-    <UseDebugLibraries>false</UseDebugLibraries>
-    <PlatformToolset>v110</PlatformToolset>
-    <WholeProgramOptimization>true</WholeProgramOptimization>
-    <CharacterSet>Unicode</CharacterSet>
-  </PropertyGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
-  <ImportGroup Label="ExtensionSettings">
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-  </ImportGroup>
-  <PropertyGroup Label="UserMacros" />
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <OutDir>$(SolutionDir)bin\$(ProjectName)\$(Configuration)\</OutDir>
-    <IntDir>bin\$(ProjectName)\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <OutDir>$(SolutionDir)bin\$(ProjectName)\$(Configuration)\</OutDir>
-    <IntDir>bin\$(ProjectName)\$(Configuration)\</IntDir>
-  </PropertyGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>Disabled</Optimization>
-      <AdditionalIncludeDirectories>../../ext/boost; ../../src; ../../ext/cvshared/cpp/include</AdditionalIncludeDirectories>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;WinHttp.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <SubSystem>Console</SubSystem>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
-    <ClCompile>
-      <WarningLevel>Level3</WarningLevel>
-      <Optimization>MaxSpeed</Optimization>
-      <FunctionLevelLinking>true</FunctionLevelLinking>
-      <IntrinsicFunctions>true</IntrinsicFunctions>
-      <AdditionalIncludeDirectories>../../ext/boost; ../../src; ../../ext/cvshared/cpp/include</AdditionalIncludeDirectories>
-    </ClCompile>
-    <Link>
-      <GenerateDebugInformation>true</GenerateDebugInformation>
-      <EnableCOMDATFolding>true</EnableCOMDATFolding>
-      <OptimizeReferences>true</OptimizeReferences>
-      <AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;WinHttp.lib;%(AdditionalDependencies)</AdditionalDependencies>
-      <SubSystem>NotSet</SubSystem>
-    </Link>
-  </ItemDefinitionGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\tests\contexts\auto_context_v2.cpp" />
-    <ClCompile Include="..\..\tests\unit_tests_v2.cpp" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\tests\contexts\auto_context_v2.h" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="mpin_sdk.vcxproj">
-      <Project>{c47bb154-f9df-4c88-81c0-a27510a16840}</Project>
-    </ProjectReference>
-    <ProjectReference Include="mpin_sdk_test_common.vcxproj">
-      <Project>{ab7741c8-a26b-4d8d-a0bc-806b5ac86cd9}</Project>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
-  <ImportGroup Label="ExtensionTargets">
-  </ImportGroup>
-</Project>
\ No newline at end of file
diff --git a/project/visual_studio_2012/unit_tests_v2.vcxproj.filters b/project/visual_studio_2012/unit_tests_v2.vcxproj.filters
deleted file mode 100644
index ff4d0c2..0000000
--- a/project/visual_studio_2012/unit_tests_v2.vcxproj.filters
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <Filter Include="src">
-      <UniqueIdentifier>{b08028e5-325e-4d98-9ed6-62a072998eb9}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\contexts">
-      <UniqueIdentifier>{6913b55c-3bd8-43d9-bdcd-7baf662a91e0}</UniqueIdentifier>
-    </Filter>
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="..\..\tests\unit_tests_v2.cpp" />
-    <ClCompile Include="..\..\tests\contexts\auto_context_v2.cpp">
-      <Filter>src\contexts</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="..\..\tests\contexts\auto_context_v2.h">
-      <Filter>src\contexts</Filter>
-    </ClInclude>
-  </ItemGroup>
-</Project>
\ No newline at end of file
diff --git a/src/mpin_crypto.h b/src/mpin_crypto.h
index 391e2da..dc1db84 100644
--- a/src/mpin_crypto.h
+++ b/src/mpin_crypto.h
@@ -41,8 +41,8 @@
 
     virtual Status OpenSession() = 0;
     virtual void CloseSession() = 0;
-    virtual Status Register(IN UserPtr user, IN std::vector<String>& clientSecretShares) = 0;
-    virtual Status AuthenticatePass1(IN UserPtr user, IN std::vector<String>& timePermitShares, OUT String& commitmentU, OUT String& commitmentUT) = 0;
+    virtual Status Register(IN UserPtr user, const String& pin, IN std::vector<String>& clientSecretShares) = 0;
+    virtual Status AuthenticatePass1(IN UserPtr user, const String& pin, IN std::vector<String>& timePermitShares, OUT String& commitmentU, OUT String& commitmentUT) = 0;
     virtual Status AuthenticatePass2(IN UserPtr user, const String& challenge, OUT String& validator) = 0;
     virtual void DeleteToken(const String& mpinId) = 0;
     
diff --git a/src/mpin_crypto_non_tee.cpp b/src/mpin_crypto_non_tee.cpp
index ab762f8..3983762 100644
--- a/src/mpin_crypto_non_tee.cpp
+++ b/src/mpin_crypto_non_tee.cpp
@@ -71,7 +71,7 @@
 }
 
 
-MPinCryptoNonTee::MPinCryptoNonTee() : m_pinPad(NULL), m_storage(NULL), m_initialized(false), m_sessionOpened(false)
+MPinCryptoNonTee::MPinCryptoNonTee() : m_storage(NULL), m_initialized(false), m_sessionOpened(false)
 {
 }
 
@@ -80,14 +80,13 @@
     Destroy();
 }
 
-Status MPinCryptoNonTee::Init(IPinPad *pinpad, IStorage *storage)
+Status MPinCryptoNonTee::Init(IStorage *storage)
 {
     if(m_initialized)
     {
         return Status(Status::OK);
     }
 
-    m_pinPad = pinpad;
     m_storage = storage;
 
     String tokensJson;
@@ -146,7 +145,7 @@
     }
 }
 
-Status MPinCryptoNonTee::Register(UserPtr user, std::vector<String>& clientSecretShares)
+Status MPinCryptoNonTee::Register(UserPtr user, const String& pin, std::vector<String>& clientSecretShares)
 {
     const String& mpinId = user->GetMPinId();
     
@@ -171,8 +170,6 @@
         return Status(Status::CRYPTO_ERROR, String().Format("MPIN_RECOMBINE_G1() failed with code %d", res));
     }
 
-    // Query the user for the pin
-    String pin = m_pinPad->Show(user, IPinPad::REGISTER);
     if(pin.empty())
     {
         return Status(Status::PIN_INPUT_CANCELED, "Pin input canceled");
@@ -195,7 +192,7 @@
     return Status(Status::OK);
 }
 
-Status MPinCryptoNonTee::AuthenticatePass1(UserPtr user, std::vector<String>& timePermitShares, String& commitmentU, String& commitmentUT)
+Status MPinCryptoNonTee::AuthenticatePass1(UserPtr user, const String& pin, std::vector<String>& timePermitShares, String& commitmentU, String& commitmentUT)
 {
     const String& mpinId = user->GetMPinId();
 
@@ -227,8 +224,6 @@
         return Status(Status::CRYPTO_ERROR, String().Format("Failed to find stored token for mpinId='%s'", mpinId.c_str()));
     }
 
-    // Query the user for the pin
-    String pin = m_pinPad->Show(user, IPinPad::AUTHENTICATE);
     if(pin.empty())
     {
         return Status(Status::PIN_INPUT_CANCELED, "Pin input canceled");
diff --git a/src/mpin_crypto_non_tee.h b/src/mpin_crypto_non_tee.h
index cf2fd88..402e92f 100644
--- a/src/mpin_crypto_non_tee.h
+++ b/src/mpin_crypto_non_tee.h
@@ -33,7 +33,6 @@
 class MPinCryptoNonTee : public IMPinCrypto
 {
 public:
-    typedef MPinSDK::IPinPad IPinPad;
     typedef MPinSDK::IStorage IStorage;
     typedef util::JsonObject JsonObject;
     typedef MPinSDK::UserPtr UserPtr;
@@ -41,13 +40,13 @@
     MPinCryptoNonTee();
     ~MPinCryptoNonTee();
 
-    Status Init(IN IPinPad *pinpad, IN IStorage *storage);
+    Status Init(IN IStorage *storage);
     void Destroy();
 
     virtual Status OpenSession();
     virtual void CloseSession();
-    virtual Status Register(IN UserPtr user, IN std::vector<String>& clientSecretShares);
-    virtual Status AuthenticatePass1(IN UserPtr user, IN std::vector<String>& timePermitShares, OUT String& commitmentU, OUT String& commitmentUT);
+    virtual Status Register(IN UserPtr user, const String& pin, IN std::vector<String>& clientSecretShares);
+    virtual Status AuthenticatePass1(IN UserPtr user, const String& pin, IN std::vector<String>& timePermitShares, OUT String& commitmentU, OUT String& commitmentUT);
     virtual Status AuthenticatePass2(IN UserPtr user, const String& challenge, OUT String& validator);
     virtual void DeleteToken(const String& mpinId);
 
@@ -63,7 +62,6 @@
     static void GenerateRandomSeed(OUT char *buf, size_t len);
 
 private:
-    IPinPad *m_pinPad;
     IStorage *m_storage;
     bool m_initialized;
     bool m_sessionOpened;
diff --git a/src/mpin_sdk.cpp b/src/mpin_sdk.cpp
index 16794d5..9f42e9b 100644
--- a/src/mpin_sdk.cpp
+++ b/src/mpin_sdk.cpp
@@ -623,7 +623,7 @@
     if(ctx->GetMPinCryptoType() == CRYPTO_NON_TEE)
     {
         MPinCryptoNonTee *nonteeCrypto = new MPinCryptoNonTee();
-        Status s = nonteeCrypto->Init(ctx->GetPinPad(), ctx->GetStorage(IStorage::SECURE));
+        Status s = nonteeCrypto->Init(ctx->GetStorage(IStorage::SECURE));
         if(s != Status::OK)
         {
             delete nonteeCrypto;
@@ -893,7 +893,7 @@
     return s;
 }
 
-Status MPinSDK::FinishRegistration(UserPtr user, const String & pushMessageIdentifier)
+Status MPinSDK::ConfirmRegistration(INOUT UserPtr user, const String& pushMessageIdentifier)
 {
     Status s = CheckIfBackendIsSet();
     if(s != Status::OK)
@@ -921,17 +921,18 @@
     String regOTT = user->GetRegOTT();
 
     String url = String().Format("%s/%s?regOTT=%s", m_clientSettings.GetStringParam("signatureURL"), mpinIdHex.c_str(), regOTT.c_str());
-    if(pushMessageIdentifier != "") {
-        url = url + "&pmiToken=" + pushMessageIdentifier;
+    if(!pushMessageIdentifier.empty())
+    {
+        url += "&pmiToken=" + pushMessageIdentifier;
     }
-    
+
     HttpResponse response = MakeGetRequest(url);
     if(response.GetStatus() != HttpResponse::HTTP_OK)
     {
         return response.TranslateToMPinStatus(HttpResponse::GET_CLIENT_SECRET1);
     }
 
-    String cs1 = util::HexDecode(response.GetJsonData().GetStringParam("clientSecretShare"));
+    user->m_clientSecret1 = util::HexDecode(response.GetJsonData().GetStringParam("clientSecretShare"));
 
     // Request the client secret share from CertiVox's D-TA.
     String cs2Params = response.GetJsonData().GetStringParam("params");
@@ -942,7 +943,38 @@
         return response.TranslateToMPinStatus(HttpResponse::GET_CLIENT_SECRET2);
     }
 
-    String cs2 = util::HexDecode(response.GetJsonData().GetStringParam("clientSecret"));
+    user->m_clientSecret2 = util::HexDecode(response.GetJsonData().GetStringParam("clientSecret"));
+
+    return Status::OK;
+}
+
+Status MPinSDK::FinishRegistration(INOUT UserPtr user, const String& pin)
+{
+    Status s = CheckIfBackendIsSet();
+    if(s != Status::OK)
+    {
+        return s;
+    }
+
+	// A user can get here either in STARTED_REGISTRATION state or in ACTIVATED state (force-activate flow)
+	// In the first case, the method might fail if the user identity has not been verified yet, and the user state
+	// should stay as it was - STARTED_REGISTRATION
+    s = CheckUserState(user, User::STARTED_REGISTRATION);
+    if(s != Status::OK)
+    {
+		Status sSave = s;
+		s = CheckUserState(user, User::ACTIVATED);
+		if ( s != Status::OK )
+		{
+			return sSave;
+		}
+    }
+
+    // In addition, client secret shares must be retrieved
+    if(user->m_clientSecret1.empty() || user->m_clientSecret2.empty())
+    {
+        return Status(Status::FLOW_ERROR, String().Format("Cannot finish user '%s' registration: User identity not verified", user->GetId().c_str()));
+    }
 
     s = m_crypto->OpenSession();
     if(s != Status::OK)
@@ -951,10 +983,10 @@
     }
 
     std::vector<String> clientSecretShares;
-    clientSecretShares.push_back(cs1);
-    clientSecretShares.push_back(cs2);
+    clientSecretShares.push_back(user->m_clientSecret1);
+    clientSecretShares.push_back(user->m_clientSecret2);
 
-    s = m_crypto->Register(user, clientSecretShares);
+    s = m_crypto->Register(user, pin, clientSecretShares);
     if(s != Status::OK)
     {
         m_crypto->CloseSession();
@@ -970,52 +1002,10 @@
         return s;
     }
 
-    return Status(Status::OK);
+    return Status::OK;
 }
 
-Status MPinSDK::Authenticate(UserPtr user)
-{
-    util::JsonObject authResult;
-    return AuthenticateImpl(user, "", NULL, authResult);
-}
-
-Status MPinSDK::Authenticate(UserPtr user, OUT String& authResultData)
-{
-    util::JsonObject authResult;
-
-    Status s = AuthenticateImpl(user, "", NULL, authResult);
-
-    authResultData = authResult.ToString();
-    return s;
-}
-
-Status MPinSDK::AuthenticateOTP(UserPtr user, OUT OTP& otp)
-{
-    util::JsonObject authResult;
-    String otpNumber;
-
-    Status s = AuthenticateImpl(user, "", &otpNumber, authResult);
-
-    otp.ExtractFrom(otpNumber, authResult);
-    return s;
-}
-
-Status MPinSDK::AuthenticateAN(INOUT UserPtr user, const String& accessNumber)
-{
-    util::JsonObject authResult;
-
-    Status s = AuthenticateImpl(user, accessNumber, NULL, authResult);
-
-    LogoutData logoutData;
-    if(logoutData.ExtractFrom(authResult))
-    {
-        m_logoutData.insert(std::make_pair(user, logoutData));
-    }
-
-    return s;
-}
-
-Status MPinSDK::AuthenticateImpl(INOUT UserPtr user, const String& accessNumber, OUT String *otp, OUT util::JsonObject& authResultData)
+Status MPinSDK::StartAuthentication(INOUT UserPtr user)
 {
     Status s = CheckIfBackendIsSet();
     if(s != Status::OK)
@@ -1031,9 +1021,7 @@
     }
 
     // Request a time permit share from the customer's D-TA and a signed request for a time permit share from CertiVox's D-TA.
-    String mpinId = user->GetMPinId();
     String mpinIdHex = user->GetMPinIdHex();
-
     String url = String().Format("%s/%s", m_clientSettings.GetStringParam("timePermitsURL"), mpinIdHex.c_str());
     HttpResponse response = MakeGetRequest(url);
     if(response.GetStatus() != HttpResponse::HTTP_OK)
@@ -1041,22 +1029,93 @@
         return response.TranslateToMPinStatus(HttpResponse::GET_TIME_PERMIT1);
     }
 
-    String tp1 = util::HexDecode(response.GetJsonData().GetStringParam("timePermit"));
+    user->m_timePermitShare1 = util::HexDecode(response.GetJsonData().GetStringParam("timePermit"));
 
     // Request time permit share from CertiVox's D-TA (Searches first in user cache, than in S3 cache)
-    String tp2;
-    s = GetCertivoxTimePermitShare(user, response.GetJsonData(), tp2);
+    s = GetCertivoxTimePermitShare(user, response.GetJsonData(), user->m_timePermitShare2);
     if(s != Status::OK)
     {
         return s;
     }
 
-    // Check accessNumber
-    if(!accessNumber.empty() && !CheckAccessNumber(accessNumber))
+    return Status::OK;
+}
+
+Status MPinSDK::CheckAccessNumber(const String& accessNumber)
+{
+    if(accessNumber.empty() || !ValidateAccessNumber(accessNumber))
     {
         return Status(Status::INCORRECT_ACCESS_NUMBER, "Invalid access number");
     }
 
+    return Status::OK;
+}
+
+Status MPinSDK::FinishAuthentication(INOUT UserPtr user, const String& pin)
+{
+    util::JsonObject authResult;
+    return FinishAuthenticationImpl(user, pin, "", NULL, authResult);
+}
+
+Status MPinSDK::FinishAuthentication(INOUT UserPtr user, const String& pin, OUT String& authResultData)
+{
+    util::JsonObject authResult;
+
+    Status s = FinishAuthenticationImpl(user, pin, "", NULL, authResult);
+
+    authResultData = authResult.ToString();
+    return s;
+}
+
+Status MPinSDK::FinishAuthenticationOTP(INOUT UserPtr user, const String& pin, OUT OTP& otp)
+{
+    util::JsonObject authResult;
+    String otpNumber;
+
+    Status s = FinishAuthenticationImpl(user, pin, "", &otpNumber, authResult);
+
+    otp.ExtractFrom(otpNumber, authResult);
+    return s;
+}
+
+Status MPinSDK::FinishAuthenticationAN(INOUT UserPtr user, const String& pin, const String& accessNumber)
+{
+    util::JsonObject authResult;
+
+    Status s = FinishAuthenticationImpl(user, pin, accessNumber, NULL, authResult);
+
+    LogoutData logoutData;
+    if(logoutData.ExtractFrom(authResult))
+    {
+        m_logoutData.insert(std::make_pair(user, logoutData));
+    }
+
+    return s;
+}
+
+Status MPinSDK::FinishAuthenticationImpl(INOUT UserPtr user, const String& pin, const String& accessNumber, OUT String *otp, OUT util::JsonObject& authResultData)
+{
+    Status s = CheckIfBackendIsSet();
+    if(s != Status::OK)
+    {
+        return s;
+    }
+
+    // Check if the user is already registered
+    s = CheckUserState(user, User::REGISTERED);
+    if(s != Status::OK)
+    {
+        return s;
+    }
+
+    // Check if time permit was obtained from StartAuthentication
+    if(user->m_timePermitShare1.empty() || user->m_timePermitShare2.empty())
+    {
+        return Status(Status::FLOW_ERROR, String().Format("Cannot finish user '%s' authentication: Invalid time permit", user->GetId().c_str()));
+    }
+
+    String mpinIdHex = user->GetMPinIdHex();
+
     s = m_crypto->OpenSession();
     if(s != Status::OK)
     {
@@ -1064,12 +1123,12 @@
     }
 
     std::vector<String> timePermitShares;
-    timePermitShares.push_back(tp1);
-    timePermitShares.push_back(tp2);
+    timePermitShares.push_back(user->m_timePermitShare1);
+    timePermitShares.push_back(user->m_timePermitShare2);
 
     // Authentication pass 1
     String u, ut;
-    s = m_crypto->AuthenticatePass1(user, timePermitShares, u, ut);
+    s = m_crypto->AuthenticatePass1(user, pin, timePermitShares, u, ut);
     if(s != Status::OK)
     {
         m_crypto->CloseSession();
@@ -1083,8 +1142,8 @@
     requestData["U"] = json::String(util::HexEncode(u));
 
     String mpinAuthServerURL = m_clientSettings.GetStringParam("mpinAuthServerURL");
-    url.Format("%s/pass1", mpinAuthServerURL.c_str());
-    response = MakeRequest(url, IHttpRequest::POST, requestData);
+    String url = String().Format("%s/pass1", mpinAuthServerURL.c_str());
+    HttpResponse response = MakeRequest(url, IHttpRequest::POST, requestData);
     if(response.GetStatus() != HttpResponse::HTTP_OK)
     {
         m_crypto->CloseSession();
@@ -1148,7 +1207,7 @@
 
     authResultData = response.GetJsonData();
 
-    return Status(Status::OK);
+    return Status::OK;
 }
 
 Status MPinSDK::GetCertivoxTimePermitShare(INOUT UserPtr user, const util::JsonObject& cutomerTimePermitData, OUT String& resultTimePermit)
@@ -1244,7 +1303,7 @@
     return true;
 }
 
-bool MPinSDK::CheckAccessNumber(const String& accessNumber)
+bool MPinSDK::ValidateAccessNumber(const String& accessNumber)
 {
     bool accessNumberUseCheckSum = m_clientSettings.GetBoolParam("accessNumberUseCheckSum", true);
     int accessNumberDigits = m_clientSettings.GetIntParam("accessNumberDigits", AN_WITH_CHECKSUM_LEN);
@@ -1510,7 +1569,7 @@
 
 const char * MPinSDK::GetVersion()
 {
-    return MPIN_SDK_VERSION;
+    return MPIN_SDK_V2_VERSION;
 }
 
 bool MPinSDK::CanLogout(UserPtr user)
@@ -1546,32 +1605,39 @@
 class StringVisitor:public json::Visitor
 {
 public:
-   virtual ~StringVisitor() {}
+    virtual ~StringVisitor() {}
 
-   virtual void Visit(json::Array& array) {}
-   virtual void Visit(json::Object& object) {}
-   virtual void Visit(json::Null& null){}
-   virtual void Visit(json::Number& number){
-	   data << (int) number.Value();
-   }
-   virtual void Visit(json::String& string){
-	   data << string.Value();
-   }
-   virtual void Visit(json::Boolean& boolean) {
-       data << (boolean.Value() ? "true" : "false");
-   }
+    virtual void Visit(json::Array& array) {}
+    virtual void Visit(json::Object& object) {}
+    virtual void Visit(json::Null& null){}
+
+    virtual void Visit(json::Number& number)
+    {
+        data << (int) number.Value();
+    }
+
+    virtual void Visit(json::String& string)
+    {
+	    data << string.Value();
+    }
+
+    virtual void Visit(json::Boolean& boolean)
+    {
+        data << (boolean.Value() ? "true" : "false");
+    }
    
+    String GetData()
+    {
+	    return data.str();
+    }	   
    
-   String getData() {
-		return data.str();
-   }	   
-   
-   private:
-	std::stringstream data;
+private:
+    std::stringstream data;
 };
 
-String MPinSDK::GetClientParam(const String& key) {
+String MPinSDK::GetClientParam(const String& key)
+{
 	StringVisitor sv;
 	m_clientSettings[key].Accept(sv);
-	return sv.getData();
+	return sv.GetData();
 }
diff --git a/src/mpin_sdk.h b/src/mpin_sdk.h
index bca46d2..d7cf2e7 100644
--- a/src/mpin_sdk.h
+++ b/src/mpin_sdk.h
@@ -97,19 +97,6 @@
         virtual const String& GetErrorMessage() const = 0;
     };
 
-    class IPinPad
-    {
-    public:
-        enum Mode
-        {
-            REGISTER,
-            AUTHENTICATE,
-        };
-
-        virtual ~IPinPad() {}
-        virtual String Show(UserPtr user, Mode mode) = 0;
-    };
-
     class IContext
     {
     public:
@@ -117,7 +104,6 @@
         virtual IHttpRequest * CreateHttpRequest() const = 0;
         virtual void ReleaseHttpRequest(IN IHttpRequest *request) const = 0;
         virtual IStorage * GetStorage(IStorage::Type type) const = 0;
-        virtual IPinPad * GetPinPad() const = 0;
         virtual CryptoType GetMPinCryptoType() const = 0;
     };
 
@@ -242,17 +228,23 @@
     void Destroy();
     void ClearUsers();
 
-    Status TestBackend(const String& server, const String& rpsPrefix = DEFAULT_RPS_PREFIX) const;
-    Status SetBackend(const String& server, const String& rpsPrefix = DEFAULT_RPS_PREFIX);
+    Status TestBackend(const String& server, const String& rpsPrefix = MPinSDK::DEFAULT_RPS_PREFIX) const;
+    Status SetBackend(const String& server, const String& rpsPrefix = MPinSDK::DEFAULT_RPS_PREFIX);
     UserPtr MakeNewUser(const String& id, const String& deviceName = "") const;
+
     Status StartRegistration(INOUT UserPtr user, const String& userData = "");
     Status RestartRegistration(INOUT UserPtr user, const String& userData = "");
-    Status VerifyUser(UserPtr user, const String& mpinId, const String &  activationKey);
-    Status FinishRegistration(INOUT UserPtr user, const String & pushMessageIdentifier = "");
-    Status Authenticate(INOUT UserPtr user);
-    Status Authenticate(INOUT UserPtr user, OUT String& authResultData);
-    Status AuthenticateOTP(INOUT UserPtr user, OUT OTP& otp);
-    Status AuthenticateAN(INOUT UserPtr user, const String& accessNumber);
+    Status VerifyUser(INOUT UserPtr user, const String& mpinId, const String& activationKey);
+    Status ConfirmRegistration(INOUT UserPtr user, const String& pushMessageIdentifier = "");
+    Status FinishRegistration(INOUT UserPtr user, const String& pin);
+
+    Status StartAuthentication(INOUT UserPtr user);
+    Status CheckAccessNumber(const String& accessNumber);
+    Status FinishAuthentication(INOUT UserPtr user, const String& pin);
+    Status FinishAuthentication(INOUT UserPtr user, const String& pin, OUT String& authResultData);
+    Status FinishAuthenticationOTP(INOUT UserPtr user, const String& pin, OUT OTP& otp);
+    Status FinishAuthenticationAN(INOUT UserPtr user, const String& pin, const String& accessNumber);
+
     void DeleteUser(INOUT UserPtr user);
     void ListUsers(OUT std::vector<UserPtr>& users);
     const char * GetVersion();
@@ -348,9 +340,9 @@
     Status RewriteRelativeUrls();
     Status GetClientSettings(const String& backend, const String& rpsPrefix, OUT util::JsonObject *clientSettings) const;
     Status RequestRegistration(INOUT UserPtr user, const String& userData);
-    Status AuthenticateImpl(INOUT UserPtr user, const String& accessNumber, OUT String *otp, OUT util::JsonObject& authResultData);
+    Status FinishAuthenticationImpl(INOUT UserPtr user, const String& pin, const String& accessNumber, OUT String *otp, OUT util::JsonObject& authResultData);
     Status GetCertivoxTimePermitShare(INOUT UserPtr user, const util::JsonObject& cutomerTimePermitData, OUT String& resultTimePermit);
-    bool CheckAccessNumber(const String& accessNumber);
+    bool ValidateAccessNumber(const String& accessNumber);
     bool ValidateAccessNumberChecksum(const String& accessNumber);
     void AddUser(IN UserPtr user);
     Status CheckUserState(IN UserPtr user, User::State expectedState);
@@ -361,8 +353,6 @@
     static const int AN_WITH_CHECKSUM_LEN = 7;
 
 private:
-    friend class MPinSDKv2;
-
     typedef std::map<String, UserPtr> UsersMap;
     typedef std::map<UserPtr, LogoutData> LogoutDataMap;
     
diff --git a/src/mpin_sdk_v2.cpp b/src/mpin_sdk_v2.cpp
deleted file mode 100644
index 597e898..0000000
--- a/src/mpin_sdk_v2.cpp
+++ /dev/null
@@ -1,494 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-/*
- * M-Pin SDK version 2 implementation
- */
-
-#include "mpin_sdk_v2.h"
-#include "mpin_crypto.h"
-#include "version.h"
-
-typedef MPinSDKv2::Status Status;
-typedef MPinSDKv2::User User;
-typedef MPinSDKv2::UserPtr UserPtr;
-typedef MPinSDKv2::String String;
-typedef MPinSDKv2::IHttpRequest IHttpRequest;
-typedef MPinSDKv2::IPinPad IPinPad;
-typedef MPinSDKv2::CryptoType CryptoType;
-
-
-
-MPinSDKv2::Context::Context() : m_appContext(NULL)
-{
-    m_pinpad = new Pinpad();
-}
-
-MPinSDKv2::Context::~Context()
-{
-    delete m_pinpad;
-}
-
-void MPinSDKv2::Context::Init(MPinSDKv2::IContext *appContext)
-{
-    m_appContext = appContext;
-}
-
-void MPinSDKv2::Context::SetPin(const String& pin)
-{
-    m_pinpad->SetPin(pin);
-}
-
-IHttpRequest * MPinSDKv2::Context::CreateHttpRequest() const
-{
-    return m_appContext->CreateHttpRequest();
-}
-
-void MPinSDKv2::Context::ReleaseHttpRequest(IN IHttpRequest *request) const
-{
-    m_appContext->ReleaseHttpRequest(request);
-}
-
-MPinSDKv2::IStorage * MPinSDKv2::Context::GetStorage(IStorage::Type type) const
-{
-    return m_appContext->GetStorage(type);
-}
-
-IPinPad * MPinSDKv2::Context::GetPinPad() const
-{
-    return m_pinpad;
-}
-
-CryptoType MPinSDKv2::Context::GetMPinCryptoType() const
-{
-    return m_appContext->GetMPinCryptoType();
-}
-
-
-
-
-
-
-MPinSDKv2::MPinSDKv2()
-{
-}
-
-MPinSDKv2::~MPinSDKv2()
-{
-}
-
-Status MPinSDKv2::Init(const StringMap& config, IN IContext* ctx)
-{
-    m_context.Init(ctx);
-    return m_v1Sdk.Init(config, &m_context);
-}
-
-void MPinSDKv2::Destroy()
-{
-    m_v1Sdk.Destroy();
-}
-
-void MPinSDKv2::ClearUsers()
-{
-    m_v1Sdk.ClearUsers();
-}
-
-Status MPinSDKv2::TestBackend(const String& server, const String& rpsPrefix) const
-{
-    return m_v1Sdk.TestBackend(server, rpsPrefix);
-}
-
-Status MPinSDKv2::SetBackend(const String& server, const String& rpsPrefix)
-{
-    return m_v1Sdk.SetBackend(server, rpsPrefix);
-}
-
-UserPtr MPinSDKv2::MakeNewUser(const String& id, const String& deviceName) const
-{
-    return m_v1Sdk.MakeNewUser(id, deviceName);
-}
-
-Status MPinSDKv2::StartRegistration(INOUT UserPtr user, const String& userData)
-{
-    return m_v1Sdk.StartRegistration(user, userData);
-}
-
-Status MPinSDKv2::RestartRegistration(INOUT UserPtr user, const String& userData)
-{
-    return m_v1Sdk.RestartRegistration(user, userData);
-}
-
-Status MPinSDKv2::VerifyUser(INOUT UserPtr user, const String& mpinId, const String& activationKey)
-{
-    return m_v1Sdk.VerifyUser(user, mpinId, activationKey);
-}
-
-Status MPinSDKv2::ConfirmRegistration(INOUT UserPtr user, const String& pushMessageIdentifier)
-{
-    Status s = m_v1Sdk.CheckIfBackendIsSet();
-    if(s != Status::OK)
-    {
-        return s;
-    }
-
-	// A user can get here either in STARTED_REGISTRATION state or in ACTIVATED state (force-activate flow)
-	// In the first case, the method might fail if the user identity has not been verified yet, and the user state
-	// should stay as it was - STARTED_REGISTRATION
-    s = m_v1Sdk.CheckUserState(user, User::STARTED_REGISTRATION);
-    if(s != Status::OK)
-    {
-		Status sSave = s;
-		s = m_v1Sdk.CheckUserState(user, User::ACTIVATED);
-		if ( s != Status::OK )
-		{
-			return sSave;
-		}
-    }
-
-    // Request a client secret share from the customer's D-TA and a signed request for a client secret share from CertiVox's D-TA.
-    String mpinId = user->GetMPinId();
-    String mpinIdHex = user->GetMPinIdHex();
-    String regOTT = user->GetRegOTT();
-
-    String url = String().Format("%s/%s?regOTT=%s", m_v1Sdk.m_clientSettings.GetStringParam("signatureURL"), mpinIdHex.c_str(), regOTT.c_str());
-    if(!pushMessageIdentifier.empty())
-    {
-        url += "&pmiToken=" + pushMessageIdentifier;
-    }
-
-    HttpResponse response = m_v1Sdk.MakeGetRequest(url);
-    if(response.GetStatus() != HttpResponse::HTTP_OK)
-    {
-        return response.TranslateToMPinStatus(HttpResponse::GET_CLIENT_SECRET1);
-    }
-
-    user->m_clientSecret1 = util::HexDecode(response.GetJsonData().GetStringParam("clientSecretShare"));
-
-    // Request the client secret share from CertiVox's D-TA.
-    String cs2Params = response.GetJsonData().GetStringParam("params");
-    url.Format("%sclientSecret?%s", m_v1Sdk.m_clientSettings.GetStringParam("certivoxURL"), cs2Params.c_str());
-    response = m_v1Sdk.MakeGetRequest(url);
-    if(response.GetStatus() != HttpResponse::HTTP_OK)
-    {
-        return response.TranslateToMPinStatus(HttpResponse::GET_CLIENT_SECRET2);
-    }
-
-    user->m_clientSecret2 = util::HexDecode(response.GetJsonData().GetStringParam("clientSecret"));
-
-    return Status::OK;
-}
-
-Status MPinSDKv2::FinishRegistration(INOUT UserPtr user, const String& pin)
-{
-    Status s = m_v1Sdk.CheckIfBackendIsSet();
-    if(s != Status::OK)
-    {
-        return s;
-    }
-
-	// A user can get here either in STARTED_REGISTRATION state or in ACTIVATED state (force-activate flow)
-	// In the first case, the method might fail if the user identity has not been verified yet, and the user state
-	// should stay as it was - STARTED_REGISTRATION
-    s = m_v1Sdk.CheckUserState(user, User::STARTED_REGISTRATION);
-    if(s != Status::OK)
-    {
-		Status sSave = s;
-		s = m_v1Sdk.CheckUserState(user, User::ACTIVATED);
-		if ( s != Status::OK )
-		{
-			return sSave;
-		}
-    }
-
-    // In addition, client secret shares must be retrieved
-    if(user->m_clientSecret1.empty() || user->m_clientSecret2.empty())
-    {
-        return Status(Status::FLOW_ERROR, String().Format("Cannot finish user '%s' registration: User identity not verified", user->GetId().c_str()));
-    }
-
-    // Set pin to the wrapper context
-    m_context.SetPin(pin);
-
-    s = m_v1Sdk.m_crypto->OpenSession();
-    if(s != Status::OK)
-    {
-        return s;
-    }
-
-    std::vector<String> clientSecretShares;
-    clientSecretShares.push_back(user->m_clientSecret1);
-    clientSecretShares.push_back(user->m_clientSecret2);
-
-    s = m_v1Sdk.m_crypto->Register(user, clientSecretShares);
-    if(s != Status::OK)
-    {
-        m_v1Sdk.m_crypto->CloseSession();
-        return s;
-    }
-
-    m_v1Sdk.m_crypto->CloseSession();
-
-    user->SetRegistered();
-    s = m_v1Sdk.WriteUsersToStorage();
-    if(s != Status::OK)
-    {
-        return s;
-    }
-
-    return Status::OK;
-}
-
-Status MPinSDKv2::StartAuthentication(INOUT UserPtr user)
-{
-    Status s = m_v1Sdk.CheckIfBackendIsSet();
-    if(s != Status::OK)
-    {
-        return s;
-    }
-
-    // Check if the user is already registered
-    s = m_v1Sdk.CheckUserState(user, User::REGISTERED);
-    if(s != Status::OK)
-    {
-        return s;
-    }
-
-    // Request a time permit share from the customer's D-TA and a signed request for a time permit share from CertiVox's D-TA.
-    String mpinIdHex = user->GetMPinIdHex();
-    String url = String().Format("%s/%s", m_v1Sdk.m_clientSettings.GetStringParam("timePermitsURL"), mpinIdHex.c_str());
-    HttpResponse response = m_v1Sdk.MakeGetRequest(url);
-    if(response.GetStatus() != HttpResponse::HTTP_OK)
-    {
-        return response.TranslateToMPinStatus(HttpResponse::GET_TIME_PERMIT1);
-    }
-
-    user->m_timePermitShare1 = util::HexDecode(response.GetJsonData().GetStringParam("timePermit"));
-
-    // Request time permit share from CertiVox's D-TA (Searches first in user cache, than in S3 cache)
-    s = m_v1Sdk.GetCertivoxTimePermitShare(user, response.GetJsonData(), user->m_timePermitShare2);
-    if(s != Status::OK)
-    {
-        return s;
-    }
-
-    return Status::OK;
-}
-
-Status MPinSDKv2::CheckAccessNumber(const String& accessNumber)
-{
-    if(accessNumber.empty() || !m_v1Sdk.CheckAccessNumber(accessNumber))
-    {
-        return Status(Status::INCORRECT_ACCESS_NUMBER, "Invalid access number");
-    }
-
-    return Status::OK;
-}
-
-Status MPinSDKv2::FinishAuthentication(INOUT UserPtr user, const String& pin)
-{
-    util::JsonObject authResult;
-    return FinishAuthenticationImpl(user, pin, "", NULL, authResult);
-}
-
-Status MPinSDKv2::FinishAuthentication(INOUT UserPtr user, const String& pin, OUT String& authResultData)
-{
-    util::JsonObject authResult;
-
-    Status s = FinishAuthenticationImpl(user, pin, "", NULL, authResult);
-
-    authResultData = authResult.ToString();
-    return s;
-}
-
-Status MPinSDKv2::FinishAuthenticationOTP(INOUT UserPtr user, const String& pin, OUT OTP& otp)
-{
-    util::JsonObject authResult;
-    String otpNumber;
-
-    Status s = FinishAuthenticationImpl(user, pin, "", &otpNumber, authResult);
-
-    otp.ExtractFrom(otpNumber, authResult);
-    return s;
-}
-
-Status MPinSDKv2::FinishAuthenticationAN(INOUT UserPtr user, const String& pin, const String& accessNumber)
-{
-    util::JsonObject authResult;
-
-    Status s = FinishAuthenticationImpl(user, pin, accessNumber, NULL, authResult);
-
-    LogoutData logoutData;
-    if(logoutData.ExtractFrom(authResult))
-    {
-        m_v1Sdk.m_logoutData.insert(std::make_pair(user, logoutData));
-    }
-
-    return s;
-}
-
-Status MPinSDKv2::FinishAuthenticationImpl(INOUT UserPtr user, const String& pin, const String& accessNumber, OUT String *otp, OUT util::JsonObject& authResultData)
-{
-    Status s = m_v1Sdk.CheckIfBackendIsSet();
-    if(s != Status::OK)
-    {
-        return s;
-    }
-
-    // Check if the user is already registered
-    s = m_v1Sdk.CheckUserState(user, User::REGISTERED);
-    if(s != Status::OK)
-    {
-        return s;
-    }
-
-    // Check if time permit was obtained from StartAuthentication
-    if(user->m_timePermitShare1.empty() || user->m_timePermitShare2.empty())
-    {
-        return Status(Status::FLOW_ERROR, String().Format("Cannot finish user '%s' authentication: Invalid time permit", user->GetId().c_str()));
-    }
-
-    String mpinIdHex = user->GetMPinIdHex();
-
-    // Set pin to the wrapper context
-    m_context.SetPin(pin);
-
-    s = m_v1Sdk.m_crypto->OpenSession();
-    if(s != Status::OK)
-    {
-        return s;
-    }
-
-    std::vector<String> timePermitShares;
-    timePermitShares.push_back(user->m_timePermitShare1);
-    timePermitShares.push_back(user->m_timePermitShare2);
-
-    // Authentication pass 1
-    String u, ut;
-    s = m_v1Sdk.m_crypto->AuthenticatePass1(user, timePermitShares, u, ut);
-    if(s != Status::OK)
-    {
-        m_v1Sdk.m_crypto->CloseSession();
-        return s;
-    }
-
-    util::JsonObject requestData;
-    requestData["pass"] = json::Number(1);
-    requestData["mpin_id"] = json::String(mpinIdHex);
-    requestData["UT"] = json::String(util::HexEncode(ut));
-    requestData["U"] = json::String(util::HexEncode(u));
-
-    String mpinAuthServerURL = m_v1Sdk.m_clientSettings.GetStringParam("mpinAuthServerURL");
-    String url = String().Format("%s/pass1", mpinAuthServerURL.c_str());
-    HttpResponse response = m_v1Sdk.MakeRequest(url, IHttpRequest::POST, requestData);
-    if(response.GetStatus() != HttpResponse::HTTP_OK)
-    {
-        m_v1Sdk.m_crypto->CloseSession();
-        return response.TranslateToMPinStatus(HttpResponse::AUTHENTICATE_PASS1);
-    }
-
-    String y = util::HexDecode(response.GetJsonData().GetStringParam("y"));
-
-    // Authentication pass 2
-    String v;
-    m_v1Sdk.m_crypto->AuthenticatePass2(user, y, v);
-    if(s != Status::OK)
-    {
-        m_v1Sdk.m_crypto->CloseSession();
-        return s;
-    }
-
-    requestData.Clear();
-    requestData["pass"] = json::Number(2);
-    requestData["OTP"] = json::Boolean(otp != NULL ? true : false);
-    requestData["WID"] = json::String(accessNumber.empty() ? "0" : accessNumber);
-    requestData["V"] = json::String(util::HexEncode(v));
-    requestData["mpin_id"] = json::String(mpinIdHex);
-
-    url.Format("%s/pass2", mpinAuthServerURL.c_str());
-    response = m_v1Sdk.MakeRequest(url, IHttpRequest::POST, requestData);
-    if(response.GetStatus() != HttpResponse::HTTP_OK)
-    {
-        m_v1Sdk.m_crypto->CloseSession();
-        return response.TranslateToMPinStatus(HttpResponse::AUTHENTICATE_PASS2);
-    }
-
-    // Save OTP data to be used if otp was requested
-    if(otp != NULL)
-    {
-        *otp = response.GetJsonData().GetStringParam("OTP");
-    }
-
-    // Send response data from M-Pin authentication server to RPA
-    url = m_v1Sdk.m_clientSettings.GetStringParam(accessNumber.empty() ? "authenticateURL" : "mobileAuthenticateURL");
-    requestData.Clear();
-    requestData["mpinResponse"] = response.GetJsonData();
-    response = m_v1Sdk.MakeRequest(url, IHttpRequest::POST, requestData);
-    if(response.GetStatus() != HttpResponse::HTTP_OK)
-    {
-        m_v1Sdk.m_crypto->CloseSession();
-        s = response.TranslateToMPinStatus(HttpResponse::AUTHENTICATE_RPA);
-
-        if(response.GetStatus() == HttpResponse::HTTP_GONE)
-        {
-            user->Block();
-            m_v1Sdk.m_crypto->DeleteToken(user->GetMPinId());
-            m_v1Sdk.WriteUsersToStorage();
-        }
-
-        return s;
-    }
-	
-    // You are now logged in with M-Pin!
-    m_v1Sdk.m_crypto->CloseSession();
-
-    authResultData = response.GetJsonData();
-
-    return Status::OK;
-}
-
-void MPinSDKv2::DeleteUser(INOUT UserPtr user)
-{
-    m_v1Sdk.DeleteUser(user);
-}
-
-void MPinSDKv2::ListUsers(OUT std::vector<UserPtr>& users)
-{
-    m_v1Sdk.ListUsers(users);
-}
-
-const char * MPinSDKv2::GetVersion()
-{
-    return MPIN_SDK_V2_VERSION;
-}
-
-bool MPinSDKv2::CanLogout(IN UserPtr user)
-{
-    return m_v1Sdk.CanLogout(user);
-}
-
-bool MPinSDKv2::Logout(IN UserPtr user)
-{
-    return m_v1Sdk.Logout(user);
-}
-
-String MPinSDKv2::GetClientParam(const String& key)
-{
-    return m_v1Sdk.GetClientParam(key);
-}
-
diff --git a/src/mpin_sdk_v2.h b/src/mpin_sdk_v2.h
deleted file mode 100644
index fa3f93f..0000000
--- a/src/mpin_sdk_v2.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-/*
- * M-Pin SDK version 2 interface
- */
-
-#ifndef _MPIN_SDK_V2_H_
-#define _MPIN_SDK_V2_H_
-
-#include "mpin_sdk.h"
-
-class MPinSDKv2
-{
-public:
-    typedef util::String String;
-    typedef util::StringMap StringMap;
-    typedef MPinSDK::User User;
-    typedef MPinSDK::UserPtr UserPtr;
-    typedef MPinSDK::CryptoType CryptoType;
-    typedef MPinSDK::IHttpRequest IHttpRequest;
-    typedef MPinSDK::IStorage IStorage;
-    typedef MPinSDK::IPinPad IPinPad;
-    typedef MPinSDK::Status Status;
-    typedef MPinSDK::OTP OTP;
-
-    class IContext
-    {
-    public:
-        virtual ~IContext() {}
-        virtual IHttpRequest * CreateHttpRequest() const = 0;
-        virtual void ReleaseHttpRequest(IN IHttpRequest *request) const = 0;
-        virtual IStorage * GetStorage(IStorage::Type type) const = 0;
-        virtual CryptoType GetMPinCryptoType() const = 0;
-    };
-
-    MPinSDKv2();
-    ~MPinSDKv2();
-
-    Status Init(const StringMap& config, IN IContext* ctx);
-    void Destroy();
-    void ClearUsers();
-
-    Status TestBackend(const String& server, const String& rpsPrefix = MPinSDK::DEFAULT_RPS_PREFIX) const;
-    Status SetBackend(const String& server, const String& rpsPrefix = MPinSDK::DEFAULT_RPS_PREFIX);
-    UserPtr MakeNewUser(const String& id, const String& deviceName = "") const;
-
-    Status StartRegistration(INOUT UserPtr user, const String& userData = "");
-    Status RestartRegistration(INOUT UserPtr user, const String& userData = "");
-    Status VerifyUser(INOUT UserPtr user, const String& mpinId, const String& activationKey);
-    Status ConfirmRegistration(INOUT UserPtr user, const String& pushMessageIdentifier = "");
-    Status FinishRegistration(INOUT UserPtr user, const String& pin);
-
-    Status StartAuthentication(INOUT UserPtr user);
-    Status CheckAccessNumber(const String& accessNumber);
-    Status FinishAuthentication(INOUT UserPtr user, const String& pin);
-    Status FinishAuthentication(INOUT UserPtr user, const String& pin, OUT String& authResultData);
-    Status FinishAuthenticationOTP(INOUT UserPtr user, const String& pin, OUT OTP& otp);
-    Status FinishAuthenticationAN(INOUT UserPtr user, const String& pin, const String& accessNumber);
-
-    void DeleteUser(INOUT UserPtr user);
-    void ListUsers(OUT std::vector<UserPtr>& users);
-    const char * GetVersion();
-    bool CanLogout(IN UserPtr user);
-    bool Logout(IN UserPtr user);
-	String GetClientParam(const String& key);
-
-private:
-    Status FinishAuthenticationImpl(INOUT UserPtr user, const String& pin, const String& accessNumber, OUT String *otp, OUT util::JsonObject& authResultData);
-
-    typedef MPinSDK::TimePermitCache TimePermitCache;
-    typedef MPinSDK::HttpResponse HttpResponse;
-    typedef MPinSDK::State State;
-    typedef MPinSDK::LogoutData LogoutData;
-
-    class Context : public MPinSDK::IContext
-    {
-    public:
-        Context();
-        ~Context();
-        void Init(MPinSDKv2::IContext *appContext);
-        void SetPin(const String& pin);
-        virtual IHttpRequest * CreateHttpRequest() const;
-        virtual void ReleaseHttpRequest(IN IHttpRequest *request) const;
-        virtual IStorage * GetStorage(IStorage::Type type) const;
-        virtual IPinPad * GetPinPad() const;
-        virtual CryptoType GetMPinCryptoType() const;
-
-    private:
-        class Pinpad : public IPinPad
-        {
-        public:
-            void SetPin(const String& pin) { m_pin = pin; }
-            virtual String Show(UserPtr user, Mode mode) { return m_pin; }
-        private:
-            String m_pin;
-        };
-
-        MPinSDKv2::IContext *m_appContext;
-        Pinpad *m_pinpad;
-    };
-
-    MPinSDK m_v1Sdk;
-    Context m_context;
-};
-
-#endif // _MPIN_SDK_V2_H_
diff --git a/src/utils.cpp b/src/utils.cpp
index f72bf47..045e25e 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -45,7 +45,7 @@
     return *this;
 }
 
-int String::GetHash()
+int String::GetHash() const
 {
     // Implements java style hashcode: h(s)=\sum_{i=0}^{n-1}s[i] \cdot 31^{n-1-i}
     int hash = 0;
diff --git a/src/utils.h b/src/utils.h
index 86f10ea..2391da9 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -47,7 +47,7 @@
     ~String();
     String& Trim(const std::string& chars = " \t\f\v\n\r");
     void Overwrite(char c = ' ');
-    int GetHash();
+    int GetHash() const;
 };
 
 void OverwriteString(std::string& str, char c = ' ');
diff --git a/tests/cmdline_test.cpp b/tests/cmdline_test.cpp
index 98e01ad..aae0b13 100644
--- a/tests/cmdline_test.cpp
+++ b/tests/cmdline_test.cpp
@@ -116,7 +116,20 @@
             _getch();
         }
 
-        s = sdk.FinishRegistration(user);
+        s = sdk.ConfirmRegistration(user);
+        if(s != MPinSDK::Status::OK)
+        {
+            cout << "Failed to confirm user registration: status code = " << s.GetStatusCode() << ", error: " << s.GetErrorMessage() << endl;
+            _getch();
+            sdk.Destroy();
+            return 0;
+        }
+
+        MPinSDK::String pin;
+        cout << "Enter pin: ";
+        cin >> pin;
+
+        s = sdk.FinishRegistration(user, pin);
         if(s != MPinSDK::Status::OK)
         {
             cout << "Failed to finish user registration: status code = " << s.GetStatusCode() << ", error: " << s.GetErrorMessage() << endl;
@@ -129,8 +142,21 @@
         _getch();
     }
 
+    s = sdk.StartAuthentication(user);
+    if(s != MPinSDK::Status::OK)
+    {
+        cout << "Failed to start user authentication: status code = " << s.GetStatusCode() << ", error: " << s.GetErrorMessage() << endl;
+        _getch();
+        sdk.Destroy();
+        return 0;
+    }
+
+    MPinSDK::String pin;
+    cout << "Enter pin: ";
+    cin >> pin;
+
     MPinSDK::String authData;
-    s = sdk.Authenticate(user, authData);
+    s = sdk.FinishAuthentication(user, pin, authData);
     if(s != MPinSDK::Status::OK)
     {
         cout << "Failed to authenticate user: status code = " << s.GetStatusCode() << ", error: " << s.GetErrorMessage() << endl;
diff --git a/tests/cmdline_v2_test.cpp b/tests/cmdline_v2_test.cpp
deleted file mode 100644
index a951e22..0000000
--- a/tests/cmdline_v2_test.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-#include <iostream>
-#include <fstream>
-#include <conio.h>
-#include <map>
-#include <vector>
-
-#include "mpin_sdk_v2.h"
-#include "contexts/cmdline_context_v2.h"
-#include "CvLogger.h"
-
-using namespace std;
-
-struct Backend
-{
-    const char *backend;
-    const char *rpsPrefix;
-};
-
-static void TestBackend(const MPinSDKv2& sdk, const char *backend, const char *rpsPrefix);
-
-int main(int argc, char *argv[])
-{
-    CvShared::InitLogger("cvlog.txt", CvShared::enLogLevel_None);
-
-    Backend backends[] = 
-    {
-        {"https://m-pindemo.certivox.org"},
-        //{"http://ec2-54-77-232-113.eu-west-1.compute.amazonaws.com", "/rps/"},
-        //{"https://mpindemo-qa-v3.certivox.org", "rps"},
-    };
-    size_t backendCount = sizeof(backends) / sizeof(backends[0]);
-
-    Backend& backend = backends[0];
-    MPinSDK::StringMap config;
-    config.Put(MPinSDK::CONFIG_BACKEND, backend.backend);
-    if(backend.rpsPrefix != NULL)
-    {
-        config.Put(MPinSDK::CONFIG_RPS_PREFIX, backend.rpsPrefix);
-    }
-
-    CmdLineContextV2 context("windows_test_v2_users.json", "windows_test_v2_tokens.json");
-    MPinSDKv2 sdk;
-
-    cout << "Using MPinSDK version " << sdk.GetVersion() << endl;
-
-    MPinSDK::Status s = sdk.Init(config, &context);
-    if(s != MPinSDK::Status::OK)
-    {
-        cout << "Failed to initialize MPinSDK: status code = " << s.GetStatusCode() << ", error: " << s.GetErrorMessage() << endl;
-        _getch();
-        sdk.Destroy();
-        return 0;
-    }
-
-    for(size_t i = 0; i < backendCount; ++i)
-    {
-        TestBackend(sdk, backends[i].backend, backends[i].rpsPrefix);
-    }
-
-    //s = sdk.SetBackend(backends[1].backend, backends[1].rpsPrefix);
-    if(s != MPinSDK::Status::OK)
-    {
-        cout << "Failed to set backend to MPinSDK: status code = " << s.GetStatusCode() << ", error: " << s.GetErrorMessage() << endl;
-        _getch();
-        sdk.Destroy();
-        return 0;
-    }
-
-    vector<MPinSDK::UserPtr> users;
-    sdk.ListUsers(users);
-    MPinSDK::UserPtr user;
-    if(!users.empty())
-    {
-        user = users[0];
-        cout << "Authenticating user '" << user->GetId() << "'" << endl;
-    }
-    else
-    {
-        user = sdk.MakeNewUser("slav.klenov@certivox.com", "Test Windows Device");
-        cout << "Did not found any registered users. Will register new user '" << user->GetId() << "'" << endl;
-        s = sdk.StartRegistration(user);
-        if(s != MPinSDK::Status::OK)
-        {
-            cout << "Failed to start user registration: status code = " << s.GetStatusCode() << ", error: " << s.GetErrorMessage() << endl;
-            _getch();
-            sdk.Destroy();
-            return 0;
-        }
-
-        if(user->GetState() == MPinSDK::User::ACTIVATED)
-        {
-            cout << "User registered and force activated" << endl;
-        }
-        else
-        {
-            cout << "Registration started. Press any key after activation is confirmed..." << endl;
-            _getch();
-        }
-
-        s = sdk.ConfirmRegistration(user);
-        if(s != MPinSDK::Status::OK)
-        {
-            cout << "Failed to confirm user registration: status code = " << s.GetStatusCode() << ", error: " << s.GetErrorMessage() << endl;
-            _getch();
-            sdk.Destroy();
-            return 0;
-        }
-
-        MPinSDK::String pin;
-        cout << "Enter pin: ";
-        cin >> pin;
-
-        s = sdk.FinishRegistration(user, pin);
-        if(s != MPinSDK::Status::OK)
-        {
-            cout << "Failed to finish user registration: status code = " << s.GetStatusCode() << ", error: " << s.GetErrorMessage() << endl;
-            _getch();
-            sdk.Destroy();
-            return 0;
-        }
-
-        cout << "User successfuly registered. Press any key to authenticate user..." << endl;
-        _getch();
-    }
-
-    s = sdk.StartAuthentication(user);
-    if(s != MPinSDK::Status::OK)
-    {
-        cout << "Failed to start user authentication: status code = " << s.GetStatusCode() << ", error: " << s.GetErrorMessage() << endl;
-        _getch();
-        sdk.Destroy();
-        return 0;
-    }
-
-    MPinSDK::String pin;
-    cout << "Enter pin: ";
-    cin >> pin;
-
-    MPinSDK::String authData;
-    s = sdk.FinishAuthentication(user, pin, authData);
-    if(s != MPinSDK::Status::OK)
-    {
-        cout << "Failed to authenticate user: status code = " << s.GetStatusCode() << ", error: " << s.GetErrorMessage() << endl;
-        _getch();
-        sdk.Destroy();
-        return 0;
-    }
-
-    cout << "User successfuly authenticated! Auth result data:" << endl << authData << endl;
-    cout << "Press any key to exit..." << endl;
-
-    _getch();
-    sdk.Destroy();
-
-    return 0;
-}
-
-static void TestBackend(const MPinSDKv2& sdk, const char *beckend, const char *rpsPrefix)
-{
-    MPinSDK::Status s;
-    if(rpsPrefix != NULL)
-    {
-        s = sdk.TestBackend(beckend, rpsPrefix);
-    }
-    else
-    {
-        s = sdk.TestBackend(beckend);
-    }
-    if(s != MPinSDK::Status::OK)
-    {
-        cout << "Backend test failed: " << beckend << ", status code = " << s.GetStatusCode() << ", error: " << s.GetErrorMessage() << endl;
-    }
-    else
-    {
-        cout << "Backend test OK: " << beckend << endl;
-    }
-}
diff --git a/tests/contexts/auto_context.cpp b/tests/contexts/auto_context.cpp
index ff82be8..dc3c981 100644
--- a/tests/contexts/auto_context.cpp
+++ b/tests/contexts/auto_context.cpp
@@ -30,32 +30,10 @@
 
 typedef MPinSDK::String String;
 typedef MPinSDK::IHttpRequest IHttpRequest;
-typedef MPinSDK::IPinPad IPinPad;
 typedef MPinSDK::CryptoType CryptoType;
 typedef MPinSDK::UserPtr UserPtr;
 
 /*
- * Pinpad class impl
- */
-
-class AutoPinpad : public MPinSDK::IPinPad
-{
-public:
-    void SetPin(const String& pin)
-    {
-        m_pin = pin;
-    }
-
-    virtual String Show(UserPtr user, Mode mode)
-    {
-        return m_pin;
-    }
-
-private:
-    String m_pin;
-};
-
-/*
  * Context class impl
  */
 
@@ -63,14 +41,12 @@
 {
     m_nonSecureStorage = new MemoryStorage();
     m_secureStorage = new MemoryStorage();
-    m_pinpad = new AutoPinpad();
 }
 
 AutoContext::~AutoContext()
 {
     delete m_nonSecureStorage;
     delete m_secureStorage;
-    delete m_pinpad;
 }
 
 IHttpRequest * AutoContext::CreateHttpRequest() const
@@ -93,17 +69,7 @@
     return m_nonSecureStorage;
 }
 
-IPinPad * AutoContext::GetPinPad() const
-{
-    return m_pinpad;
-}
-
 CryptoType AutoContext::GetMPinCryptoType() const
 {
     return MPinSDK::CRYPTO_NON_TEE;
 }
-
-void AutoContext::SetPin(const String& pin)
-{
-    ((AutoPinpad *) m_pinpad)->SetPin(pin);
-}
diff --git a/tests/contexts/auto_context.h b/tests/contexts/auto_context.h
index 5d8b86a..7c6b011 100644
--- a/tests/contexts/auto_context.h
+++ b/tests/contexts/auto_context.h
@@ -32,7 +32,6 @@
     typedef MPinSDK::String String;
     typedef MPinSDK::IHttpRequest IHttpRequest;
     typedef MPinSDK::IStorage IStorage;
-    typedef MPinSDK::IPinPad IPinPad;
     typedef MPinSDK::CryptoType CryptoType;
 
     AutoContext();
@@ -40,14 +39,11 @@
     virtual IHttpRequest * CreateHttpRequest() const;
     virtual void ReleaseHttpRequest(IN IHttpRequest *request) const;
     virtual IStorage * GetStorage(IStorage::Type type) const;
-    virtual IPinPad * GetPinPad() const;
     virtual CryptoType GetMPinCryptoType() const;
-    void SetPin(const String& pin);
 
 private:
     IStorage *m_nonSecureStorage;
     IStorage *m_secureStorage;
-    IPinPad *m_pinpad;
 };
 
 #endif // _AUTO_CONTEXT_H_
diff --git a/tests/contexts/auto_context_v2.cpp b/tests/contexts/auto_context_v2.cpp
deleted file mode 100644
index 471c971..0000000
--- a/tests/contexts/auto_context_v2.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-#include "auto_context_v2.h"
-#include "../common/http_request.h"
-#include "../common/memory_storage.h"
-
-#include <iostream>
-#include <fstream>
-
-typedef MPinSDKv2::String String;
-typedef MPinSDKv2::IHttpRequest IHttpRequest;
-typedef MPinSDKv2::CryptoType CryptoType;
-typedef MPinSDKv2::UserPtr UserPtr;
-
-AutoContextV2::AutoContextV2()
-{
-    m_nonSecureStorage = new MemoryStorage();
-    m_secureStorage = new MemoryStorage();
-}
-
-AutoContextV2::~AutoContextV2()
-{
-    delete m_nonSecureStorage;
-    delete m_secureStorage;
-}
-
-IHttpRequest * AutoContextV2::CreateHttpRequest() const
-{
-    return new HttpRequest();
-}
-
-void AutoContextV2::ReleaseHttpRequest(IN IHttpRequest *request) const
-{
-    delete request;
-}
-
-MPinSDK::IStorage * AutoContextV2::GetStorage(IStorage::Type type) const
-{
-    if(type == IStorage::SECURE)
-    {
-        return m_secureStorage;
-    }
-
-    return m_nonSecureStorage;
-}
-
-CryptoType AutoContextV2::GetMPinCryptoType() const
-{
-    return MPinSDK::CRYPTO_NON_TEE;
-}
diff --git a/tests/contexts/auto_context_v2.h b/tests/contexts/auto_context_v2.h
deleted file mode 100644
index 9c47065..0000000
--- a/tests/contexts/auto_context_v2.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-#ifndef _AUTO_CONTEXT_V2_H_
-#define _AUTO_CONTEXT_V2_H_
-
-#include "mpin_sdk_v2.h"
-
-class AutoContextV2 : public MPinSDKv2::IContext
-{
-public:
-    typedef MPinSDKv2::String String;
-    typedef MPinSDKv2::IHttpRequest IHttpRequest;
-    typedef MPinSDKv2::IStorage IStorage;
-    typedef MPinSDKv2::CryptoType CryptoType;
-
-    AutoContextV2();
-    ~AutoContextV2();
-    virtual IHttpRequest * CreateHttpRequest() const;
-    virtual void ReleaseHttpRequest(IN IHttpRequest *request) const;
-    virtual IStorage * GetStorage(IStorage::Type type) const;
-    virtual CryptoType GetMPinCryptoType() const;
-
-private:
-    IStorage *m_nonSecureStorage;
-    IStorage *m_secureStorage;
-};
-
-#endif // _AUTO_CONTEXT_V2_H_
diff --git a/tests/contexts/cmdline_context.cpp b/tests/contexts/cmdline_context.cpp
index ea354fe..0bc97fd 100644
--- a/tests/contexts/cmdline_context.cpp
+++ b/tests/contexts/cmdline_context.cpp
@@ -30,35 +30,11 @@
 
 typedef MPinSDK::String String;
 typedef MPinSDK::IHttpRequest IHttpRequest;
-typedef MPinSDK::IPinPad IPinPad;
 typedef MPinSDK::CryptoType CryptoType;
 typedef MPinSDK::UserPtr UserPtr;
 using namespace std;
 
 /*
- * Pinpad class impl
- */
-
-class CmdLinePinpad : public MPinSDK::IPinPad
-{
-public:
-    virtual String Show(UserPtr user, Mode mode)
-    {
-        String pin;
-        cout << "Enter pin: ";
-        cin >> pin;
-
-        // Special character to simulate PIN_INPUT_CANCELED
-        if(pin == "c")
-        {
-            pin.clear();
-        }
-
-        return pin;
-    }
-};
-
-/*
  * Context class impl
  */
 
@@ -66,14 +42,12 @@
 {
     m_nonSecureStorage = new FileStorage(usersFile);
     m_secureStorage = new FileStorage(tokensFile);
-    m_pinpad = new CmdLinePinpad();
 }
 
 CmdLineContext::~CmdLineContext()
 {
     delete m_nonSecureStorage;
     delete m_secureStorage;
-    delete m_pinpad;
 }
 
 IHttpRequest * CmdLineContext::CreateHttpRequest() const
@@ -96,11 +70,6 @@
     return m_nonSecureStorage;
 }
 
-IPinPad * CmdLineContext::GetPinPad() const
-{
-    return m_pinpad;
-}
-
 CryptoType CmdLineContext::GetMPinCryptoType() const
 {
     return MPinSDK::CRYPTO_NON_TEE;
diff --git a/tests/contexts/cmdline_context.h b/tests/contexts/cmdline_context.h
index b1cfde7..80c4511 100644
--- a/tests/contexts/cmdline_context.h
+++ b/tests/contexts/cmdline_context.h
@@ -32,7 +32,6 @@
     typedef MPinSDK::String String;
     typedef MPinSDK::IHttpRequest IHttpRequest;
     typedef MPinSDK::IStorage IStorage;
-    typedef MPinSDK::IPinPad IPinPad;
     typedef MPinSDK::CryptoType CryptoType;
 
     CmdLineContext(const String& usersFile, const String& tokensFile);
@@ -40,13 +39,11 @@
     virtual IHttpRequest * CreateHttpRequest() const;
     virtual void ReleaseHttpRequest(IN IHttpRequest *request) const;
     virtual IStorage * GetStorage(IStorage::Type type) const;
-    virtual IPinPad * GetPinPad() const;
     virtual CryptoType GetMPinCryptoType() const;
 
 private:
     IStorage *m_nonSecureStorage;
     IStorage *m_secureStorage;
-    IPinPad *m_pinpad;
 };
 
 #endif // _CMDLINE_CONTEXT_H_
diff --git a/tests/contexts/cmdline_context_v2.cpp b/tests/contexts/cmdline_context_v2.cpp
deleted file mode 100644
index 9738b86..0000000
--- a/tests/contexts/cmdline_context_v2.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-/*
- * MPinSDK::IContext and all related interfaces implementation for command line test client
- */
-
-#include "cmdline_context_v2.h"
-#include "../common/http_request.h"
-#include "../common/file_storage.h"
-
-#include <iostream>
-#include <fstream>
-
-typedef MPinSDKv2::String String;
-typedef MPinSDKv2::IHttpRequest IHttpRequest;
-typedef MPinSDKv2::CryptoType CryptoType;
-typedef MPinSDKv2::UserPtr UserPtr;
-
-/*
- * Context class impl
- */
-
-CmdLineContextV2::CmdLineContextV2(const String& usersFile, const String& tokensFile)
-{
-    m_nonSecureStorage = new FileStorage(usersFile);
-    m_secureStorage = new FileStorage(tokensFile);
-}
-
-CmdLineContextV2::~CmdLineContextV2()
-{
-    delete m_nonSecureStorage;
-    delete m_secureStorage;
-}
-
-IHttpRequest * CmdLineContextV2::CreateHttpRequest() const
-{
-    return new HttpRequest();
-}
-
-void CmdLineContextV2::ReleaseHttpRequest(IN IHttpRequest *request) const
-{
-    delete request;
-}
-
-MPinSDK::IStorage * CmdLineContextV2::GetStorage(IStorage::Type type) const
-{
-    if(type == IStorage::SECURE)
-    {
-        return m_secureStorage;
-    }
-
-    return m_nonSecureStorage;
-}
-
-CryptoType CmdLineContextV2::GetMPinCryptoType() const
-{
-    return MPinSDK::CRYPTO_NON_TEE;
-}
diff --git a/tests/contexts/cmdline_context_v2.h b/tests/contexts/cmdline_context_v2.h
deleted file mode 100644
index b74ed6e..0000000
--- a/tests/contexts/cmdline_context_v2.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-/*
- * MPinSDKv2::IContext and all related interfaces implementation for command line test client
- */
-
-#ifndef _CMDLINE_CONTEXT_V2_H_
-#define _CMDLINE_CONTEXT_V2_H_
-
-#include "mpin_sdk_v2.h"
-
-class CmdLineContextV2 : public MPinSDKv2::IContext
-{
-public:
-    typedef MPinSDKv2::String String;
-    typedef MPinSDKv2::IHttpRequest IHttpRequest;
-    typedef MPinSDKv2::IStorage IStorage;
-    typedef MPinSDKv2::CryptoType CryptoType;
-
-    CmdLineContextV2(const String& usersFile, const String& tokensFile);
-    ~CmdLineContextV2();
-    virtual IHttpRequest * CreateHttpRequest() const;
-    virtual void ReleaseHttpRequest(IN IHttpRequest *request) const;
-    virtual IStorage * GetStorage(IStorage::Type type) const;
-    virtual CryptoType GetMPinCryptoType() const;
-
-private:
-    IStorage *m_nonSecureStorage;
-    IStorage *m_secureStorage;
-};
-
-#endif // _CMDLINE_CONTEXT_V2_H_
diff --git a/tests/unit_tests.cpp b/tests/unit_tests.cpp
index c21e026..1950189 100644
--- a/tests/unit_tests.cpp
+++ b/tests/unit_tests.cpp
@@ -35,13 +35,22 @@
 static AutoContext context;
 static MPinSDK sdk;
 static MPinSDK::StringMap config;
-//static const char *backend = "http://ec2-54-77-232-113.eu-west-1.compute.amazonaws.com";
-static const char *backend = "http://ec2-52-28-120-46.eu-central-1.compute.amazonaws.com";
+static const char *backend = "http://192.168.98.89:8005";
 
 using namespace boost::unit_test;
 
+static std::ostream& operator<<(std::ostream& ostr, const Status& s)
+{
+    ostr << s.GetStatusCode();
+    return ostr;
+}
+
 BOOST_AUTO_TEST_CASE(testNoInit)
 {
+    unit_test_log.set_threshold_level(log_messages);
+
+    BOOST_MESSAGE("Starting testNoInit...");
+
     CvShared::InitLogger("cvlog.txt", CvShared::enLogLevel_None);
 
     int argc = framework::master_test_suite().argc;
@@ -52,104 +61,158 @@
     }
 
     Status s = sdk.TestBackend("12354");
-    BOOST_CHECK(s == Status::FLOW_ERROR);
+    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
 
     s = sdk.SetBackend("12354");
-    BOOST_CHECK(s == Status::FLOW_ERROR);
+    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
 
     UserPtr user = sdk.MakeNewUser("testUser");
 
     s = sdk.StartRegistration(user);
-    BOOST_CHECK(s == Status::FLOW_ERROR);
-    BOOST_CHECK(user->GetState() == User::INVALID);
+    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
+    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
 
     s = sdk.RestartRegistration(user);
-    BOOST_CHECK(s == Status::FLOW_ERROR);
-    BOOST_CHECK(user->GetState() == User::INVALID);
+    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
+    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
 
-    s = sdk.FinishRegistration(user);
-    BOOST_CHECK(s == Status::FLOW_ERROR);
-    BOOST_CHECK(user->GetState() == User::INVALID);
+    s = sdk.VerifyUser(user, "", "");
+    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
+    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
 
-    s = sdk.Authenticate(user);
-    BOOST_CHECK(s == Status::FLOW_ERROR);
-    BOOST_CHECK(user->GetState() == User::INVALID);
+    s = sdk.ConfirmRegistration(user);
+    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
+    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
+
+    s = sdk.FinishRegistration(user, "");
+    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
+    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
+
+    s = sdk.StartAuthentication(user);
+    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
+    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
+
+    s = sdk.FinishAuthentication(user, "");
+    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
+    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
+
+    String authResultData;
+    s = sdk.FinishAuthentication(user, "", authResultData);
+    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
+    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
+
+    MPinSDK::OTP otp;
+    s = sdk.FinishAuthenticationOTP(user, "", otp);
+    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
+    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
+
+    s = sdk.FinishAuthenticationAN(user, "", "");
+    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
+    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
+
+    BOOST_MESSAGE("    testNoInit finished");
 }
 
 BOOST_AUTO_TEST_CASE(testInit)
 {
+    BOOST_MESSAGE("Starting testInit...");
+
     config.Put(MPinSDK::CONFIG_BACKEND, backend);
 
     Status s = sdk.Init(config, &context);
 
-    BOOST_CHECK(s == Status::OK);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+
+    BOOST_MESSAGE("    testInit finished");
 }
 
 BOOST_AUTO_TEST_CASE(testBackend)
 {
+    BOOST_MESSAGE("Starting testBackend...");
+
     Status s = sdk.TestBackend("https://m-pindemo.certivox.org");
-    BOOST_CHECK(s == Status::OK);
+    BOOST_CHECK_EQUAL(s, Status::OK);
 
     s = sdk.TestBackend("https://blabla.certivox.org");
-    BOOST_CHECK(s != Status::OK);
+    BOOST_CHECK_NE(s, Status::OK);
+
+    BOOST_MESSAGE("    testBackend finished");
 }
 
 BOOST_AUTO_TEST_CASE(setBackend)
 {
+    BOOST_MESSAGE("Starting setBackend...");
+
     Status s = sdk.SetBackend("https://blabla.certivox.org");
-    BOOST_CHECK(s != Status::OK);
+    BOOST_CHECK_NE(s, Status::OK);
 
     s = sdk.SetBackend(backend);
-    BOOST_CHECK(s == Status::OK);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+
+    BOOST_MESSAGE("    setBackend finished");
 }
 
 BOOST_AUTO_TEST_CASE(testUsers1)
 {
+    BOOST_MESSAGE("Starting testUsers1...");
+
     UserPtr user = sdk.MakeNewUser("testUser");
-    BOOST_CHECK(user->GetState() == User::INVALID);
+    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
 
     Status s = sdk.StartRegistration(user);
 
-    BOOST_CHECK(s == Status::OK);
-    BOOST_CHECK(user->GetState() == User::ACTIVATED);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
 
     sdk.DeleteUser(user);
     std::vector<UserPtr> users;
     sdk.ListUsers(users);
     BOOST_CHECK(users.empty());
+
+    BOOST_MESSAGE("    testUsers1 finished");
 }
 
 BOOST_AUTO_TEST_CASE(testUsers2)
 {
+    BOOST_MESSAGE("Starting testUsers2...");
+
     UserPtr user = sdk.MakeNewUser("testUser");
     Status s = sdk.StartRegistration(user);
 
     std::vector<UserPtr> users;
     sdk.ListUsers(users);
-    BOOST_CHECK(users.size() == 1);
+    BOOST_CHECK_EQUAL(users.size(), 1);
 
     sdk.DeleteUser(user);
+
+    BOOST_MESSAGE("    testUsers2 finished");
 }
 
 BOOST_AUTO_TEST_CASE(testUsers3)
 {
+    BOOST_MESSAGE("Starting testUsers3...");
+
     UserPtr user = sdk.MakeNewUser("testUser");
 
-    Status s = sdk.Authenticate(user);
-    BOOST_CHECK(s == Status::FLOW_ERROR);
-    BOOST_CHECK(user->GetState() == User::INVALID);
+    Status s = sdk.StartAuthentication(user);
+    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
+    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
 
-    s = sdk.FinishRegistration(user);
-    BOOST_CHECK(s == Status::FLOW_ERROR);
-    BOOST_CHECK(user->GetState() == User::INVALID);
+    s = sdk.FinishRegistration(user, "");
+    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
+    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
 
     s = sdk.RestartRegistration(user);
-    BOOST_CHECK(s == Status::FLOW_ERROR);
-    BOOST_CHECK(user->GetState() == User::INVALID);
+    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
+    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
+
+    BOOST_MESSAGE("    testUsers3 finished");
 }
 
 BOOST_AUTO_TEST_CASE(testUsers4)
 {
+    BOOST_MESSAGE("Starting testUsers4...");
+
     int count = 10;
     for(int i = 0; i < count; ++i)
     {
@@ -158,13 +221,13 @@
         UserPtr user = sdk.MakeNewUser(id);
 
         Status s = sdk.StartRegistration(user);
-        BOOST_CHECK(s == Status::OK);
-        BOOST_CHECK(user->GetState() == User::ACTIVATED);
+        BOOST_CHECK_EQUAL(s, Status::OK);
+        BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
     }
 
     std::vector<UserPtr> users;
     sdk.ListUsers(users);
-    BOOST_CHECK(users.size() == count);
+    BOOST_CHECK_EQUAL(users.size(), count);
 
     for(std::vector<UserPtr>::iterator i = users.begin(); i != users.end(); ++i)
     {
@@ -174,175 +237,250 @@
 
     sdk.ListUsers(users);
     BOOST_CHECK(users.empty());
+
+    BOOST_MESSAGE("    testUsers4 finished");
 }
 
 BOOST_AUTO_TEST_CASE(testUsers5)
 {
+    BOOST_MESSAGE("Starting testUsers5...");
+
     UserPtr user = sdk.MakeNewUser("testUser");
     sdk.StartRegistration(user);
 
     BOOST_CHECK(!sdk.CanLogout(user));
     BOOST_CHECK(!sdk.Logout(user));
     sdk.DeleteUser(user);
+
+    BOOST_MESSAGE("    testUsers5 finished");
 }
 
+
 BOOST_AUTO_TEST_CASE(testRegister1)
 {
+    BOOST_MESSAGE("Starting testRegister1...");
+
     UserPtr user = sdk.MakeNewUser("testUser");
+
     Status s = sdk.StartRegistration(user);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
 
-    BOOST_CHECK(s == Status::OK);
-    BOOST_CHECK(user->GetState() == User::ACTIVATED);
+    s = sdk.ConfirmRegistration(user);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
 
-    context.SetPin("1234");
-
-    s = sdk.FinishRegistration(user);
-    BOOST_CHECK(s == Status::OK);
+    s = sdk.FinishRegistration(user, "1234");
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
 
     sdk.DeleteUser(user);
+
+    BOOST_MESSAGE("    testRegister1 finished");
 }
 
 BOOST_AUTO_TEST_CASE(testRegister2)
 {
-    UserPtr user = sdk.MakeNewUser("testUser");
-    Status s = sdk.StartRegistration(user);
+    BOOST_MESSAGE("Starting testRegister2...");
 
-    BOOST_CHECK(s == Status::OK);
-    BOOST_CHECK(user->GetState() == User::ACTIVATED);
+    UserPtr user = sdk.MakeNewUser("testUser");
+
+    Status s = sdk.StartRegistration(user);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
 
     s = sdk.RestartRegistration(user);
-    BOOST_CHECK(s == Status::FLOW_ERROR);
-    BOOST_CHECK(user->GetState() == User::ACTIVATED);
+    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
+    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
 
     sdk.DeleteUser(user);
+
+    BOOST_MESSAGE("    testRegister2 finished");
 }
 
 BOOST_AUTO_TEST_CASE(testRegister3)
 {
+    BOOST_MESSAGE("Starting testRegister3...");
+
     UserPtr user = sdk.MakeNewUser("");
+
     Status s = sdk.StartRegistration(user);
+    BOOST_CHECK_EQUAL(s, Status::HTTP_REQUEST_ERROR);
+    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
 
-    BOOST_CHECK(s == Status::HTTP_REQUEST_ERROR);
-    BOOST_CHECK(user->GetState() == User::INVALID);
-
-    s = sdk.FinishRegistration(user);
-    BOOST_CHECK(s == Status::FLOW_ERROR);
+    s = sdk.FinishRegistration(user, "");
+    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
+    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
 
     sdk.DeleteUser(user);
+
+    BOOST_MESSAGE("    testRegister3 finished");
 }
 
 BOOST_AUTO_TEST_CASE(testRegister4)
 {
+    BOOST_MESSAGE("Starting testRegister4...");
+
     UserPtr user = sdk.MakeNewUser("testUser");
+
     Status s = sdk.StartRegistration(user);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
 
-    BOOST_CHECK(s == Status::OK);
-    BOOST_CHECK(user->GetState() == User::ACTIVATED);
+    s = sdk.ConfirmRegistration(user);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
 
-    context.SetPin("");
-
-    s = sdk.FinishRegistration(user);
-    BOOST_CHECK(s == Status::PIN_INPUT_CANCELED);
-    BOOST_CHECK(user->GetState() == User::ACTIVATED);
+    s = sdk.FinishRegistration(user, "");
+    BOOST_CHECK_EQUAL(s, Status::PIN_INPUT_CANCELED);
+    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
 
     sdk.DeleteUser(user);
+
+    BOOST_MESSAGE("    testRegister4 finished");
 }
 
 BOOST_AUTO_TEST_CASE(testAuthenticate1)
 {
+    BOOST_MESSAGE("Starting testAuthenticate1...");
+
     UserPtr user = sdk.MakeNewUser("testUser");
+
     Status s = sdk.StartRegistration(user);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
 
-    BOOST_CHECK(s == Status::OK);
-    BOOST_CHECK(user->GetState() == User::ACTIVATED);
+    s = sdk.ConfirmRegistration(user);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
 
-    context.SetPin("1234");
+    s = sdk.FinishRegistration(user, "1234");
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
 
-    s = sdk.FinishRegistration(user);
-    BOOST_CHECK(s == Status::OK);
+    s = sdk.StartAuthentication(user);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
 
-    s = sdk.Authenticate(user);
-    BOOST_CHECK(s == Status::OK);
+    s = sdk.FinishAuthentication(user, "1234");
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
 
     String authData;
-    s = sdk.Authenticate(user, authData);
-    BOOST_CHECK(s == Status::OK);
+    //s = sdk.StartAuthentication(user);
+    s = sdk.FinishAuthentication(user, "1234", authData);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
 
-    context.SetPin("1235");
-    s = sdk.Authenticate(user);
-    BOOST_CHECK(s == Status::INCORRECT_PIN);
+    //s = sdk.StartAuthentication(user);
+    s = sdk.FinishAuthentication(user, "1235");
+    BOOST_CHECK_EQUAL(s, Status::INCORRECT_PIN);
+    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
 
-    context.SetPin("1234");
-    s = sdk.Authenticate(user);
-    BOOST_CHECK(s == Status::OK);
+    //s = sdk.StartAuthentication(user);
+    s = sdk.FinishAuthentication(user, "1234");
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
 
     sdk.DeleteUser(user);
+
+    BOOST_MESSAGE("    testAuthenticate1 finished");
 }
 
 BOOST_AUTO_TEST_CASE(testAuthenticate2)
 {
+    BOOST_MESSAGE("Starting testAuthenticate2...");
+
     UserPtr user = sdk.MakeNewUser("testUser");
+
     Status s = sdk.StartRegistration(user);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
 
-    BOOST_CHECK(s == Status::OK);
-    BOOST_CHECK(user->GetState() == User::ACTIVATED);
+    s = sdk.ConfirmRegistration(user);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
 
-    context.SetPin("1234");
+    s = sdk.FinishRegistration(user, "1234");
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
 
-    s = sdk.FinishRegistration(user);
-    BOOST_CHECK(s == Status::OK);
+    s = sdk.StartAuthentication(user);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
 
-    context.SetPin("1111");
-    s = sdk.Authenticate(user);
-    BOOST_CHECK(s == Status::INCORRECT_PIN);
-    BOOST_CHECK(user->GetState() == User::REGISTERED);
-    s = sdk.Authenticate(user);
-    BOOST_CHECK(s == Status::INCORRECT_PIN);
-    BOOST_CHECK(user->GetState() == User::REGISTERED);
-    s = sdk.Authenticate(user);
-    BOOST_CHECK(s == Status::INCORRECT_PIN);
-    BOOST_CHECK(user->GetState() == User::BLOCKED);
+    s = sdk.FinishAuthentication(user, "1111");
+    BOOST_CHECK_EQUAL(s, Status::INCORRECT_PIN);
+    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
+
+    //s = sdk.StartAuthentication(user);
+    s = sdk.FinishAuthentication(user, "1111");
+    BOOST_CHECK_EQUAL(s, Status::INCORRECT_PIN);
+    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
+
+    //s = sdk.StartAuthentication(user);
+    s = sdk.FinishAuthentication(user, "1111");
+    BOOST_CHECK_EQUAL(s, Status::INCORRECT_PIN);
+    BOOST_CHECK_EQUAL(user->GetState(), User::BLOCKED);
 
     sdk.DeleteUser(user);
+
+    BOOST_MESSAGE("    testAuthenticate2 finished");
 }
 
 BOOST_AUTO_TEST_CASE(testAuthenticateOTP)
 {
+    BOOST_MESSAGE("Starting testAuthenticateOTP...");
+
     UserPtr user = sdk.MakeNewUser("testUser");
+
     Status s = sdk.StartRegistration(user);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
 
-    BOOST_CHECK(s == Status::OK);
-    BOOST_CHECK(user->GetState() == User::ACTIVATED);
+    s = sdk.ConfirmRegistration(user);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
 
-    context.SetPin("1234");
+    s = sdk.FinishRegistration(user, "1234");
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
 
-    s = sdk.FinishRegistration(user);
-    BOOST_CHECK(s == Status::OK);
+    s = sdk.StartAuthentication(user);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
 
     MPinSDK::OTP otp;
-    s = sdk.AuthenticateOTP(user, otp);
-    BOOST_CHECK(s == Status::OK);
-    BOOST_CHECK(user->GetState() == User::REGISTERED);
-    BOOST_CHECK(otp.status == Status::RESPONSE_PARSE_ERROR);
+    s = sdk.FinishAuthenticationOTP(user, "1234", otp);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
+    BOOST_CHECK_EQUAL(otp.status, Status::RESPONSE_PARSE_ERROR);
 
     sdk.DeleteUser(user);
+
+    BOOST_MESSAGE("    testAuthenticateOTP finished");
 }
 
 static AccessNumberThread g_accessNumberThread;
 
 BOOST_AUTO_TEST_CASE(testAuthenticateAN1)
 {
+    BOOST_MESSAGE("Starting testAuthenticateAN1...");
+
     // Register user
     UserPtr user = sdk.MakeNewUser("testUser");
+
     Status s = sdk.StartRegistration(user);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
 
-    BOOST_CHECK(s == Status::OK);
-    BOOST_CHECK(user->GetState() == User::ACTIVATED);
+    s = sdk.ConfirmRegistration(user);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
 
-    context.SetPin("1234");
-
-    s = sdk.FinishRegistration(user);
-    BOOST_CHECK(s == Status::OK);
+    s = sdk.FinishRegistration(user, "1234");
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
 
     // Request access number
     HttpRequest req;
@@ -353,14 +491,13 @@
 
     String url = String().Format("%s/rps/getAccessNumber", backend);
     bool res = req.Execute(MPinSDK::IHttpRequest::POST, url);
-
-    BOOST_CHECK(res == true);
-    BOOST_CHECK(req.GetHttpStatusCode() == 200);
+    BOOST_CHECK(res);
+    BOOST_CHECK_EQUAL(req.GetHttpStatusCode(), 200);
 
     String data = req.GetResponseData();
     util::JsonObject json;
     res = json.Parse(data.c_str());
-    BOOST_CHECK(res == true);
+    BOOST_CHECK(res);
 
     String accessNumber = json.GetStringParam("accessNumber");
     BOOST_CHECK(accessNumber.length() > 0);
@@ -369,29 +506,41 @@
     g_accessNumberThread.Start(backend, json.GetStringParam("webOTT"), sdk.GetClientParam("authenticateURL"));
 
     // Authenticate with access number
-    s = sdk.AuthenticateAN(user, accessNumber);
-    BOOST_CHECK(s == Status::OK);
+    s = sdk.StartAuthentication(user);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
+
+    s = sdk.FinishAuthenticationAN(user, "1234", accessNumber);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
 
     // The backend *must* support logout data
     BOOST_CHECK(sdk.CanLogout(user));
     BOOST_CHECK(sdk.Logout(user));
 
     sdk.DeleteUser(user);
+
+    BOOST_MESSAGE("    testAuthenticateAN1 finished");
 }
 
 BOOST_AUTO_TEST_CASE(testAuthenticateAN2)
 {
+    BOOST_MESSAGE("Starting testAuthenticateAN2...");
+
     // Register user
     UserPtr user = sdk.MakeNewUser("testUser");
+
     Status s = sdk.StartRegistration(user);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
 
-    BOOST_CHECK(s == Status::OK);
-    BOOST_CHECK(user->GetState() == User::ACTIVATED);
+    s = sdk.ConfirmRegistration(user);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
 
-    context.SetPin("1234");
-
-    s = sdk.FinishRegistration(user);
-    BOOST_CHECK(s == Status::OK);
+    s = sdk.FinishRegistration(user, "1234");
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
 
     // Request access number
     HttpRequest req;
@@ -402,14 +551,13 @@
 
     String url = String().Format("%s/rps/getAccessNumber", backend);
     bool res = req.Execute(MPinSDK::IHttpRequest::POST, url);
-
-    BOOST_CHECK(res == true);
-    BOOST_CHECK(req.GetHttpStatusCode() == 200);
+    BOOST_CHECK(res);
+    BOOST_CHECK_EQUAL(req.GetHttpStatusCode(), 200);
 
     String data = req.GetResponseData();
     util::JsonObject json;
     res = json.Parse(data.c_str());
-    BOOST_CHECK(res == true);
+    BOOST_CHECK(res);
 
     String accessNumber = json.GetStringParam("accessNumber");
     BOOST_CHECK(accessNumber.length() > 0);
@@ -426,24 +574,34 @@
     g_accessNumberThread.Start(backend, json.GetStringParam("webOTT"), sdk.GetClientParam("authenticateURL"));
 
     // Authenticate with access number
-    s = sdk.AuthenticateAN(user, accessNumber);
-    BOOST_CHECK(s == Status::INCORRECT_ACCESS_NUMBER);
+    s = sdk.StartAuthentication(user);
+    BOOST_CHECK_EQUAL(s, Status::OK);
+    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
+
+    s = sdk.FinishAuthenticationAN(user, "1234", accessNumber);
+    BOOST_CHECK_EQUAL(s, Status::INCORRECT_ACCESS_NUMBER);
+    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
 
     // The backend *must* support logout data
     BOOST_CHECK(!sdk.CanLogout(user));
 
     // Simulate wrong pin - must fail on access number validation too
-    context.SetPin("1233");
-    s = sdk.AuthenticateAN(user, accessNumber);
-    BOOST_CHECK(s == Status::INCORRECT_ACCESS_NUMBER);
+    //s = sdk.StartAuthentication(user);
+    s = sdk.FinishAuthenticationAN(user, "1233", accessNumber);
+    BOOST_CHECK_EQUAL(s, Status::INCORRECT_ACCESS_NUMBER);
+    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
 
     // Fix access number - must fail with incorrect pin already
     accessNumber = originalAccessNumber;
-    s = sdk.AuthenticateAN(user, accessNumber);
-    BOOST_CHECK(s == Status::INCORRECT_PIN);
+    //s = sdk.StartAuthentication(user);
+    s = sdk.FinishAuthenticationAN(user, "1233", accessNumber);
+    BOOST_CHECK_EQUAL(s, Status::INCORRECT_PIN);
+    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
 
     sdk.DeleteUser(user);
 
     // Wait the AccessNumberThread to complete
     CvShared::SleepFor(CvShared::Millisecs(AccessNumberThread::RETRY_INTERVAL_MILLISEC * AccessNumberThread::MAX_TRIES).Value());
+
+    BOOST_MESSAGE("    testAuthenticateAN2 finished");
 }
diff --git a/tests/unit_tests_v2.cpp b/tests/unit_tests_v2.cpp
deleted file mode 100644
index 3b6f6d9..0000000
--- a/tests/unit_tests_v2.cpp
+++ /dev/null
@@ -1,609 +0,0 @@
-/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
-#include "mpin_sdk_v2.h"
-#include "contexts/auto_context_v2.h"
-#include "common/http_request.h"
-#include "common/access_number_thread.h"
-#include "CvTime.h"
-#include "CvLogger.h"
-
-#define BOOST_TEST_MODULE Simple testcases
-#include "boost/test/included/unit_test.hpp"
-
-#include <ostream>
-
-typedef MPinSDKv2::User User;
-typedef MPinSDKv2::UserPtr UserPtr;
-typedef MPinSDKv2::Status Status;
-typedef MPinSDKv2::String String;
-
-static AutoContextV2 context;
-static MPinSDKv2 sdk;
-static MPinSDKv2::StringMap config;
-//static const char *backend = "http://ec2-54-77-232-113.eu-west-1.compute.amazonaws.com";
-static const char *backend = "http://ec2-52-28-120-46.eu-central-1.compute.amazonaws.com";
-
-using namespace boost::unit_test;
-
-std::ostream& operator<<(std::ostream& ostr, const Status& s)
-{
-    ostr << s.GetStatusCode();
-    return ostr;
-}
-
-BOOST_AUTO_TEST_CASE(testNoInit)
-{
-    unit_test_log.set_threshold_level(log_messages);
-
-    BOOST_MESSAGE("Starting testNoInit...");
-
-    CvShared::InitLogger("cvlog.txt", CvShared::enLogLevel_None);
-
-    int argc = framework::master_test_suite().argc;
-    if(argc > 1)
-    {
-        char **argv = framework::master_test_suite().argv;
-        backend = argv[1];
-    }
-
-    Status s = sdk.TestBackend("12354");
-    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
-
-    s = sdk.SetBackend("12354");
-    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
-
-    UserPtr user = sdk.MakeNewUser("testUser");
-
-    s = sdk.StartRegistration(user);
-    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
-    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
-
-    s = sdk.RestartRegistration(user);
-    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
-    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
-
-    s = sdk.VerifyUser(user, "", "");
-    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
-    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
-
-    s = sdk.ConfirmRegistration(user);
-    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
-    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
-
-    s = sdk.FinishRegistration(user, "");
-    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
-    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
-
-    s = sdk.StartAuthentication(user);
-    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
-    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
-
-    s = sdk.FinishAuthentication(user, "");
-    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
-    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
-
-    String authResultData;
-    s = sdk.FinishAuthentication(user, "", authResultData);
-    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
-    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
-
-    MPinSDKv2::OTP otp;
-    s = sdk.FinishAuthenticationOTP(user, "", otp);
-    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
-    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
-
-    s = sdk.FinishAuthenticationAN(user, "", "");
-    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
-    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
-
-    BOOST_MESSAGE("    testNoInit finished");
-}
-
-BOOST_AUTO_TEST_CASE(testInit)
-{
-    BOOST_MESSAGE("Starting testInit...");
-
-    config.Put(MPinSDK::CONFIG_BACKEND, backend);
-
-    Status s = sdk.Init(config, &context);
-
-    BOOST_CHECK_EQUAL(s, Status::OK);
-
-    BOOST_MESSAGE("    testInit finished");
-}
-
-BOOST_AUTO_TEST_CASE(testBackend)
-{
-    BOOST_MESSAGE("Starting testBackend...");
-
-    Status s = sdk.TestBackend("https://m-pindemo.certivox.org");
-    BOOST_CHECK_EQUAL(s, Status::OK);
-
-    s = sdk.TestBackend("https://blabla.certivox.org");
-    BOOST_CHECK_NE(s, Status::OK);
-
-    BOOST_MESSAGE("    testBackend finished");
-}
-
-BOOST_AUTO_TEST_CASE(setBackend)
-{
-    BOOST_MESSAGE("Starting setBackend...");
-
-    Status s = sdk.SetBackend("https://blabla.certivox.org");
-    BOOST_CHECK_NE(s, Status::OK);
-
-    s = sdk.SetBackend(backend);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-
-    BOOST_MESSAGE("    setBackend finished");
-}
-
-BOOST_AUTO_TEST_CASE(testUsers1)
-{
-    BOOST_MESSAGE("Starting testUsers1...");
-
-    UserPtr user = sdk.MakeNewUser("testUser");
-    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
-
-    Status s = sdk.StartRegistration(user);
-
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
-
-    sdk.DeleteUser(user);
-    std::vector<UserPtr> users;
-    sdk.ListUsers(users);
-    BOOST_CHECK(users.empty());
-
-    BOOST_MESSAGE("    testUsers1 finished");
-}
-
-BOOST_AUTO_TEST_CASE(testUsers2)
-{
-    BOOST_MESSAGE("Starting testUsers2...");
-
-    UserPtr user = sdk.MakeNewUser("testUser");
-    Status s = sdk.StartRegistration(user);
-
-    std::vector<UserPtr> users;
-    sdk.ListUsers(users);
-    BOOST_CHECK_EQUAL(users.size(), 1);
-
-    sdk.DeleteUser(user);
-
-    BOOST_MESSAGE("    testUsers2 finished");
-}
-
-BOOST_AUTO_TEST_CASE(testUsers3)
-{
-    BOOST_MESSAGE("Starting testUsers3...");
-
-    UserPtr user = sdk.MakeNewUser("testUser");
-
-    Status s = sdk.StartAuthentication(user);
-    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
-    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
-
-    s = sdk.FinishRegistration(user, "");
-    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
-    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
-
-    s = sdk.RestartRegistration(user);
-    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
-    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
-
-    BOOST_MESSAGE("    testUsers3 finished");
-}
-
-BOOST_AUTO_TEST_CASE(testUsers4)
-{
-    BOOST_MESSAGE("Starting testUsers4...");
-
-    int count = 10;
-    for(int i = 0; i < count; ++i)
-    {
-        String id;
-        id.Format("testUser%03d", i);
-        UserPtr user = sdk.MakeNewUser(id);
-
-        Status s = sdk.StartRegistration(user);
-        BOOST_CHECK_EQUAL(s, Status::OK);
-        BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
-    }
-
-    std::vector<UserPtr> users;
-    sdk.ListUsers(users);
-    BOOST_CHECK_EQUAL(users.size(), count);
-
-    for(std::vector<UserPtr>::iterator i = users.begin(); i != users.end(); ++i)
-    {
-        UserPtr user = *i;
-        sdk.DeleteUser(user);
-    }
-
-    sdk.ListUsers(users);
-    BOOST_CHECK(users.empty());
-
-    BOOST_MESSAGE("    testUsers4 finished");
-}
-
-BOOST_AUTO_TEST_CASE(testUsers5)
-{
-    BOOST_MESSAGE("Starting testUsers5...");
-
-    UserPtr user = sdk.MakeNewUser("testUser");
-    sdk.StartRegistration(user);
-
-    BOOST_CHECK(!sdk.CanLogout(user));
-    BOOST_CHECK(!sdk.Logout(user));
-    sdk.DeleteUser(user);
-
-    BOOST_MESSAGE("    testUsers5 finished");
-}
-
-BOOST_AUTO_TEST_CASE(testRegister1)
-{
-    BOOST_MESSAGE("Starting testRegister1...");
-
-    UserPtr user = sdk.MakeNewUser("testUser");
-
-    Status s = sdk.StartRegistration(user);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
-
-    s = sdk.ConfirmRegistration(user);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
-
-    s = sdk.FinishRegistration(user, "1234");
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
-
-    sdk.DeleteUser(user);
-
-    BOOST_MESSAGE("    testRegister1 finished");
-}
-
-BOOST_AUTO_TEST_CASE(testRegister2)
-{
-    BOOST_MESSAGE("Starting testRegister2...");
-
-    UserPtr user = sdk.MakeNewUser("testUser");
-
-    Status s = sdk.StartRegistration(user);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
-
-    s = sdk.RestartRegistration(user);
-    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
-    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
-
-    sdk.DeleteUser(user);
-
-    BOOST_MESSAGE("    testRegister2 finished");
-}
-
-BOOST_AUTO_TEST_CASE(testRegister3)
-{
-    BOOST_MESSAGE("Starting testRegister3...");
-
-    UserPtr user = sdk.MakeNewUser("");
-
-    Status s = sdk.StartRegistration(user);
-    BOOST_CHECK_EQUAL(s, Status::HTTP_REQUEST_ERROR);
-    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
-
-    s = sdk.FinishRegistration(user, "");
-    BOOST_CHECK_EQUAL(s, Status::FLOW_ERROR);
-    BOOST_CHECK_EQUAL(user->GetState(), User::INVALID);
-
-    sdk.DeleteUser(user);
-
-    BOOST_MESSAGE("    testRegister3 finished");
-}
-
-BOOST_AUTO_TEST_CASE(testRegister4)
-{
-    BOOST_MESSAGE("Starting testRegister4...");
-
-    UserPtr user = sdk.MakeNewUser("testUser");
-
-    Status s = sdk.StartRegistration(user);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
-
-    s = sdk.ConfirmRegistration(user);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
-
-    s = sdk.FinishRegistration(user, "");
-    BOOST_CHECK_EQUAL(s, Status::PIN_INPUT_CANCELED);
-    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
-
-    sdk.DeleteUser(user);
-
-    BOOST_MESSAGE("    testRegister4 finished");
-}
-
-BOOST_AUTO_TEST_CASE(testAuthenticate1)
-{
-    BOOST_MESSAGE("Starting testAuthenticate1...");
-
-    UserPtr user = sdk.MakeNewUser("testUser");
-
-    Status s = sdk.StartRegistration(user);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
-
-    s = sdk.ConfirmRegistration(user);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
-
-    s = sdk.FinishRegistration(user, "1234");
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
-
-    s = sdk.StartAuthentication(user);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
-
-    s = sdk.FinishAuthentication(user, "1234");
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
-
-    String authData;
-    //s = sdk.StartAuthentication(user);
-    s = sdk.FinishAuthentication(user, "1234", authData);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
-
-    //s = sdk.StartAuthentication(user);
-    s = sdk.FinishAuthentication(user, "1235");
-    BOOST_CHECK_EQUAL(s, Status::INCORRECT_PIN);
-    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
-
-    //s = sdk.StartAuthentication(user);
-    s = sdk.FinishAuthentication(user, "1234");
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
-
-    sdk.DeleteUser(user);
-
-    BOOST_MESSAGE("    testAuthenticate1 finished");
-}
-
-BOOST_AUTO_TEST_CASE(testAuthenticate2)
-{
-    BOOST_MESSAGE("Starting testAuthenticate2...");
-
-    UserPtr user = sdk.MakeNewUser("testUser");
-
-    Status s = sdk.StartRegistration(user);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
-
-    s = sdk.ConfirmRegistration(user);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
-
-    s = sdk.FinishRegistration(user, "1234");
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
-
-    s = sdk.StartAuthentication(user);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
-
-    s = sdk.FinishAuthentication(user, "1111");
-    BOOST_CHECK_EQUAL(s, Status::INCORRECT_PIN);
-    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
-
-    //s = sdk.StartAuthentication(user);
-    s = sdk.FinishAuthentication(user, "1111");
-    BOOST_CHECK_EQUAL(s, Status::INCORRECT_PIN);
-    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
-
-    //s = sdk.StartAuthentication(user);
-    s = sdk.FinishAuthentication(user, "1111");
-    BOOST_CHECK_EQUAL(s, Status::INCORRECT_PIN);
-    BOOST_CHECK_EQUAL(user->GetState(), User::BLOCKED);
-
-    sdk.DeleteUser(user);
-
-    BOOST_MESSAGE("    testAuthenticate2 finished");
-}
-
-BOOST_AUTO_TEST_CASE(testAuthenticateOTP)
-{
-    BOOST_MESSAGE("Starting testAuthenticateOTP...");
-
-    UserPtr user = sdk.MakeNewUser("testUser");
-
-    Status s = sdk.StartRegistration(user);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
-
-    s = sdk.ConfirmRegistration(user);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
-
-    s = sdk.FinishRegistration(user, "1234");
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
-
-    s = sdk.StartAuthentication(user);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
-
-    MPinSDKv2::OTP otp;
-    s = sdk.FinishAuthenticationOTP(user, "1234", otp);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
-    BOOST_CHECK_EQUAL(otp.status, Status::RESPONSE_PARSE_ERROR);
-
-    sdk.DeleteUser(user);
-
-    BOOST_MESSAGE("    testAuthenticateOTP finished");
-}
-
-static AccessNumberThread g_accessNumberThread;
-
-BOOST_AUTO_TEST_CASE(testAuthenticateAN1)
-{
-    BOOST_MESSAGE("Starting testAuthenticateAN1...");
-
-    // Register user
-    UserPtr user = sdk.MakeNewUser("testUser");
-
-    Status s = sdk.StartRegistration(user);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
-
-    s = sdk.ConfirmRegistration(user);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
-
-    s = sdk.FinishRegistration(user, "1234");
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
-
-    // Request access number
-    HttpRequest req;
-    HttpRequest::StringMap headers;
-    headers.Put("Content-Type", "application/json");
-    headers.Put("Accept", "*/*");
-    req.SetHeaders(headers);
-
-    String url = String().Format("%s/rps/getAccessNumber", backend);
-    bool res = req.Execute(MPinSDK::IHttpRequest::POST, url);
-    BOOST_CHECK(res);
-    BOOST_CHECK_EQUAL(req.GetHttpStatusCode(), 200);
-
-    String data = req.GetResponseData();
-    util::JsonObject json;
-    res = json.Parse(data.c_str());
-    BOOST_CHECK(res);
-
-    String accessNumber = json.GetStringParam("accessNumber");
-    BOOST_CHECK(accessNumber.length() > 0);
-
-    // Start access number thread
-    g_accessNumberThread.Start(backend, json.GetStringParam("webOTT"), sdk.GetClientParam("authenticateURL"));
-
-    // Authenticate with access number
-    s = sdk.StartAuthentication(user);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
-
-    s = sdk.FinishAuthenticationAN(user, "1234", accessNumber);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
-
-    // The backend *must* support logout data
-    BOOST_CHECK(sdk.CanLogout(user));
-    BOOST_CHECK(sdk.Logout(user));
-
-    sdk.DeleteUser(user);
-
-    BOOST_MESSAGE("    testAuthenticateAN1 finished");
-}
-
-BOOST_AUTO_TEST_CASE(testAuthenticateAN2)
-{
-    BOOST_MESSAGE("Starting testAuthenticateAN2...");
-
-    // Register user
-    UserPtr user = sdk.MakeNewUser("testUser");
-
-    Status s = sdk.StartRegistration(user);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
-
-    s = sdk.ConfirmRegistration(user);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::ACTIVATED);
-
-    s = sdk.FinishRegistration(user, "1234");
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
-
-    // Request access number
-    HttpRequest req;
-    HttpRequest::StringMap headers;
-    headers.Put("Content-Type", "application/json");
-    headers.Put("Accept", "*/*");
-    req.SetHeaders(headers);
-
-    String url = String().Format("%s/rps/getAccessNumber", backend);
-    bool res = req.Execute(MPinSDK::IHttpRequest::POST, url);
-    BOOST_CHECK(res);
-    BOOST_CHECK_EQUAL(req.GetHttpStatusCode(), 200);
-
-    String data = req.GetResponseData();
-    util::JsonObject json;
-    res = json.Parse(data.c_str());
-    BOOST_CHECK(res);
-
-    String accessNumber = json.GetStringParam("accessNumber");
-    BOOST_CHECK(accessNumber.length() > 0);
-
-    // Simulate wrong access number
-    String originalAccessNumber = accessNumber;
-    accessNumber[3] += (char) 1;
-    if(accessNumber[3] > '9')
-    {
-        accessNumber[3] = '0';
-    }
-
-    // Start access number thread
-    g_accessNumberThread.Start(backend, json.GetStringParam("webOTT"), sdk.GetClientParam("authenticateURL"));
-
-    // Authenticate with access number
-    s = sdk.StartAuthentication(user);
-    BOOST_CHECK_EQUAL(s, Status::OK);
-    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
-
-    s = sdk.FinishAuthenticationAN(user, "1234", accessNumber);
-    BOOST_CHECK_EQUAL(s, Status::INCORRECT_ACCESS_NUMBER);
-    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
-
-    // The backend *must* support logout data
-    BOOST_CHECK(!sdk.CanLogout(user));
-
-    // Simulate wrong pin - must fail on access number validation too
-    //s = sdk.StartAuthentication(user);
-    s = sdk.FinishAuthenticationAN(user, "1233", accessNumber);
-    BOOST_CHECK_EQUAL(s, Status::INCORRECT_ACCESS_NUMBER);
-    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
-
-    // Fix access number - must fail with incorrect pin already
-    accessNumber = originalAccessNumber;
-    //s = sdk.StartAuthentication(user);
-    s = sdk.FinishAuthenticationAN(user, "1233", accessNumber);
-    BOOST_CHECK_EQUAL(s, Status::INCORRECT_PIN);
-    BOOST_CHECK_EQUAL(user->GetState(), User::REGISTERED);
-
-    sdk.DeleteUser(user);
-
-    // Wait the AccessNumberThread to complete
-    CvShared::SleepFor(CvShared::Millisecs(AccessNumberThread::RETRY_INTERVAL_MILLISEC * AccessNumberThread::MAX_TRIES).Value());
-
-    BOOST_MESSAGE("    testAuthenticateAN2 finished");
-}