changeset 1569:546ec0531099

removing deprecated files, backup is available in tag legacy-with-deprecated
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 21 Sep 2020 14:50:07 +0200
parents 37d90bd69f31
children 9a04f42098a3
files OrthancStone/Resources/CMake/OrthancStoneConfiguration.cmake OrthancStone/Resources/CMake/OrthancStoneParameters.cmake OrthancStone/Resources/Graveyard/Deprecated/Applications/Commands/BaseCommands.yml OrthancStone/Resources/Graveyard/Deprecated/Applications/Generic/NativeStoneApplicationContext.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Generic/NativeStoneApplicationContext.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Generic/NativeStoneApplicationRunner.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Generic/NativeStoneApplicationRunner.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Generic/Scene2DInteractor.h OrthancStone/Resources/Graveyard/Deprecated/Applications/IStoneApplication.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Qt/QCairoWidget.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Qt/QCairoWidget.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Qt/QStoneMainWindow.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Qt/QStoneMainWindow.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Qt/QtStoneApplicationRunner.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Qt/QtStoneApplicationRunner.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/BasicPetCtFusionApplication.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/CMakeLists.txt OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/CMakeLists.txt.old OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/EmptyApplication.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/LayoutPetCtFusionApplication.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Qt/SampleMainWindow.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Qt/SampleMainWindow.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Qt/SampleMainWindow.ui OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Qt/SampleMainWindowWithButtons.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Qt/SampleMainWindowWithButtons.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Qt/SampleMainWindowWithButtons.ui OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Qt/SampleQtApplicationRunner.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SampleApplicationBase.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SampleInteractor.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SampleList.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SampleMainNative.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SampleMainWasm.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Samples-status.md OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/AppStatus.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/MainWidgetInteractor.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/MainWidgetInteractor.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/Qt/SimpleViewerMainWindow.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/Qt/SimpleViewerMainWindow.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/Qt/SimpleViewerMainWindow.ui OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/Qt/mainQt.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/SimpleViewerApplication.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/SimpleViewerApplication.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/ThumbnailInteractor.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/ThumbnailInteractor.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/Wasm/SimpleViewerWasmApplicationAdapter.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/Wasm/SimpleViewerWasmApplicationAdapter.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/Wasm/mainWasm.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/Wasm/simple-viewer.html OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/Wasm/simple-viewer.ts OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/Wasm/styles.css OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/Wasm/tsconfig-simple-viewer.json OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewerApplicationSingleFile.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SingleFrameApplication.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SingleFrameEditorApplication.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SingleVolumeApplication.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/StoneSampleCommands.yml OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/StoneSampleCommands_generate.py OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/StoneSampleCommands_generated.hpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/StoneSampleCommands_generated.ts OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SynchronizedSeriesApplication.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/TestPatternApplication.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/index.html OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/samples-styles.css OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/simple-viewer-single-file.html OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/simple-viewer-single-file.ts OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/simple-viewer-single-file.tsconfig.json OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/single-frame-editor.html OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/single-frame-editor.ts OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/single-frame-editor.tsconfig.json OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/single-frame.html OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/single-frame.ts OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/single-frame.tsconfig.json OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/tsconfig-samples.json OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/build-wasm.sh OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/build-wasm.sh.old OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/build-web-ext.sh OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/build-web.sh OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/get-requirements-windows.ps1 OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/nginx.local.conf OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/package-lock.json OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/CMakeLists.txt OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/build-sdl-msvc15.ps1 OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/build-wasm.sh OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/build-web.sh OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/index.html OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/main.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/nginx.local.conf OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/rt-viewer-demo.html OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/rt-viewer-demo.ts OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/rt-viewer-demo.tsconfig.json OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/samples-styles.css OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/start-serving-files.sh OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/stop-serving-files.sh OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/tsconfig-samples.json OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/tsconfig-stone.json OrthancStone/Resources/Graveyard/Deprecated/Applications/Sdl/SdlCairoSurface.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Sdl/SdlCairoSurface.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Sdl/SdlEngine.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Sdl/SdlEngine.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Sdl/SdlOrthancSurface.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Sdl/SdlOrthancSurface.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Sdl/SdlStoneApplicationRunner.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Sdl/SdlStoneApplicationRunner.h OrthancStone/Resources/Graveyard/Deprecated/Applications/StoneApplicationContext.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/StoneApplicationContext.h OrthancStone/Resources/Graveyard/Deprecated/Applications/Wasm/StartupParametersBuilder.cpp OrthancStone/Resources/Graveyard/Deprecated/Applications/Wasm/StartupParametersBuilder.h OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/DelayedCallCommand.cpp OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/DelayedCallCommand.h OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/IOracleCommand.h OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/Oracle.cpp OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/Oracle.h OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/OracleDelayedCallExecutor.h OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/OracleWebService.cpp OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/OracleWebService.h OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/WebServiceCommandBase.cpp OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/WebServiceCommandBase.h OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/WebServiceDeleteCommand.cpp OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/WebServiceDeleteCommand.h OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/WebServiceGetCommand.cpp OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/WebServiceGetCommand.h OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/WebServicePostCommand.cpp OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/WebServicePostCommand.h OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/Defaults.cpp OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/Defaults.h OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/WasmDelayedCallExecutor.cpp OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/WasmDelayedCallExecutor.h OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/WasmDelayedCallExecutor.js OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/WasmPlatformApplicationAdapter.cpp OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/WasmPlatformApplicationAdapter.h OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/WasmViewport.cpp OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/WasmViewport.h OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/WasmWebService.cpp OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/WasmWebService.h OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/WasmWebService.js OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/default-library.js OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/logger.ts OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/stone-framework-loader.ts OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/tsconfig-stone.json OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/wasm-application-runner.ts OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/wasm-viewport.ts OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/Graveyard/playground.ts OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/Graveyard/playground2.ts OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/Graveyard/playground3.ts OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/Graveyard/playground4.py OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/Graveyard/runts.ps1 OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/Graveyard/test_stonegen.html OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/Graveyard/test_stonegen.ts OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/Graveyard/tsconfig.json OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/README.md OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/stonegentool.py OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/stonegentool_test.py OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/template.in.h.j2 OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/template.in.ts.j2 OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testCppHandler/CMakeLists.txt OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testCppHandler/README.md OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testCppHandler/conanfile.txt OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testCppHandler/main.cpp OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testCppHandler/test_data/test_Message2.json OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/CMakeLists.txt OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/DefaultLibrary.js OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/build-web.sh OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/build.sh OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/jsoncpp-1.8.4/json/json-forwards.h OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/jsoncpp-1.8.4/json/json.h OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/jsoncpp-1.8.4/jsoncpp.cpp OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/main.cpp OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/serve.py OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/styles.css OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/testWasmIntegrated.html OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/testWasmIntegrated.ts OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/test_data/test2.yaml OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/test_data/testTestStoneCodeGen.yaml OrthancStone/Resources/Graveyard/Deprecated/Samples/MultiPlatform/BasicScene/BasicScene.cpp OrthancStone/Resources/Graveyard/Deprecated/Samples/MultiPlatform/BasicScene/BasicScene.h OrthancStone/Resources/Graveyard/Deprecated/Samples/MultiPlatform/BasicScene/mainQt.cpp OrthancStone/Resources/Graveyard/Deprecated/Samples/MultiPlatform/BasicScene/mainSdl.cpp OrthancStone/Resources/Graveyard/Deprecated/Samples/Qt/BasicSceneWindow.cpp OrthancStone/Resources/Graveyard/Deprecated/Samples/Qt/BasicSceneWindow.h OrthancStone/Resources/Graveyard/Deprecated/Samples/Qt/BasicSceneWindow.ui OrthancStone/Resources/Graveyard/Deprecated/Samples/Qt/CMakeLists.txt OrthancStone/Resources/Graveyard/Deprecated/Samples/Qt/QStoneOpenGlWidget.cpp OrthancStone/Resources/Graveyard/Deprecated/Samples/Qt/QStoneOpenGlWidget.h OrthancStone/Resources/Graveyard/Deprecated/Samples/Qt/Scene2DInteractor.cpp OrthancStone/Resources/Graveyard/Deprecated/Samples/Qt/Scene2DInteractor.h OrthancStone/Resources/Graveyard/Deprecated/Samples/README.md OrthancStone/Resources/Graveyard/Deprecated/Samples/Sdl/BasicScene.cpp OrthancStone/Resources/Graveyard/Deprecated/Samples/Sdl/CMakeLists.txt OrthancStone/Resources/Graveyard/Deprecated/Samples/Sdl/FusionMprSdl.cpp OrthancStone/Resources/Graveyard/Deprecated/Samples/Sdl/FusionMprSdl.h OrthancStone/Resources/Graveyard/Deprecated/Samples/Sdl/Loader.cpp OrthancStone/Resources/Graveyard/Deprecated/Samples/Sdl/RadiographyEditor.cpp OrthancStone/Resources/Graveyard/Deprecated/Samples/Sdl/TrackerSample.cpp OrthancStone/Resources/Graveyard/Deprecated/Samples/Sdl/TrackerSampleApp.cpp OrthancStone/Resources/Graveyard/Deprecated/Samples/Sdl/TrackerSampleApp.h OrthancStone/Resources/Graveyard/Deprecated/Samples/Sdl/cpp.hint OrthancStone/Resources/Graveyard/Deprecated/Samples/WebAssembly/BasicMPR.cpp OrthancStone/Resources/Graveyard/Deprecated/Samples/WebAssembly/BasicMPR.html OrthancStone/Resources/Graveyard/Deprecated/Samples/WebAssembly/BasicScene.cpp OrthancStone/Resources/Graveyard/Deprecated/Samples/WebAssembly/BasicScene.html OrthancStone/Resources/Graveyard/Deprecated/Samples/WebAssembly/CMakeLists.txt OrthancStone/Resources/Graveyard/Deprecated/Samples/WebAssembly/Configuration.json OrthancStone/Resources/Graveyard/Deprecated/Samples/WebAssembly/ConfigurationLocalSJO.json OrthancStone/Resources/Graveyard/Deprecated/Samples/WebAssembly/NOTES.txt OrthancStone/Resources/Graveyard/Deprecated/Samples/WebAssembly/app.js OrthancStone/Resources/Graveyard/Deprecated/Samples/WebAssembly/dev.h OrthancStone/Resources/Graveyard/Deprecated/Samples/WebAssembly/index.html OrthancStone/Sources/Deprecated/GuiAdapter.cpp OrthancStone/Sources/Deprecated/GuiAdapter.h OrthancStone/Sources/Deprecated/Layers/CircleMeasureTracker.cpp OrthancStone/Sources/Deprecated/Layers/CircleMeasureTracker.h OrthancStone/Sources/Deprecated/Layers/ColorFrameRenderer.cpp OrthancStone/Sources/Deprecated/Layers/ColorFrameRenderer.h OrthancStone/Sources/Deprecated/Layers/DicomSeriesVolumeSlicer.cpp OrthancStone/Sources/Deprecated/Layers/DicomSeriesVolumeSlicer.h OrthancStone/Sources/Deprecated/Layers/DicomStructureSetSlicer.cpp OrthancStone/Sources/Deprecated/Layers/DicomStructureSetSlicer.h OrthancStone/Sources/Deprecated/Layers/FrameRenderer.cpp OrthancStone/Sources/Deprecated/Layers/FrameRenderer.h OrthancStone/Sources/Deprecated/Layers/GrayscaleFrameRenderer.cpp OrthancStone/Sources/Deprecated/Layers/GrayscaleFrameRenderer.h OrthancStone/Sources/Deprecated/Layers/ILayerRenderer.h OrthancStone/Sources/Deprecated/Layers/IVolumeSlicer.h OrthancStone/Sources/Deprecated/Layers/LineLayerRenderer.cpp OrthancStone/Sources/Deprecated/Layers/LineLayerRenderer.h OrthancStone/Sources/Deprecated/Layers/LineMeasureTracker.cpp OrthancStone/Sources/Deprecated/Layers/LineMeasureTracker.h OrthancStone/Sources/Deprecated/Layers/RenderStyle.cpp OrthancStone/Sources/Deprecated/Layers/RenderStyle.h OrthancStone/Sources/Deprecated/Layers/SeriesFrameRendererFactory.cpp OrthancStone/Sources/Deprecated/Layers/SeriesFrameRendererFactory.h OrthancStone/Sources/Deprecated/Layers/SingleFrameRendererFactory.cpp OrthancStone/Sources/Deprecated/Layers/SingleFrameRendererFactory.h OrthancStone/Sources/Deprecated/Layers/SliceOutlineRenderer.cpp OrthancStone/Sources/Deprecated/Layers/SliceOutlineRenderer.h OrthancStone/Sources/Deprecated/Loaders/DicomStructureSetLoader2.cpp OrthancStone/Sources/Deprecated/Loaders/DicomStructureSetLoader2.h OrthancStone/Sources/Deprecated/Messages/LockingEmitter.cpp OrthancStone/Sources/Deprecated/Messages/LockingEmitter.h OrthancStone/Sources/Deprecated/Radiography/RadiographyAlphaLayer.cpp OrthancStone/Sources/Deprecated/Radiography/RadiographyAlphaLayer.h OrthancStone/Sources/Deprecated/Radiography/RadiographyDicomLayer.cpp OrthancStone/Sources/Deprecated/Radiography/RadiographyDicomLayer.h OrthancStone/Sources/Deprecated/Radiography/RadiographyLayer.cpp OrthancStone/Sources/Deprecated/Radiography/RadiographyLayer.h OrthancStone/Sources/Deprecated/Radiography/RadiographyLayerCropTracker.cpp OrthancStone/Sources/Deprecated/Radiography/RadiographyLayerCropTracker.h OrthancStone/Sources/Deprecated/Radiography/RadiographyLayerMaskTracker.cpp OrthancStone/Sources/Deprecated/Radiography/RadiographyLayerMaskTracker.h OrthancStone/Sources/Deprecated/Radiography/RadiographyLayerMoveTracker.cpp OrthancStone/Sources/Deprecated/Radiography/RadiographyLayerMoveTracker.h OrthancStone/Sources/Deprecated/Radiography/RadiographyLayerResizeTracker.cpp OrthancStone/Sources/Deprecated/Radiography/RadiographyLayerResizeTracker.h OrthancStone/Sources/Deprecated/Radiography/RadiographyLayerRotateTracker.cpp OrthancStone/Sources/Deprecated/Radiography/RadiographyLayerRotateTracker.h OrthancStone/Sources/Deprecated/Radiography/RadiographyMaskLayer.cpp OrthancStone/Sources/Deprecated/Radiography/RadiographyMaskLayer.h OrthancStone/Sources/Deprecated/Radiography/RadiographyScene.cpp OrthancStone/Sources/Deprecated/Radiography/RadiographyScene.h OrthancStone/Sources/Deprecated/Radiography/RadiographySceneCommand.cpp OrthancStone/Sources/Deprecated/Radiography/RadiographySceneCommand.h OrthancStone/Sources/Deprecated/Radiography/RadiographySceneReader.cpp OrthancStone/Sources/Deprecated/Radiography/RadiographySceneReader.h OrthancStone/Sources/Deprecated/Radiography/RadiographySceneWriter.cpp OrthancStone/Sources/Deprecated/Radiography/RadiographySceneWriter.h OrthancStone/Sources/Deprecated/Radiography/RadiographyTextLayer.cpp OrthancStone/Sources/Deprecated/Radiography/RadiographyTextLayer.h OrthancStone/Sources/Deprecated/Radiography/RadiographyWidget.cpp OrthancStone/Sources/Deprecated/Radiography/RadiographyWidget.h OrthancStone/Sources/Deprecated/Radiography/RadiographyWindowingTracker.cpp OrthancStone/Sources/Deprecated/Radiography/RadiographyWindowingTracker.h OrthancStone/Sources/Deprecated/SmartLoader.cpp OrthancStone/Sources/Deprecated/SmartLoader.h OrthancStone/Sources/Deprecated/Toolbox/BaseWebService.cpp OrthancStone/Sources/Deprecated/Toolbox/BaseWebService.h OrthancStone/Sources/Deprecated/Toolbox/DicomFrameConverter.cpp OrthancStone/Sources/Deprecated/Toolbox/DicomFrameConverter.h OrthancStone/Sources/Deprecated/Toolbox/DownloadStack.cpp OrthancStone/Sources/Deprecated/Toolbox/DownloadStack.h OrthancStone/Sources/Deprecated/Toolbox/IDelayedCallExecutor.h OrthancStone/Sources/Deprecated/Toolbox/ISeriesLoader.h OrthancStone/Sources/Deprecated/Toolbox/IWebService.cpp OrthancStone/Sources/Deprecated/Toolbox/IWebService.h OrthancStone/Sources/Deprecated/Toolbox/MessagingToolbox.cpp OrthancStone/Sources/Deprecated/Toolbox/MessagingToolbox.h OrthancStone/Sources/Deprecated/Toolbox/OrthancApiClient.cpp OrthancStone/Sources/Deprecated/Toolbox/OrthancApiClient.h OrthancStone/Sources/Deprecated/Toolbox/OrthancSlicesLoader.cpp OrthancStone/Sources/Deprecated/Toolbox/OrthancSlicesLoader.h OrthancStone/Sources/Deprecated/Toolbox/ParallelSlices.cpp OrthancStone/Sources/Deprecated/Toolbox/ParallelSlices.h OrthancStone/Sources/Deprecated/Toolbox/ParallelSlicesCursor.cpp OrthancStone/Sources/Deprecated/Toolbox/ParallelSlicesCursor.h OrthancStone/Sources/Deprecated/Toolbox/Slice.cpp OrthancStone/Sources/Deprecated/Toolbox/Slice.h OrthancStone/Sources/Deprecated/Toolbox/ViewportGeometry.cpp OrthancStone/Sources/Deprecated/Toolbox/ViewportGeometry.h OrthancStone/Sources/Deprecated/Viewport/CairoFont.cpp OrthancStone/Sources/Deprecated/Viewport/CairoFont.h OrthancStone/Sources/Deprecated/Viewport/IMouseTracker.h OrthancStone/Sources/Deprecated/Viewport/IStatusBar.h OrthancStone/Sources/Deprecated/Viewport/IViewport.h OrthancStone/Sources/Deprecated/Viewport/WidgetViewport.cpp OrthancStone/Sources/Deprecated/Viewport/WidgetViewport.h OrthancStone/Sources/Deprecated/Volumes/ISlicedVolume.h OrthancStone/Sources/Deprecated/Volumes/IVolumeLoader.h OrthancStone/Sources/Deprecated/Volumes/StructureSetLoader.cpp OrthancStone/Sources/Deprecated/Volumes/StructureSetLoader.h OrthancStone/Sources/Deprecated/Widgets/CairoWidget.cpp OrthancStone/Sources/Deprecated/Widgets/CairoWidget.h OrthancStone/Sources/Deprecated/Widgets/EmptyWidget.cpp OrthancStone/Sources/Deprecated/Widgets/EmptyWidget.h OrthancStone/Sources/Deprecated/Widgets/IWidget.h OrthancStone/Sources/Deprecated/Widgets/IWorldSceneInteractor.h OrthancStone/Sources/Deprecated/Widgets/IWorldSceneMouseTracker.h OrthancStone/Sources/Deprecated/Widgets/LayoutWidget.cpp OrthancStone/Sources/Deprecated/Widgets/LayoutWidget.h OrthancStone/Sources/Deprecated/Widgets/PanMouseTracker.cpp OrthancStone/Sources/Deprecated/Widgets/PanMouseTracker.h OrthancStone/Sources/Deprecated/Widgets/PanZoomMouseTracker.cpp OrthancStone/Sources/Deprecated/Widgets/PanZoomMouseTracker.h OrthancStone/Sources/Deprecated/Widgets/SliceViewerWidget.cpp OrthancStone/Sources/Deprecated/Widgets/SliceViewerWidget.h OrthancStone/Sources/Deprecated/Widgets/TestCairoWidget.cpp OrthancStone/Sources/Deprecated/Widgets/TestCairoWidget.h OrthancStone/Sources/Deprecated/Widgets/TestWorldSceneWidget.cpp OrthancStone/Sources/Deprecated/Widgets/TestWorldSceneWidget.h OrthancStone/Sources/Deprecated/Widgets/WidgetBase.cpp OrthancStone/Sources/Deprecated/Widgets/WidgetBase.h OrthancStone/Sources/Deprecated/Widgets/WorldSceneWidget.cpp OrthancStone/Sources/Deprecated/Widgets/WorldSceneWidget.h OrthancStone/Sources/Deprecated/Widgets/ZoomMouseTracker.cpp OrthancStone/Sources/Deprecated/Widgets/ZoomMouseTracker.h OrthancStone/Sources/Deprecated/dev.h
diffstat 334 files changed, 0 insertions(+), 52491 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancStone/Resources/CMake/OrthancStoneConfiguration.cmake	Thu Sep 17 15:39:33 2020 +0200
+++ b/OrthancStone/Resources/CMake/OrthancStoneConfiguration.cmake	Mon Sep 21 14:50:07 2020 +0200
@@ -268,13 +268,6 @@
     )
 endif()
 
-if ((ENABLE_SDL OR ENABLE_WASM) AND ENABLE_GUIADAPTER)
-  list(APPEND APPLICATIONS_SOURCES
-    ${ORTHANC_STONE_ROOT}/Sources/Deprecated/GuiAdapter.cpp
-    ${ORTHANC_STONE_ROOT}/Sources/Deprecated/GuiAdapter.h
-    )
-endif()
-
 
 list(APPEND ORTHANC_STONE_SOURCES
   ${ORTHANC_STONE_ROOT}/Sources/Toolbox/OrthancDatasets/DicomDatasetReader.cpp
--- a/OrthancStone/Resources/CMake/OrthancStoneParameters.cmake	Thu Sep 17 15:39:33 2020 +0200
+++ b/OrthancStone/Resources/CMake/OrthancStoneParameters.cmake	Mon Sep 21 14:50:07 2020 +0200
@@ -90,4 +90,3 @@
 
 set(ENABLE_OPENGL ON CACHE BOOL "Enable support of OpenGL")
 set(ENABLE_WASM OFF CACHE INTERNAL "Enable support of WebAssembly")
-set(ENABLE_GUIADAPTER OFF CACHE INTERNAL "Enable backward compatibility with the Stone GuiAdapter class")
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Commands/BaseCommands.yml	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-SelectTool:
-  target: Application
-  toolName: string
-  comment: Selects the current application tool
-DownloadDicom:
-  target: SliceViewerWidget
-  comment: Downloads the slice currently displayed in the SliceViewerWidget
-Export:
-  target: IWidget
-  comment: Export the content of the widget
\ No newline at end of file
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Generic/NativeStoneApplicationContext.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "NativeStoneApplicationContext.h"
-#include "../../Platforms/Generic/OracleWebService.h"
-
-namespace OrthancStone
-{
-  void NativeStoneApplicationContext::GlobalMutexLocker::SetCentralWidget(
-    boost::shared_ptr<Deprecated::IWidget> widget)
-  {
-    that_.centralViewport_.SetCentralWidget(widget);
-  }
-
-
-  void NativeStoneApplicationContext::UpdateThread(NativeStoneApplicationContext* that)
-  {
-    while (!that->stopped_)
-    {
-      {
-        GlobalMutexLocker locker(*that);
-        locker.GetCentralViewport().DoAnimation();
-      }
-      
-      boost::this_thread::sleep(boost::posix_time::milliseconds(that->updateDelayInMs_));
-    }
-  }
-  
-
-  NativeStoneApplicationContext::NativeStoneApplicationContext() :
-    stopped_(true),
-    updateDelayInMs_(100)   // By default, 100ms between each refresh of the content
-  {
-    srand(static_cast<unsigned int>(time(NULL))); 
-  }
-
-
-  void NativeStoneApplicationContext::Start()
-  {
-    boost::recursive_mutex::scoped_lock lock(globalMutex_);
-    
-    if (stopped_ &&
-        centralViewport_.HasAnimation())
-    {
-      stopped_ = false;
-      updateThread_ = boost::thread(UpdateThread, this);
-    }
-  }
-
-
-  void NativeStoneApplicationContext::Stop()
-  {
-    stopped_ = true;
-    
-    if (updateThread_.joinable())
-    {
-      updateThread_.join();
-    }
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Generic/NativeStoneApplicationContext.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Framework/Deprecated/Viewport/WidgetViewport.h"
-#include "../../Framework/Deprecated/Volumes/ISlicedVolume.h"
-#include "../../Framework/Deprecated/Volumes/IVolumeLoader.h"
-
-#include <list>
-#include <boost/thread.hpp>
-#include "../StoneApplicationContext.h"
-
-namespace OrthancStone
-{
-  class NativeStoneApplicationContext : public StoneApplicationContext
-  {
-  private:
-    static void UpdateThread(NativeStoneApplicationContext* that);
-
-    boost::recursive_mutex    globalMutex_;
-    Deprecated::WidgetViewport  centralViewport_;
-    boost::thread   updateThread_;
-    bool            stopped_;
-    unsigned int    updateDelayInMs_;
-
-  public:
-    class GlobalMutexLocker: public boost::noncopyable
-    {
-    private:
-      NativeStoneApplicationContext&        that_;
-      boost::recursive_mutex::scoped_lock   lock_;
-      
-    public:
-      GlobalMutexLocker(NativeStoneApplicationContext& that) :
-        that_(that),
-        lock_(that.globalMutex_)
-      {
-      }
-
-      void SetCentralWidget(boost::shared_ptr<Deprecated::IWidget> widget);
-
-      Deprecated::IViewport& GetCentralViewport() 
-      {
-        return that_.centralViewport_;
-      }
-
-      void SetUpdateDelay(unsigned int delayInMs)
-      {
-        that_.updateDelayInMs_ = delayInMs;
-      }
-    };
-
-    NativeStoneApplicationContext();
-
-    void Start();
-
-    void Stop();
-  };
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Generic/NativeStoneApplicationRunner.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,265 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#if ORTHANC_ENABLE_THREADS != 1
-#error this file shall be included only with the ORTHANC_ENABLE_THREADS set to 1
-#endif
-
-#include "NativeStoneApplicationRunner.h"
-
-#include "../../Framework/Deprecated/Toolbox/MessagingToolbox.h"
-#include "../../Platforms/Generic/OracleWebService.h"
-#include "../../Platforms/Generic/OracleDelayedCallExecutor.h"
-#include "NativeStoneApplicationContext.h"
-
-#include <Core/Logging.h>
-#include <Core/HttpClient.h>
-#include <Core/Toolbox.h>
-#include <Core/OrthancException.h>
-#include <Plugins/Samples/Common/OrthancHttpConnection.h>
-
-#include <boost/program_options.hpp>
-
-namespace OrthancStone
-{
-  // Anonymous namespace to avoid clashes against other compilation modules
-  namespace
-  {
-    class LogStatusBar : public Deprecated::IStatusBar
-    {
-    public:
-      virtual void ClearMessage()
-      {
-      }
-
-      virtual void SetMessage(const std::string& message)
-      {
-        LOG(WARNING) << message;
-      }
-    };
-  }
-
-  int NativeStoneApplicationRunner::Execute(int argc,
-                                            char* argv[])
-  {
-    /******************************************************************
-     * Initialize all the subcomponents of Orthanc Stone
-     ******************************************************************/
-
-    Orthanc::Logging::Initialize();
-    Orthanc::Toolbox::InitializeOpenSsl();
-    Orthanc::HttpClient::GlobalInitialize();
-
-    Initialize();
-
-    /******************************************************************
-     * Declare and parse the command-line options of the application
-     ******************************************************************/
-
-    boost::program_options::options_description options;
-
-    { // generic options
-      boost::program_options::options_description generic("Generic options");
-      generic.add_options()
-          ("help", "Display this help and exit")
-          ("verbose", "Be verbose in logs")
-          ("orthanc", boost::program_options::value<std::string>()->
-            default_value("http://localhost:8042/"),
-           "URL to the Orthanc server")
-          ("username", "Username for the Orthanc server")
-          ("password", "Password for the Orthanc server")
-          ("https-verify", boost::program_options::value<bool>()->
-            default_value(true), "Check HTTPS certificates")
-          ;
-
-      options.add(generic);
-    }
-
-    // platform specific options
-    DeclareCommandLineOptions(options);
-    
-    // application specific options
-    application_->DeclareStartupOptions(options);
-
-    boost::program_options::variables_map parameters;
-    bool error = false;
-
-    try
-    {
-      boost::program_options::store(
-        boost::program_options::command_line_parser(argc, argv).
-          options(options).allow_unregistered().run(), parameters);
-      boost::program_options::notify(parameters);
-    }
-    catch (boost::program_options::error& e)
-    {
-      LOG(ERROR) << 
-        "Error while parsing the command-line arguments: " << e.what();
-      error = true;
-    }
-
-
-    /******************************************************************
-     * Configure the application with the command-line parameters
-     ******************************************************************/
-
-    if (error || parameters.count("help"))
-    {
-      std::cout << std::endl;
-
-      std::cout << options << "\n";
-      return error ? -1 : 0;
-    }
-
-    if (parameters.count("https-verify") &&
-        !parameters["https-verify"].as<bool>())
-    {
-      LOG(WARNING) << "Turning off verification of HTTPS certificates (unsafe)";
-      Orthanc::HttpClient::ConfigureSsl(false, "");
-    }
-
-    LOG(ERROR) << "???????? if (parameters.count(\"verbose\"))";
-    if (parameters.count("verbose"))
-    {
-      LOG(ERROR) << "parameters.count(\"verbose\") != 0";
-      Orthanc::Logging::EnableInfoLevel(true);
-      LOG(INFO) << "Verbose logs are enabled";
-    }
-
-    LOG(ERROR) << "???????? if (parameters.count(\"trace\"))";
-    if (parameters.count("trace"))
-    {
-      LOG(ERROR) << "parameters.count(\"trace\") != 0";
-      Orthanc::Logging::EnableTraceLevel(true);
-      VLOG(1) << "Trace logs are enabled";
-    }
-
-    ParseCommandLineOptions(parameters);
-
-    bool success = true;
-    try
-    {
-      /****************************************************************
-       * Initialize the connection to the Orthanc server
-       ****************************************************************/
-
-      Orthanc::WebServiceParameters webServiceParameters;
-
-      if (parameters.count("orthanc"))
-      {
-        webServiceParameters.SetUrl(parameters["orthanc"].as<std::string>());
-      }
-
-      if (parameters.count("username") && parameters.count("password"))
-      {
-        webServiceParameters.SetCredentials(parameters["username"].
-          as<std::string>(),
-          parameters["password"].as<std::string>());
-      }
-
-      LOG(WARNING) << "URL to the Orthanc REST API: " << 
-        webServiceParameters.GetUrl();
-
-      {
-        OrthancPlugins::OrthancHttpConnection orthanc(webServiceParameters);
-        if (!Deprecated::MessagingToolbox::CheckOrthancVersion(orthanc))
-        {
-          LOG(ERROR) << "Your version of Orthanc is incompatible with Stone of "
-            << "Orthanc, please upgrade";
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol);
-        }
-      }
-
-
-      /****************************************************************
-       * Initialize the application
-       ****************************************************************/
-
-      LOG(WARNING) << "Creating the widgets of the application";
-
-      LogStatusBar statusBar;
-
-      NativeStoneApplicationContext context;
-
-      {
-        // use multiple threads to execute asynchronous tasks like 
-        // download content
-        Deprecated::Oracle oracle(6); 
-        oracle.Start();
-
-        {
-          boost::shared_ptr<Deprecated::OracleWebService> webService
-            (new Deprecated::OracleWebService(oracle, webServiceParameters, context));
-          context.SetWebService(webService);
-          context.SetOrthancBaseUrl(webServiceParameters.GetUrl());
-
-          Deprecated::OracleDelayedCallExecutor delayedExecutor(oracle, context);
-          context.SetDelayedCallExecutor(delayedExecutor);
-
-          application_->Initialize(&context, statusBar, parameters);
-
-          {
-            NativeStoneApplicationContext::GlobalMutexLocker locker(context);
-            locker.SetCentralWidget(application_->GetCentralWidget());
-            locker.GetCentralViewport().SetStatusBar(statusBar);
-          }
-
-          std::string title = application_->GetTitle();
-          if (title.empty())
-          {
-            title = "Stone of Orthanc";
-          }
-
-          /****************************************************************
-           * Run the application
-           ****************************************************************/
-
-          Run(context, title, argc, argv);
-
-          /****************************************************************
-           * Finalize the application
-           ****************************************************************/
-
-          oracle.Stop();
-        }
-      }
-
-      LOG(WARNING) << "The application is stopping";
-      application_->Finalize();
-    }
-    catch (Orthanc::OrthancException& e)
-    {
-      LOG(ERROR) << "EXCEPTION: " << e.What();
-      success = false;
-    }
-
-
-    /******************************************************************
-     * Finalize all the subcomponents of Orthanc Stone
-     ******************************************************************/
-
-    Finalize();
-    Orthanc::HttpClient::GlobalFinalize();
-    Orthanc::Toolbox::FinalizeOpenSsl();
-
-    return (success ? 0 : -1);
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Generic/NativeStoneApplicationRunner.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../IStoneApplication.h"
-
-#if ORTHANC_ENABLE_THREADS != 1
-#error this file shall be included only with the ORTHANC_ENABLE_THREADS set to 1
-#endif
-
-namespace OrthancStone
-{
-  class NativeStoneApplicationContext;
-
-  class NativeStoneApplicationRunner
-  {
-  protected:
-    boost::shared_ptr<IStoneApplication>  application_;
-    
-  public:
-    NativeStoneApplicationRunner(boost::shared_ptr<IStoneApplication> application)
-      : application_(application)
-    {
-    }
-    int Execute(int argc,
-                char* argv[]);
-
-    virtual void Initialize() = 0;
-    virtual void DeclareCommandLineOptions(boost::program_options::options_description& options) = 0;
-    virtual void ParseCommandLineOptions(const boost::program_options::variables_map& parameters) = 0;
-
-    virtual void Run(NativeStoneApplicationContext& context, const std::string& title, int argc, char* argv[]) = 0;
-    virtual void Finalize() = 0;
-  };
-
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Generic/Scene2DInteractor.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-#pragma once
-
-#include "../../Framework/Scene2D/PointerEvent.h"
-#include "../../Framework/Scene2DViewport/ViewportController.h"
-//#include "../../Framework/Scene2D/Internals/CompositorHelper.h"
-#include "GuiAdapter.h"
-
-
-namespace OrthancStone
-{
-
-  class Scene2DInteractor
-  {
-  protected:
-    boost::shared_ptr<ViewportController>       viewportController_;
-//    boost::shared_ptr<ICompositor>              compositor_;
-
-  public:
-    Scene2DInteractor(boost::shared_ptr<ViewportController> viewportController) :
-      viewportController_(viewportController)
-    {}
-
-//    void SetCompositor(boost::shared_ptr<ICompositor> compositor)
-//    {
-//      compositor_ = compositor;
-//    }
-
-    virtual bool OnMouseEvent(const GuiAdapterMouseEvent& guiEvent, const PointerEvent& pointerEvent) = 0; // returns true if it has handled the event
-    virtual bool OnKeyboardEvent(const GuiAdapterKeyboardEvent& guiEvent) = 0; // returns true if it has handled the event
-    virtual bool OnWheelEvent(const GuiAdapterWheelEvent& guiEvent) = 0; // returns true if it has handled the event
-
-  };
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/IStoneApplication.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "StoneApplicationContext.h"
-#include "../Framework/Deprecated/Viewport/WidgetViewport.h"
-
-#include <boost/program_options.hpp>
-#include <json/json.h>
-
-namespace OrthancStone
-{
-#if ORTHANC_ENABLE_QT==1
-  class QStoneMainWindow;
-#endif
-
-  // a StoneApplication is an application that can actually be executed
-  // in multiple environments.  i.e: it can run natively integrated in a QtApplication
-  // or it can be executed as part of a WebPage when compiled into WebAssembly.
-  class IStoneApplication : public boost::noncopyable
-  {
-  protected:
-    StoneApplicationContext* context_;
-
-  public:
-    virtual ~IStoneApplication()
-    {
-    }
-
-    virtual void DeclareStartupOptions(boost::program_options::options_description& options) = 0;
-    virtual void Initialize(StoneApplicationContext* context,
-                            Deprecated::IStatusBar& statusBar,
-                            const boost::program_options::variables_map& parameters) = 0;
-
-    /**
-      This method is meant to process messages received from the outside world (i.e. GUI)
-    */
-    virtual void HandleSerializedMessage(const char* data) = 0;
-
-#if ORTHANC_ENABLE_WASM==1
-    virtual void InitializeWasm() {}  // specific initialization when the app is running in WebAssembly.  This is called after the other Initialize()
-#endif
-#if ORTHANC_ENABLE_QT==1
-      virtual QStoneMainWindow* CreateQtMainWindow() = 0;
-#endif
-
-    virtual std::string GetTitle() const = 0;
-    
-    virtual void SetCentralWidget(boost::shared_ptr<Deprecated::IWidget> widget) = 0;
-    
-    virtual boost::shared_ptr<Deprecated::IWidget> GetCentralWidget() = 0;
-    
-    virtual void Finalize() = 0;
-  };
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Qt/QCairoWidget.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,238 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "QCairoWidget.h"
-
-#include <QPainter>
-#include <QPaintEvent>
-
-#include <stdexcept>
-
-
-QCairoWidget::StoneObserver::StoneObserver(QCairoWidget& that,
-                                           Deprecated::IViewport& viewport,
-                                           OrthancStone::MessageBroker& broker) :
-  OrthancStone::IObserver(broker),
-  that_(that)
-{
-  // get notified each time the content of the central viewport changes
-  viewport.RegisterObserverCallback(
-    new OrthancStone::Callable<StoneObserver, Deprecated::IViewport::ViewportChangedMessage>
-    (*this, &StoneObserver::OnViewportChanged));
-}
-
-
-QCairoWidget::QCairoWidget(QWidget *parent) :
-  QWidget(parent),
-  context_(NULL)
-{
-  setFocusPolicy(Qt::StrongFocus); // catch keyPressEvents
-}
-
-
-void QCairoWidget::SetContext(OrthancStone::NativeStoneApplicationContext& context)
-{
-  context_ = &context;
-
-  {
-    OrthancStone::NativeStoneApplicationContext::GlobalMutexLocker locker(*context_);
-    observer_.reset(new StoneObserver(*this,
-                                      locker.GetCentralViewport(),
-                                      locker.GetMessageBroker()));
-  }
-}
-
-
-void QCairoWidget::paintEvent(QPaintEvent* /*event*/)
-{
-  QPainter painter(this);
-
-  if (image_.get() != NULL &&
-      context_ != NULL)
-  {
-    OrthancStone::NativeStoneApplicationContext::GlobalMutexLocker locker(*context_);
-    Deprecated::IViewport& viewport = locker.GetCentralViewport();
-    Orthanc::ImageAccessor a;
-    surface_.GetWriteableAccessor(a);
-    viewport.Render(a);
-    painter.drawImage(0, 0, *image_);
-  }
-  else
-  {
-    painter.fillRect(rect(), Qt::red);
-  }
-}
-
-OrthancStone::KeyboardModifiers GetKeyboardModifiers(QInputEvent* event)
-{
-  Qt::KeyboardModifiers qtModifiers = event->modifiers();
-  int stoneModifiers = static_cast<int>(OrthancStone::KeyboardModifiers_None);
-  if ((qtModifiers & Qt::AltModifier) != 0)
-  {
-    stoneModifiers |= static_cast<int>(OrthancStone::KeyboardModifiers_Alt);
-  }
-  if ((qtModifiers & Qt::ControlModifier) != 0)
-  {
-    stoneModifiers |= static_cast<int>(OrthancStone::KeyboardModifiers_Control);
-  }
-  if ((qtModifiers & Qt::ShiftModifier) != 0)
-  {
-    stoneModifiers |= static_cast<int>(OrthancStone::KeyboardModifiers_Shift);
-  }
-  return static_cast<OrthancStone::KeyboardModifiers>(stoneModifiers);
-}
-
-void QCairoWidget::mousePressEvent(QMouseEvent* event)
-{
-  OrthancStone::KeyboardModifiers stoneModifiers = GetKeyboardModifiers(event);
-
-  OrthancStone::MouseButton button;
-
-  switch (event->button())
-  {
-    case Qt::LeftButton:
-      button = OrthancStone::MouseButton_Left;
-      break;
-
-    case Qt::RightButton:
-      button = OrthancStone::MouseButton_Right;
-      break;
-
-    case Qt::MiddleButton:
-      button = OrthancStone::MouseButton_Middle;
-      break;
-
-    default:
-      return;  // Unsupported button
-  }
-
-  {
-    OrthancStone::NativeStoneApplicationContext::GlobalMutexLocker locker(*context_);
-    locker.GetCentralViewport().MouseDown(button, event->pos().x(), event->pos().y(), stoneModifiers, std::vector<Deprecated::Touch>());
-  }
-}
-
-
-void QCairoWidget::mouseReleaseEvent(QMouseEvent* /*eventNotUsed*/)
-{
-  OrthancStone::NativeStoneApplicationContext::GlobalMutexLocker locker(*context_);
-  locker.GetCentralViewport().MouseLeave();
-}
-
-
-void QCairoWidget::mouseMoveEvent(QMouseEvent* event)
-{
-  OrthancStone::NativeStoneApplicationContext::GlobalMutexLocker locker(*context_);
-  locker.GetCentralViewport().MouseMove(event->pos().x(), event->pos().y(), std::vector<Deprecated::Touch>());
-}
-
-
-void QCairoWidget::wheelEvent(QWheelEvent * event)
-{
-  OrthancStone::NativeStoneApplicationContext::GlobalMutexLocker locker(*context_);
-
-  OrthancStone::KeyboardModifiers stoneModifiers = GetKeyboardModifiers(event);
-
-  if (event->orientation() == Qt::Vertical)
-  {
-    if (event->delta() < 0)  // TODO: compare direction with SDL and make sure we send the same directions
-    {
-       locker.GetCentralViewport().MouseWheel(OrthancStone::MouseWheelDirection_Up, event->pos().x(), event->pos().y(), stoneModifiers);
-    }
-    else
-    {
-      locker.GetCentralViewport().MouseWheel(OrthancStone::MouseWheelDirection_Down, event->pos().x(), event->pos().y(), stoneModifiers);
-    }
-  }
-}
-
-void QCairoWidget::keyPressEvent(QKeyEvent *event)
-{
-  using namespace OrthancStone;
-
-  OrthancStone::KeyboardModifiers stoneModifiers = GetKeyboardModifiers(event);
-
-  OrthancStone::KeyboardKeys keyType = OrthancStone::KeyboardKeys_Generic;
-  char keyChar = event->text()[0].toLatin1();
-
-#define CASE_QT_KEY_TO_ORTHANC(qt, o) case qt: keyType = o; break;
-  if (keyChar == 0)
-  {
-    switch (event->key())
-    {
-      CASE_QT_KEY_TO_ORTHANC(Qt::Key_Up, KeyboardKeys_Up);
-      CASE_QT_KEY_TO_ORTHANC(Qt::Key_Down, KeyboardKeys_Down);
-      CASE_QT_KEY_TO_ORTHANC(Qt::Key_Left, KeyboardKeys_Left);
-      CASE_QT_KEY_TO_ORTHANC(Qt::Key_Right, KeyboardKeys_Right);
-      CASE_QT_KEY_TO_ORTHANC(Qt::Key_F1, KeyboardKeys_F1);
-      CASE_QT_KEY_TO_ORTHANC(Qt::Key_F2, KeyboardKeys_F2);
-      CASE_QT_KEY_TO_ORTHANC(Qt::Key_F3, KeyboardKeys_F3);
-      CASE_QT_KEY_TO_ORTHANC(Qt::Key_F4, KeyboardKeys_F4);
-      CASE_QT_KEY_TO_ORTHANC(Qt::Key_F5, KeyboardKeys_F5);
-      CASE_QT_KEY_TO_ORTHANC(Qt::Key_F6, KeyboardKeys_F6);
-      CASE_QT_KEY_TO_ORTHANC(Qt::Key_F7, KeyboardKeys_F7);
-      CASE_QT_KEY_TO_ORTHANC(Qt::Key_F8, KeyboardKeys_F8);
-      CASE_QT_KEY_TO_ORTHANC(Qt::Key_F9, KeyboardKeys_F9);
-      CASE_QT_KEY_TO_ORTHANC(Qt::Key_F10, KeyboardKeys_F10);
-      CASE_QT_KEY_TO_ORTHANC(Qt::Key_F11, KeyboardKeys_F11);
-      CASE_QT_KEY_TO_ORTHANC(Qt::Key_F12, KeyboardKeys_F12);
-    default:
-      break;
-    }
-  }
-  else if (keyChar == 127)
-  {
-    switch (event->key())
-    {
-      CASE_QT_KEY_TO_ORTHANC(Qt::Key_Delete, KeyboardKeys_Delete);
-      CASE_QT_KEY_TO_ORTHANC(Qt::Key_Backspace, KeyboardKeys_Backspace);
-    default:
-      break;
-    }
-  }
-
-  {
-    OrthancStone::NativeStoneApplicationContext::GlobalMutexLocker locker(*context_);    
-    locker.GetCentralViewport().KeyPressed(keyType, keyChar, stoneModifiers);
-  }
-}
-
-
-void QCairoWidget::resizeEvent(QResizeEvent* event)
-{
-  grabGesture(Qt::PanGesture);
-  QWidget::resizeEvent(event);
-
-  if (event)
-  {
-    surface_.SetSize(event->size().width(), event->size().height(), true);
-
-    image_.reset(new QImage(reinterpret_cast<uchar*>(surface_.GetBuffer()),
-                            event->size().width(), 
-                            event->size().height(),
-                            surface_.GetPitch(),
-                            QImage::Format_RGB32));
-
-    {
-      OrthancStone::NativeStoneApplicationContext::GlobalMutexLocker locker(*context_);
-      locker.GetCentralViewport().SetSize(event->size().width(), event->size().height());
-    }
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Qt/QCairoWidget.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#pragma once
-
-#include "../../Applications/Generic/NativeStoneApplicationContext.h"
-#include "../../Framework/Wrappers/CairoSurface.h"
-#include "../../Framework/Deprecated/Widgets/IWidget.h"
-
-#include <QWidget>
-#include <memory>
-#include <cassert>
-
-class QCairoWidget : public QWidget
-{
-  Q_OBJECT
-
-private:
-  class StoneObserver : public OrthancStone::IObserver
-  {
-  private:
-    QCairoWidget& that_;
-    
-  public:
-    StoneObserver(QCairoWidget& that,
-                  Deprecated::IViewport& viewport,
-                  OrthancStone::MessageBroker& broker);
-
-    void OnViewportChanged(const Deprecated::IViewport::ViewportChangedMessage& message)
-    {
-      that_.OnViewportChanged();
-    }
-  };
-  
-  std::unique_ptr<QImage>         image_;
-  OrthancStone::CairoSurface    surface_;
-  OrthancStone::NativeStoneApplicationContext* context_;
-  std::unique_ptr<StoneObserver>  observer_;
-
-protected:
-  virtual void paintEvent(QPaintEvent *event);
-
-  virtual void resizeEvent(QResizeEvent *event);
-
-  virtual void mouseMoveEvent(QMouseEvent *event);
-
-  virtual void mousePressEvent(QMouseEvent *event);
-
-  virtual void mouseReleaseEvent(QMouseEvent *event);
-
-  virtual void wheelEvent(QWheelEvent *event);
-
-  virtual void keyPressEvent(QKeyEvent *event);
-
-public:
-  explicit QCairoWidget(QWidget *parent);
- 
-  void SetContext(OrthancStone::NativeStoneApplicationContext& context);
-
-  void OnViewportChanged()
-  {
-    update();  // schedule a repaint (handled by Qt)
-    emit ContentChanged();
-  }
-
-signals:
-  void ContentChanged();
-                                               
-public slots:
-
-};
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Qt/QStoneMainWindow.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "QStoneMainWindow.h"
-
-namespace OrthancStone
-{
-
-  QStoneMainWindow::QStoneMainWindow(NativeStoneApplicationContext& context,
-                                     QWidget *parent) :
-    QMainWindow(parent),
-    context_(context),
-    cairoCentralWidget_(NULL)
-  {
-  }
-
-  void QStoneMainWindow::SetCentralStoneWidget(QCairoWidget& centralWidget)
-  {
-    cairoCentralWidget_ = &centralWidget;
-    cairoCentralWidget_->SetContext(context_);
-  }
-
-  QStoneMainWindow::~QStoneMainWindow()
-  {
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Qt/QStoneMainWindow.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-#pragma once
-
-#include <QMainWindow>
-
-#include "QCairoWidget.h"
-#include "../Generic/NativeStoneApplicationContext.h"
-
-namespace OrthancStone
-{
-  class QStoneMainWindow : public QMainWindow
-  {
-    Q_OBJECT
-
-  private:
-    OrthancStone::NativeStoneApplicationContext& context_;
-    QCairoWidget          *cairoCentralWidget_;
-
-  protected:  // you must inherit this class
-    QStoneMainWindow(NativeStoneApplicationContext& context, QWidget *parent = 0);
-    void SetCentralStoneWidget(QCairoWidget& centralWidget);
-
-  public:
-    virtual ~QStoneMainWindow();
-  };
-
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Qt/QtStoneApplicationRunner.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#if ORTHANC_ENABLE_QT != 1
-#error this file shall be included only with the ORTHANC_ENABLE_QT set to 1
-#endif
-
-#include "QtStoneApplicationRunner.h"
-#include <boost/program_options.hpp>
-#include <QApplication>
-
-#include "../../Framework/Deprecated/Toolbox/MessagingToolbox.h"
-
-#include <Core/Logging.h>
-#include <Core/HttpClient.h>
-#include <Core/Toolbox.h>
-#include <Plugins/Samples/Common/OrthancHttpConnection.h>
-#include "../../Platforms/Generic/OracleWebService.h"
-
-
-namespace OrthancStone
-{
-  void QtStoneApplicationRunner::Initialize()
-  {
-  }
-
-  void QtStoneApplicationRunner::DeclareCommandLineOptions(boost::program_options::options_description& options)
-  {
-  }
-
-  void QtStoneApplicationRunner::Run(NativeStoneApplicationContext& context, const std::string& title, int argc, char* argv[])
-  {
-    context.Start();
-
-    QApplication qtApplication(argc, argv);
-    window_.reset(application_.CreateQtMainWindow());
-
-    window_->show();
-    qtApplication.exec();
-
-    context.Stop();
-  }
-
-  void QtStoneApplicationRunner::Finalize()
-  {
-  }
-
-
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Qt/QtStoneApplicationRunner.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../Generic/NativeStoneApplicationRunner.h"
-#include "QStoneMainWindow.h"
-
-#if ORTHANC_ENABLE_QT != 1
-#error this file shall be included only with the ORTHANC_ENABLE_QT set to 1
-#endif
-
-namespace OrthancStone
-{
-  class QtStoneApplicationRunner : public NativeStoneApplicationRunner
-  {
-  protected:
-    std::unique_ptr<QStoneMainWindow> window_;
-
-  public:
-    QtStoneApplicationRunner(MessageBroker& broker,
-                             IStoneApplication& application)
-      : NativeStoneApplicationRunner(broker, application)
-    {
-    }
-
-
-    virtual void Initialize();
-
-    virtual void DeclareCommandLineOptions(boost::program_options::options_description& options);
-    virtual void ParseCommandLineOptions(const boost::program_options::variables_map& parameters) {}
-    virtual void Run(NativeStoneApplicationContext& context, const std::string& title, int argc, char* argv[]);
-    virtual void Finalize();
-  };
-
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/BasicPetCtFusionApplication.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,202 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "SampleInteractor.h"
-
-#include <Core/Logging.h>
-
-namespace OrthancStone
-{
-  namespace Samples
-  {
-    class BasicPetCtFusionApplication : public SampleApplicationBase
-    {
-    private:
-      class Interactor : public SampleInteractor
-      {
-      public:
-        static void SetStyle(LayeredSceneWidget& widget,
-                             bool ct,
-                             bool pet)
-        {
-          if (ct)
-          {
-            RenderStyle style;
-            style.windowing_ = ImageWindowing_Bone;
-            widget.SetLayerStyle(0, style);
-          }
-          else
-          {
-            RenderStyle style;
-            style.visible_ = false;
-            widget.SetLayerStyle(0, style);
-          }
-
-          if (ct && pet)
-          {
-            RenderStyle style;
-            style.applyLut_ = true;
-            style.alpha_ = 0.5;
-            widget.SetLayerStyle(1, style);
-          }
-          else if (pet)
-          {
-            RenderStyle style;
-            style.applyLut_ = true;
-            widget.SetLayerStyle(1, style);
-          }
-          else
-          {
-            RenderStyle style;
-            style.visible_ = false;
-            widget.SetLayerStyle(1, style);
-          }
-        }
-
-
-        static bool IsVisible(LayeredSceneWidget& widget,
-                              size_t layer)
-        {
-          RenderStyle style = widget.GetLayerStyle(layer);
-          return style.visible_;
-        }
-
-
-        static void ToggleInterpolation(LayeredSceneWidget& widget,
-                                        size_t layer)
-        {
-          RenderStyle style = widget.GetLayerStyle(layer);
-         
-          if (style.interpolation_ == ImageInterpolation_Bilinear)
-          {
-            style.interpolation_ = ImageInterpolation_Nearest;
-          }
-          else
-          {
-            style.interpolation_ = ImageInterpolation_Bilinear;
-          }
-
-          widget.SetLayerStyle(layer, style);
-        }
-
-
-        Interactor(VolumeImage& volume,
-                   VolumeProjection projection, 
-                   bool reverse) :
-          SampleInteractor(volume, projection, reverse)
-        {
-        }
-
-
-        virtual void KeyPressed(WorldSceneWidget& widget,
-                                char key,
-                                KeyboardModifiers modifiers,
-                                IStatusBar* statusBar)
-        {
-          LayeredSceneWidget& layered = dynamic_cast<LayeredSceneWidget&>(widget);
-
-          switch (key)
-          {
-            case 'c':
-              // Toggle the visibility of the CT layer
-              SetStyle(layered, !IsVisible(layered, 0), IsVisible(layered, 1));
-              break;
-
-            case 'p':
-              // Toggle the visibility of the PET layer
-              SetStyle(layered, IsVisible(layered, 0), !IsVisible(layered, 1));
-              break;
-
-            case 'i':
-            {
-              // Toggle on/off the interpolation
-              ToggleInterpolation(layered, 0);
-              ToggleInterpolation(layered, 1);
-              break;
-            }
-
-            default:
-              break;
-          }
-        }
-      };
-
-
-    public:
-      virtual void DeclareCommandLineOptions(boost::program_options::options_description& options)
-      {
-        boost::program_options::options_description generic("Sample options");
-        generic.add_options()
-          ("ct", boost::program_options::value<std::string>(), 
-           "Orthanc ID of the CT series")
-          ("pet", boost::program_options::value<std::string>(), 
-           "Orthanc ID of the PET series")
-          ("threads", boost::program_options::value<unsigned int>()->default_value(3), 
-           "Number of download threads for the CT series")
-          ;
-
-        options.add(generic);    
-      }
-
-      virtual void Initialize(BasicApplicationContext& context,
-                              IStatusBar& statusBar,
-                              const boost::program_options::variables_map& parameters)
-      {
-        using namespace OrthancStone;
-
-        if (parameters.count("ct") != 1 ||
-            parameters.count("pet") != 1)
-        {
-          LOG(ERROR) << "The series ID is missing";
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-        }
-
-        std::string ct = parameters["ct"].as<std::string>();
-        std::string pet = parameters["pet"].as<std::string>();
-        unsigned int threads = parameters["threads"].as<unsigned int>();
-
-        VolumeImage& ctVolume = context.AddSeriesVolume(ct, true /* progressive download */, threads);
-        VolumeImage& petVolume = context.AddSeriesVolume(pet, true /* progressive download */, 1);
-
-        // Take the PET volume as the reference for the slices
-        std::unique_ptr<Interactor> interactor(new Interactor(petVolume, VolumeProjection_Axial, false /* don't reverse normal */));
-
-        std::unique_ptr<LayeredSceneWidget> widget(new LayeredSceneWidget);
-        widget->AddLayer(new VolumeImage::LayerFactory(ctVolume));
-        widget->AddLayer(new VolumeImage::LayerFactory(petVolume));
-        widget->SetSlice(interactor->GetCursor().GetCurrentSlice());
-        widget->SetInteractor(*interactor);
-
-        Interactor::SetStyle(*widget, true, true);   // Initially, show both CT and PET layers
-
-        context.AddInteractor(interactor.release());
-        context.SetCentralWidget(widget.release());
-
-        statusBar.SetMessage("Use the key \"t\" to toggle the fullscreen mode");
-        statusBar.SetMessage("Use the key \"c\" to show/hide the CT layer");
-        statusBar.SetMessage("Use the key \"p\" to show/hide the PET layer");
-        statusBar.SetMessage("Use the key \"i\" to toggle the smoothing of the images");
-      }
-    };
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/CMakeLists.txt	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,292 +0,0 @@
-# Usage (Linux):
-# to build the WASM samples
-# source ~/Downloads/emsdk/emsdk_env.sh && cmake -DCMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN}/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_BUILD_TYPE=Release -DSTONE_SOURCES_DIR=$currentDir/../../../orthanc-stone -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT=$currentDir/../../../orthanc -DALLOW_DOWNLOADS=ON .. -DENABLE_WASM=ON
-# to build the Qt samples
-
-cmake_minimum_required(VERSION 2.8.3)
-project(OrthancStone)
-
-include(../../../Resources/CMake/OrthancStoneParameters.cmake)
-
-set(ENABLE_STONE_DEPRECATED ON)  # Need deprecated classes for these samples
-set(EMSCRIPTEN_SET_LLVM_WASM_BACKEND ON)
-
-include(${ORTHANC_ROOT}/Resources/CMake/DownloadPackage.cmake)
-DownloadPackage(
-  "a24b8136b8f3bb93f166baf97d9328de"
-  "http://orthanc.osimis.io/ThirdPartyDownloads/ubuntu-font-family-0.83.zip"
-  "${CMAKE_BINARY_DIR}/ubuntu-font-family-0.83")
-
-set(ORTHANC_STONE_APPLICATION_RESOURCES
-  UBUNTU_FONT  ${CMAKE_BINARY_DIR}/ubuntu-font-family-0.83/Ubuntu-R.ttf
-  )
-
-if (OPENSSL_NO_CAPIENG)
-add_definitions(-DOPENSSL_NO_CAPIENG=1)
-endif()
-
-
-# the following block has been borrowed from orthanc/**/Compiler.cmake
-if (MSVC_MULTIPLE_PROCESSES)
-# "If you omit the processMax argument in the /MP option, the
-# compiler obtains the number of effective processors from the
-# operating system, and then creates one process per effective
-# processor"
-# https://blog.kitware.com/cmake-building-with-all-your-cores/
-# https://docs.microsoft.com/en-us/cpp/build/reference/mp-build-with-multiple-processes
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
-endif()
-
-#set(ENABLE_DCMTK ON)
-
-set(ENABLE_SDL OFF CACHE BOOL "Target SDL Native application")
-set(ENABLE_QT OFF CACHE BOOL "Target Qt Native application")
-set(ENABLE_WASM OFF CACHE BOOL "Target WASM application")
-
-if (ENABLE_WASM)
-  #####################################################################
-  ## Configuration of the Emscripten compiler for WebAssembly target
-  #####################################################################
-
-  set(WASM_FLAGS "-s WASM=1")
-  set(WASM_FLAGS "${WASM_FLAGS} -s STRICT=1") # drops support for all deprecated build options
-  set(WASM_FLAGS "${WASM_FLAGS} -s FILESYSTEM=1") # if we don't include it, gen_uuid.c fails to build because srand, getpid(), ... are not defined
-  set(WASM_FLAGS "${WASM_FLAGS} -s DISABLE_EXCEPTION_CATCHING=0") # actually enable exception catching 
-  set(WASM_FLAGS "${WASM_FLAGS} -s ERROR_ON_MISSING_LIBRARIES=1")
-  
-  if (CMAKE_BUILD_TYPE MATCHES DEBUG)
-    set(WASM_FLAGS "${WASM_FLAGS} -g4") # generate debug information
-    set(WASM_FLAGS "${WASM_FLAGS} -s ASSERTIONS=2") # more runtime checks
-  else()
-    set(WASM_FLAGS "${WASM_FLAGS} -Os") # optimize for web (speed and size)
-  endif()
-
-  set(WASM_MODULE_NAME "StoneFrameworkModule" CACHE STRING "Name of the WebAssembly module")
-
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WASM_FLAGS}")
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WASM_FLAGS}")
-
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${WASM_FLAGS}")  # not always clear which flags are for the compiler and which one are for the linker -> pass them all to the linker too
-  # set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --js-library ${STONE_SOURCES_DIR}/Applications/Samples/samples-library.js")
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --js-library ${STONE_SOURCES_DIR}/Platforms/Wasm/WasmWebService.js")
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --js-library ${STONE_SOURCES_DIR}/Platforms/Wasm/WasmDelayedCallExecutor.js")
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --js-library ${STONE_SOURCES_DIR}/Platforms/Wasm/default-library.js")
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXTRA_EXPORTED_RUNTIME_METHODS='[\"ccall\", \"cwrap\"]'")
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXPORT_NAME='\"${WASM_MODULE_NAME}\"'")
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ALLOW_MEMORY_GROWTH=1")
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s TOTAL_MEMORY=536870912")
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s TOTAL_STACK=128000000")
-
-  add_definitions(-DORTHANC_ENABLE_WASM=1)
-  set(ORTHANC_SANDBOXED ON)
-
-elseif (ENABLE_QT OR ENABLE_SDL)
-
-  set(ENABLE_NATIVE ON)
-  set(ORTHANC_SANDBOXED OFF)
-  set(ENABLE_CRYPTO_OPTIONS ON)
-  set(ENABLE_GOOGLE_TEST ON)
-  set(ENABLE_WEB_CLIENT ON)
-
-else()
-  set(ENABLE_NATIVE ON)
-  set(ENABLE_OPENGL OFF)
-  
-endif()
-
-
-#####################################################################
-## Configuration for Orthanc
-#####################################################################
-
-# include(../../Resources/CMake/Version.cmake)
-
-if (ORTHANC_STONE_VERSION STREQUAL "mainline")
-  set(ORTHANC_FRAMEWORK_VERSION "mainline")
-  set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "hg")
-else()
-  set(ORTHANC_FRAMEWORK_VERSION "1.4.1")
-  set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "web")
-endif()
-
-set(ORTHANC_FRAMEWORK_SOURCE "${ORTHANC_FRAMEWORK_DEFAULT_SOURCE}" CACHE STRING "Source of the Orthanc source code (can be \"hg\", \"archive\", \"web\" or \"path\")")
-set(ORTHANC_FRAMEWORK_ARCHIVE "" CACHE STRING "Path to the Orthanc archive, if ORTHANC_FRAMEWORK_SOURCE is \"archive\"")
-set(ORTHANC_FRAMEWORK_ROOT "" CACHE STRING "Path to the Orthanc source directory, if ORTHANC_FRAMEWORK_SOURCE is \"path\"")
-
-add_definitions(
-  -DORTHANC_ENABLE_LOGGING_PLUGIN=0
-  )
-
-
-#####################################################################
-## Build a static library containing the Orthanc Stone framework
-#####################################################################
-
-
-LIST(APPEND ORTHANC_BOOST_COMPONENTS program_options)
-
-include(../../../Resources/CMake/OrthancStoneConfiguration.cmake)
-
-add_library(OrthancStone STATIC
-  ${ORTHANC_STONE_SOURCES}
-  )
-
-#####################################################################
-## Build all the sample applications
-#####################################################################
-
-include_directories(${ORTHANC_STONE_ROOT})
-
-# files common to all samples
-list(APPEND SAMPLE_APPLICATIONS_SOURCES
-  ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/SampleInteractor.h
-  ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/SampleApplicationBase.h
-  )
-
-if (ENABLE_QT)
-  list(APPEND SAMPLE_APPLICATIONS_SOURCES
-    ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/Qt/SampleQtApplicationRunner.h
-    ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/Qt/SampleMainWindow.cpp
-    ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/Qt/SampleMainWindowWithButtons.cpp
-    )
-
-  ORTHANC_QT_WRAP_UI(SAMPLE_APPLICATIONS_SOURCES
-    ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/Qt/SampleMainWindow.ui
-    ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/Qt/SampleMainWindowWithButtons.ui
-    )
-
-  ORTHANC_QT_WRAP_CPP(SAMPLE_APPLICATIONS_SOURCES
-    ${ORTHANC_STONE_ROOT}/Applications/Qt/QCairoWidget.h
-    ${ORTHANC_STONE_ROOT}/Applications/Qt/QStoneMainWindow.h
-    ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/Qt/SampleMainWindow.h
-    ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/Qt/SampleMainWindowWithButtons.h
-    )
-endif()
-
-if (ENABLE_NATIVE)
-  list(APPEND SAMPLE_APPLICATIONS_SOURCES
-    ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/SampleMainNative.cpp
-    )
-
-elseif (ENABLE_WASM)
-
-  list(APPEND SAMPLE_APPLICATIONS_SOURCES
-    ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/SampleMainWasm.cpp
-    ${STONE_WASM_SOURCES}
-    )
-endif()
-
-
-macro(BuildSingleFileSample Target Header Sample)
-  add_executable(${Target}
-    ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/${Header}
-    ${SAMPLE_APPLICATIONS_SOURCES}
-    )
-  set_target_properties(${Target} PROPERTIES COMPILE_DEFINITIONS ORTHANC_STONE_SAMPLE=${Sample})
-  target_link_libraries(${Target} OrthancStone)
-endmacro()
-
-
-if (ENABLE_SDL)
-  #BuildSingleFileSample(OrthancStoneEmpty EmptyApplication.h 1)
-  #BuildSingleFileSample(OrthancStoneTestPattern TestPatternApplication.h 2)
-  BuildSingleFileSample(OrthancStoneSingleFrame SingleFrameApplication.h 3)
-  #BuildSingleFileSample(OrthancStoneSingleVolume SingleVolumeApplication.h 4)
-  #BuildSingleFileSample(OrthancStoneBasicPetCtFusion 5)
-  #BuildSingleFileSample(OrthancStoneSynchronizedSeries 6)
-  #BuildSingleFileSample(OrthancStoneLayoutPetCtFusion 7)
-  BuildSingleFileSample(OrthancStoneSimpleViewerSingleFile SimpleViewerApplicationSingleFile.h 8)  # we keep that one just as a sample before we convert another sample to this pattern
-  BuildSingleFileSample(OrthancStoneSingleFrameEditor SingleFrameEditorApplication.h 9)
-endif()
-  
-##### SimpleViewer sample (Qt and WASM only) #######
-
-if (ENABLE_QT OR ENABLE_WASM)
-
-    if (ENABLE_QT)
-      list(APPEND SIMPLE_VIEWER_APPLICATION_SOURCES
-        ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/SimpleViewer/Qt/SimpleViewerMainWindow.cpp
-        ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/SimpleViewer/Qt/SimpleViewerMainWindow.ui
-        ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/SimpleViewer/Qt/mainQt.cpp
-        )
-
-      ORTHANC_QT_WRAP_UI(SIMPLE_VIEWER_APPLICATION_SOURCES
-        ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/SimpleViewer/Qt/SimpleViewerMainWindow.ui
-        )
-
-      ORTHANC_QT_WRAP_CPP(SIMPLE_VIEWER_APPLICATION_SOURCES
-        ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/SimpleViewer/Qt/SimpleViewerMainWindow.h
-        )
-
-elseif (ENABLE_WASM)
-        list(APPEND SIMPLE_VIEWER_APPLICATION_SOURCES
-            ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/SimpleViewer/Wasm/mainWasm.cpp
-            ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/SimpleViewer/Wasm/SimpleViewerWasmApplicationAdapter.cpp
-            ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/SimpleViewer/Wasm/SimpleViewerWasmApplicationAdapter.h
-            ${STONE_WASM_SOURCES}
-          )
-    endif()
-
-    add_executable(OrthancStoneSimpleViewer
-      ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/SimpleViewer/AppStatus.h
-      ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/SimpleViewer/MainWidgetInteractor.cpp
-      ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/SimpleViewer/MainWidgetInteractor.h
-      ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/SimpleViewer/SimpleViewerApplication.cpp
-      ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/SimpleViewer/SimpleViewerApplication.h
-      ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/SimpleViewer/ThumbnailInteractor.cpp
-      ${ORTHANC_STONE_ROOT}/Applications/Samples/Deprecated/SimpleViewer/ThumbnailInteractor.h
-      ${SIMPLE_VIEWER_APPLICATION_SOURCES}
-      )
-    target_link_libraries(OrthancStoneSimpleViewer OrthancStone)
-
-    BuildSingleFileSample(OrthancStoneSingleFrameEditor SingleFrameEditorApplication.h 9)
-endif()
-
-#####################################################################
-## Build the unit tests
-#####################################################################
-
-if (ENABLE_NATIVE)
-  add_executable(UnitTests
-    ${GOOGLE_TEST_SOURCES}
-    ${ORTHANC_STONE_ROOT}/UnitTestsSources/GenericToolboxTests.cpp
-    ${ORTHANC_STONE_ROOT}/UnitTestsSources/ImageToolboxTests.cpp
-    ${ORTHANC_STONE_ROOT}/UnitTestsSources/PixelTestPatternsTests.cpp
-    ${ORTHANC_STONE_ROOT}/UnitTestsSources/TestCommands.cpp
-    ${ORTHANC_STONE_ROOT}/UnitTestsSources/TestMessageBroker.cpp
-    ${ORTHANC_STONE_ROOT}/UnitTestsSources/TestStrategy.cpp
-    ${ORTHANC_STONE_ROOT}/UnitTestsSources/TestStructureSet.cpp
-    ${ORTHANC_STONE_ROOT}/UnitTestsSources/UnitTestsMain.cpp
-    )
-
-  target_link_libraries(UnitTests OrthancStone)
-
-  add_custom_command(
-    TARGET UnitTests
-    POST_BUILD
-    COMMAND ${CMAKE_COMMAND} -E copy
-      "${ORTHANC_STONE_ROOT}/UnitTestsSources/72c773ac-5059f2c4-2e6a9120-4fd4bca1-45701661.json" 
-      "$<TARGET_FILE_DIR:UnitTests>/72c773ac-5059f2c4-2e6a9120-4fd4bca1-45701661.json"
-    )
-
-endif()
-
-#####################################################################
-## Generate the documentation if Doxygen is present
-#####################################################################
-
-find_package(Doxygen)
-if (DOXYGEN_FOUND)
-  configure_file(
-    ${ORTHANC_STONE_ROOT}/Resources/OrthancStone.doxygen
-    ${CMAKE_CURRENT_BINARY_DIR}/OrthancStone.doxygen
-    @ONLY)
-
-  add_custom_target(doc
-    ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/OrthancStone.doxygen
-    COMMENT "Generating documentation with Doxygen" VERBATIM
-    )
-else()
-  message("Doxygen not found. The documentation will not be built.")
-endif()
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/CMakeLists.txt.old	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,248 +0,0 @@
-# Usage: see README file
-
-cmake_minimum_required(VERSION 2.8.3)
-
-# Automatically link Qt executables to qtmain target on Windows
-# ("OLD" == do not link)
-if(POLICY CMP0020)
-  cmake_policy(SET CMP0020 OLD)
-endif()
-
-# Only interpret if() arguments as variables or keywords when unquoted.
-# NEW = do NOT dereference *quoted* variables
-if(POLICY CMP0054)
-  cmake_policy(SET CMP0054 NEW)
-endif()
-
-project(OrthancStone)
-
-include(../../Resources/CMake/OrthancStoneParameters.cmake)
-
-#set(ENABLE_DCMTK ON)
-
-set(ENABLE_SDL OFF CACHE BOOL "Target SDL Native application")
-set(ENABLE_QT OFF CACHE BOOL "Target Qt Native application")
-set(ENABLE_WASM OFF CACHE BOOL "Target WASM application")
-
-# TODO: replace or compute STONE_SOURCES_DIR from CMAKE_CURRENT_LIST_FILE
-
-if (ENABLE_WASM)
-  #####################################################################
-  ## Configuration of the Emscripten compiler for WebAssembly target
-  #####################################################################
-
-  set(WASM_FLAGS "-s WASM=1 -O0 -g0")
-  message("*****************************************************************************")
-  message("WARNING: optimizations are disabled in emcc!!! Enable them for production use")
-  message("*****************************************************************************")
-  set(WASM_MODULE_NAME "StoneFrameworkModule" CACHE STRING "Name of the WebAssembly module")
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WASM_FLAGS}")
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WASM_FLAGS}")
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --js-library ${STONE_SOURCES_DIR}/Platforms/Wasm/WasmWebService.js --js-library ${STONE_SOURCES_DIR}/Platforms/Wasm/WasmDelayedCallExecutor.js --js-library ${STONE_SOURCES_DIR}/Platforms/Wasm/default-library.js  -s EXTRA_EXPORTED_RUNTIME_METHODS='[\"ccall\", \"cwrap\"]'")
-
-  # Handling of memory
-  #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ALLOW_MEMORY_GROWTH=1")  # Resize
-  #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s TOTAL_MEMORY=536870912")  # 512MB
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXPORT_NAME='\"${WASM_MODULE_NAME}\"' -s ALLOW_MEMORY_GROWTH=1 -s TOTAL_MEMORY=536870912 -s TOTAL_STACK=128000000")  # 512MB + resize
-  #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ALLOW_MEMORY_GROWTH=1 -s TOTAL_MEMORY=1073741824")  # 1GB + resize
-
-  # To debug exceptions
-  #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s DEMANGLE_SUPPORT=1 -s ASSERTIONS=2")
-
-  add_definitions(-DORTHANC_ENABLE_WASM=1)
-  set(ORTHANC_SANDBOXED ON)
-
-elseif (ENABLE_QT OR ENABLE_SDL)
-
-  set(ENABLE_NATIVE ON)
-  set(ORTHANC_SANDBOXED OFF)
-  set(ENABLE_CRYPTO_OPTIONS ON)
-  set(ENABLE_GOOGLE_TEST ON)
-  set(ENABLE_WEB_CLIENT ON)
-
-endif()
-
-#####################################################################
-## Configuration for Orthanc
-#####################################################################
-
-# include(../../Resources/CMake/Version.cmake)
-
-if (ORTHANC_STONE_VERSION STREQUAL "mainline")
-  set(ORTHANC_FRAMEWORK_VERSION "mainline")
-  set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "hg")
-else()
-  set(ORTHANC_FRAMEWORK_VERSION "1.4.1")
-  set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "web")
-endif()
-
-set(ORTHANC_FRAMEWORK_SOURCE "${ORTHANC_FRAMEWORK_DEFAULT_SOURCE}" CACHE STRING "Source of the Orthanc source code (can be \"hg\", \"archive\", \"web\" or \"path\")")
-set(ORTHANC_FRAMEWORK_ARCHIVE "" CACHE STRING "Path to the Orthanc archive, if ORTHANC_FRAMEWORK_SOURCE is \"archive\"")
-set(ORTHANC_FRAMEWORK_ROOT "" CACHE STRING "Path to the Orthanc source directory, if ORTHANC_FRAMEWORK_SOURCE is \"path\"")
-
-#####################################################################
-## Build a static library containing the Orthanc Stone framework
-#####################################################################
-
-LIST(APPEND ORTHANC_BOOST_COMPONENTS program_options)
-
-include(../../Resources/CMake/OrthancStoneConfiguration.cmake)
-
-add_library(OrthancStone STATIC
-  ${ORTHANC_STONE_SOURCES}
-  )
-
-#####################################################################
-## Build all the sample applications
-#####################################################################
-
-include_directories(${ORTHANC_STONE_ROOT})
-
-# files common to all samples
-list(APPEND SAMPLE_APPLICATIONS_SOURCES
-  ${ORTHANC_STONE_ROOT}/Applications/Samples/SampleInteractor.h
-  ${ORTHANC_STONE_ROOT}/Applications/Samples/SampleApplicationBase.h
-  )
-
-if (ENABLE_QT)
-  list(APPEND SAMPLE_APPLICATIONS_SOURCES
-    ${ORTHANC_STONE_ROOT}/Applications/Samples/Qt/SampleQtApplicationRunner.h
-    ${ORTHANC_STONE_ROOT}/Applications/Samples/Qt/SampleMainWindow.cpp
-    ${ORTHANC_STONE_ROOT}/Applications/Samples/Qt/SampleMainWindowWithButtons.cpp
-    )
-
-  ORTHANC_QT_WRAP_UI(SAMPLE_APPLICATIONS_SOURCES
-    ${ORTHANC_STONE_ROOT}/Applications/Samples/Qt/SampleMainWindow.ui
-    ${ORTHANC_STONE_ROOT}/Applications/Samples/Qt/SampleMainWindowWithButtons.ui
-    )
-
-  ORTHANC_QT_WRAP_CPP(SAMPLE_APPLICATIONS_SOURCES
-    ${ORTHANC_STONE_ROOT}/Applications/Qt/QCairoWidget.h
-    ${ORTHANC_STONE_ROOT}/Applications/Qt/QStoneMainWindow.h
-    ${ORTHANC_STONE_ROOT}/Applications/Samples/Qt/SampleMainWindow.h
-    ${ORTHANC_STONE_ROOT}/Applications/Samples/Qt/SampleMainWindowWithButtons.h
-    )
-endif()
-
-if (ENABLE_NATIVE)
-  list(APPEND SAMPLE_APPLICATIONS_SOURCES
-    ${ORTHANC_STONE_ROOT}/Applications/Samples/SampleMainNative.cpp
-    )
-
-elseif (ENABLE_WASM)
-
-  list(APPEND SAMPLE_APPLICATIONS_SOURCES
-    ${ORTHANC_STONE_ROOT}/Applications/Samples/SampleMainWasm.cpp
-    ${STONE_WASM_SOURCES}
-    )
-endif()
-
-
-macro(BuildSingleFileSample Target Header Sample)
-  add_executable(${Target}
-    ${ORTHANC_STONE_ROOT}/Applications/Samples/${Header}
-    ${SAMPLE_APPLICATIONS_SOURCES}
-    )
-  set_target_properties(${Target} PROPERTIES COMPILE_DEFINITIONS ORTHANC_STONE_SAMPLE=${Sample})
-  target_link_libraries(${Target} OrthancStone)
-  
-  if (ENABLE_QT AND (CMAKE_SYSTEM_NAME STREQUAL "Windows"))
-    message("(ENABLE_QT and (CMAKE_SYSTEM_NAME matches \"Windows\")) is true")
-    add_custom_command(
-      TARGET ${Target} POST_BUILD
-      COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Core> $<TARGET_FILE_DIR:${Target}>
-      COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Widgets> $<TARGET_FILE_DIR:${Target}>
-      COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Gui> $<TARGET_FILE_DIR:${Target}>
-    )
-  endif()
-endmacro()
-
-#BuildSingleFileSample(OrthancStoneEmpty EmptyApplication.h 1)
-#BuildSingleFileSample(OrthancStoneTestPattern TestPatternApplication.h 2)
-BuildSingleFileSample(OrthancStoneSingleFrame SingleFrameApplication.h 3)
-#BuildSingleFileSample(OrthancStoneSingleVolume SingleVolumeApplication.h 4)
-#BuildSingleFileSample(OrthancStoneBasicPetCtFusion 5)
-#BuildSingleFileSample(OrthancStoneSynchronizedSeries 6)
-#BuildSingleFileSample(OrthancStoneLayoutPetCtFusion 7)
-BuildSingleFileSample(OrthancStoneSimpleViewerSingleFile SimpleViewerApplicationSingleFile.h 8)  # we keep that one just as a sample before we convert another sample to this pattern
-BuildSingleFileSample(OrthancStoneSingleFrameEditor SingleFrameEditorApplication.h 9)
-
-##### SimpleViewer sample (Qt and WASM only) #######
-
-if (ENABLE_QT OR ENABLE_WASM)
-
-      # GenerateCodeFromFlatBufferSchema("${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/ApplicationCommands.fbs")
-
-      list(APPEND SIMPLE_VIEWER_APPLICATION_SOURCES ${FLATC_AUTOGENERATED_SOURCES})
-      message(STATUS "SIMPLE_VIEWER_APPLICATION_SOURCES = ${SIMPLE_VIEWER_APPLICATION_SOURCES}")
-      message(STATUS "FLATC_AUTOGENERATED_SOURCES = ${FLATC_AUTOGENERATED_SOURCES}")
-
-    if (ENABLE_QT)
-      list(APPEND SIMPLE_VIEWER_APPLICATION_SOURCES
-        ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/Qt/SimpleViewerMainWindow.cpp
-        ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/Qt/SimpleViewerMainWindow.ui
-        ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/Qt/mainQt.cpp
-        )
-
-      ORTHANC_QT_WRAP_UI(SIMPLE_VIEWER_APPLICATION_SOURCES
-        ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/Qt/SimpleViewerMainWindow.ui
-        )
-
-      ORTHANC_QT_WRAP_CPP(SIMPLE_VIEWER_APPLICATION_SOURCES
-        ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/Qt/SimpleViewerMainWindow.h
-        )
-
-elseif (ENABLE_WASM)
-        list(APPEND SIMPLE_VIEWER_APPLICATION_SOURCES
-            ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/Wasm/mainWasm.cpp
-            ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/Wasm/SimpleViewerWasmApplicationAdapter.cpp
-            ${STONE_WASM_SOURCES}
-          )
-    endif()
-
-    add_executable(OrthancStoneSimpleViewer
-      ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/SimpleViewerApplication.cpp
-      ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/ThumbnailInteractor.cpp
-      ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/MainWidgetInteractor.cpp
-      ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/AppStatus.h
-      ${ORTHANC_STONE_ROOT}/Applications/Samples/SimpleViewer/Messages.h
-      ${SIMPLE_VIEWER_APPLICATION_SOURCES}
-      )
-    target_link_libraries(OrthancStoneSimpleViewer OrthancStone)
-
-endif()
-
-#####################################################################
-## Build the unit tests
-#####################################################################
-
-if (ENABLE_NATIVE)
-  add_executable(UnitTests
-    ${GOOGLE_TEST_SOURCES}
-    ${ORTHANC_STONE_ROOT}/UnitTestsSources/TestCommands.cpp
-    ${ORTHANC_STONE_ROOT}/UnitTestsSources/TestExceptions.cpp
-    ${ORTHANC_STONE_ROOT}/UnitTestsSources/TestMessageBroker.cpp
-    ${ORTHANC_STONE_ROOT}/UnitTestsSources/UnitTestsMain.cpp
-    )
-
-  target_link_libraries(UnitTests OrthancStone)
-endif()
-
-#####################################################################
-## Generate the documentation if Doxygen is present
-#####################################################################
-
-find_package(Doxygen)
-if (DOXYGEN_FOUND)
-  configure_file(
-    ${ORTHANC_STONE_ROOT}/Resources/OrthancStone.doxygen
-    ${CMAKE_CURRENT_BINARY_DIR}/OrthancStone.doxygen
-    @ONLY)
-
-  add_custom_target(doc
-    ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/OrthancStone.doxygen
-    COMMENT "Generating documentation with Doxygen" VERBATIM
-    )
-else()
-  message("Doxygen not found. The documentation will not be built.")
-endif()
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/EmptyApplication.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "SampleApplicationBase.h"
-
-#include "../../../Framework/Widgets/EmptyWidget.h"
-
-namespace OrthancStone
-{
-  namespace Samples
-  {
-    class EmptyApplication : public SampleApplicationBase
-    {
-    public:
-      virtual void DeclareStartupOptions(boost::program_options::options_description& options)
-      {
-        boost::program_options::options_description generic("Sample options");
-        generic.add_options()
-          ("red", boost::program_options::value<int>()->default_value(255), "Background color: red channel")
-          ("green", boost::program_options::value<int>()->default_value(0), "Background color: green channel")
-          ("blue", boost::program_options::value<int>()->default_value(0), "Background color: blue channel")
-          ;
-
-        options.add(generic);    
-      }
-
-      virtual void Initialize(IStatusBar& statusBar,
-                              const boost::program_options::variables_map& parameters)
-      {
-        int red = parameters["red"].as<int>();
-        int green = parameters["green"].as<int>();
-        int blue = parameters["blue"].as<int>();
-
-        context_->SetCentralWidget(new EmptyWidget(red, green, blue));
-      }
-    };
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/LayoutPetCtFusionApplication.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,398 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "SampleInteractor.h"
-
-#include "../../../Framework/Layers/ReferenceLineFactory.h"
-#include "../../../Framework/Layers/DicomStructureSetSlicer.h"
-#include "../../../Framework/Widgets/LayoutWidget.h"
-
-#include <Core/Logging.h>
-
-namespace OrthancStone
-{
-  namespace Samples
-  {
-    class LayoutPetCtFusionApplication : 
-      public SampleApplicationBase,
-      public LayeredSceneWidget::ISliceObserver,
-      public WorldSceneWidget::IWorldObserver
-    {
-    private:
-      class Interactor : public SampleInteractor
-      {
-      private:
-        LayoutPetCtFusionApplication& that_;
-
-      public:
-        Interactor(LayoutPetCtFusionApplication& that,
-                   VolumeImage& volume,
-                   VolumeProjection projection, 
-                   bool reverse) :
-          SampleInteractor(volume, projection, reverse),
-          that_(that)
-        {
-        }
-
-        virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget,
-                                                            const SliceGeometry& slice,
-                                                            const ViewportGeometry& view,
-                                                            MouseButton button,
-                                                            double x,
-                                                            double y,
-                                                            IStatusBar* statusBar)
-        {
-          if (button == MouseButton_Left)
-          {
-            // Center the sibling views over the clicked point
-            Vector p = slice.MapSliceToWorldCoordinates(x, y);
-
-            if (statusBar != NULL)
-            {
-              char buf[64];
-              sprintf(buf, "Click on coordinates (%.02f,%.02f,%.02f) in cm", p[0] / 10.0, p[1] / 10.0, p[2] / 10.0);
-              statusBar->SetMessage(buf);
-            }
-
-            that_.interactorAxial_->LookupSliceContainingPoint(*that_.ctAxial_, p);
-            that_.interactorCoronal_->LookupSliceContainingPoint(*that_.ctCoronal_, p);
-            that_.interactorSagittal_->LookupSliceContainingPoint(*that_.ctSagittal_, p);
-          }
-
-          return NULL;
-        }
-
-        virtual void KeyPressed(WorldSceneWidget& widget,
-                                char key,
-                                KeyboardModifiers modifiers,
-                                IStatusBar* statusBar)
-        {
-          if (key == 's')
-          {
-            that_.FitContent();
-          }
-        }
-      };
-
-      bool                 processingEvent_;
-      Interactor*          interactorAxial_;
-      Interactor*          interactorCoronal_;
-      Interactor*          interactorSagittal_;
-      LayeredSceneWidget*  ctAxial_;
-      LayeredSceneWidget*  ctCoronal_;
-      LayeredSceneWidget*  ctSagittal_;
-      LayeredSceneWidget*  petAxial_;
-      LayeredSceneWidget*  petCoronal_;
-      LayeredSceneWidget*  petSagittal_;
-      LayeredSceneWidget*  fusionAxial_;
-      LayeredSceneWidget*  fusionCoronal_;
-      LayeredSceneWidget*  fusionSagittal_;
-
-
-      void FitContent()
-      {
-        petAxial_->FitContent();
-        petCoronal_->FitContent();
-        petSagittal_->FitContent();
-      }
-
-
-      void AddLayer(LayeredSceneWidget& widget,
-                    VolumeImage& volume,
-                    bool isCt)
-      {
-        size_t layer;
-        widget.AddLayer(layer, new VolumeImage::LayerFactory(volume));
-
-        if (isCt)
-        {
-          RenderStyle style; 
-          style.windowing_ = ImageWindowing_Bone;
-          widget.SetLayerStyle(layer, style);
-        }
-        else
-        {
-          RenderStyle style; 
-          style.applyLut_ = true;
-          style.alpha_ = (layer == 0 ? 1.0f : 0.5f);
-          widget.SetLayerStyle(layer, style);
-        }
-      }
-
-
-      void ConnectSiblingLocations(LayeredSceneWidget& axial,
-                                   LayeredSceneWidget& coronal,
-                                   LayeredSceneWidget& sagittal)
-      {
-        ReferenceLineFactory::Configure(axial, coronal);
-        ReferenceLineFactory::Configure(axial, sagittal);
-        ReferenceLineFactory::Configure(coronal, sagittal);
-      }
-
-
-      void SynchronizeView(const WorldSceneWidget& source,
-                           const ViewportGeometry& view,
-                           LayeredSceneWidget& widget1,
-                           LayeredSceneWidget& widget2,
-                           LayeredSceneWidget& widget3)
-      {
-        if (&source == &widget1 ||
-            &source == &widget2 ||
-            &source == &widget3)
-        {
-          if (&source != &widget1)
-          {
-            widget1.SetView(view);
-          }
-
-          if (&source != &widget2)
-          {
-            widget2.SetView(view);
-          }
-
-          if (&source != &widget3)
-          {
-            widget3.SetView(view);
-          }
-        }
-      }
-
-
-      void SynchronizeSlice(const LayeredSceneWidget& source,
-                            const SliceGeometry& slice,
-                            LayeredSceneWidget& widget1,
-                            LayeredSceneWidget& widget2,
-                            LayeredSceneWidget& widget3)
-      {
-        if (&source == &widget1 ||
-            &source == &widget2 ||
-            &source == &widget3)
-        {
-          if (&source != &widget1)
-          {
-            widget1.SetSlice(slice);
-          }
-
-          if (&source != &widget2)
-          {
-            widget2.SetSlice(slice);
-          }
-
-          if (&source != &widget3)
-          {
-            widget3.SetSlice(slice);
-          }
-        }
-      }
-
-
-      LayeredSceneWidget* CreateWidget()
-      {
-        std::unique_ptr<LayeredSceneWidget> widget(new LayeredSceneWidget);
-        widget->Register(dynamic_cast<WorldSceneWidget::IWorldObserver&>(*this));
-        widget->Register(dynamic_cast<LayeredSceneWidget::ISliceObserver&>(*this));
-        return widget.release();
-      }
-
-
-      void CreateLayout(BasicApplicationContext& context)
-      {
-        std::unique_ptr<OrthancStone::LayoutWidget> layout(new OrthancStone::LayoutWidget);
-        layout->SetBackgroundCleared(true);
-        //layout->SetBackgroundColor(255,0,0);
-        layout->SetPadding(5);
-
-        OrthancStone::LayoutWidget& layoutA = dynamic_cast<OrthancStone::LayoutWidget&>
-          (layout->AddWidget(new OrthancStone::LayoutWidget));
-        layoutA.SetPadding(0, 0, 0, 0, 5);
-        layoutA.SetVertical();
-        petAxial_ = &dynamic_cast<LayeredSceneWidget&>(layoutA.AddWidget(CreateWidget()));
-        OrthancStone::LayoutWidget& layoutA2 = dynamic_cast<OrthancStone::LayoutWidget&>
-          (layoutA.AddWidget(new OrthancStone::LayoutWidget));
-        layoutA2.SetPadding(0, 0, 0, 0, 5);
-        petSagittal_ = &dynamic_cast<LayeredSceneWidget&>(layoutA2.AddWidget(CreateWidget()));
-        petCoronal_ = &dynamic_cast<LayeredSceneWidget&>(layoutA2.AddWidget(CreateWidget()));
-
-        OrthancStone::LayoutWidget& layoutB = dynamic_cast<OrthancStone::LayoutWidget&>
-          (layout->AddWidget(new OrthancStone::LayoutWidget));
-        layoutB.SetPadding(0, 0, 0, 0, 5);
-        layoutB.SetVertical();
-        ctAxial_ = &dynamic_cast<LayeredSceneWidget&>(layoutB.AddWidget(CreateWidget()));
-        OrthancStone::LayoutWidget& layoutB2 = dynamic_cast<OrthancStone::LayoutWidget&>
-          (layoutB.AddWidget(new OrthancStone::LayoutWidget));
-        layoutB2.SetPadding(0, 0, 0, 0, 5);
-        ctSagittal_ = &dynamic_cast<LayeredSceneWidget&>(layoutB2.AddWidget(CreateWidget()));
-        ctCoronal_ = &dynamic_cast<LayeredSceneWidget&>(layoutB2.AddWidget(CreateWidget()));
-
-        OrthancStone::LayoutWidget& layoutC = dynamic_cast<OrthancStone::LayoutWidget&>
-          (layout->AddWidget(new OrthancStone::LayoutWidget));
-        layoutC.SetPadding(0, 0, 0, 0, 5);
-        layoutC.SetVertical();
-        fusionAxial_ = &dynamic_cast<LayeredSceneWidget&>(layoutC.AddWidget(CreateWidget()));
-        OrthancStone::LayoutWidget& layoutC2 = dynamic_cast<OrthancStone::LayoutWidget&>
-          (layoutC.AddWidget(new OrthancStone::LayoutWidget));
-        layoutC2.SetPadding(0, 0, 0, 0, 5);
-        fusionSagittal_ = &dynamic_cast<LayeredSceneWidget&>(layoutC2.AddWidget(CreateWidget()));
-        fusionCoronal_ = &dynamic_cast<LayeredSceneWidget&>(layoutC2.AddWidget(CreateWidget()));
-  
-        context.SetCentralWidget(layout.release());
-      }
-
-
-    public:
-      virtual void DeclareCommandLineOptions(boost::program_options::options_description& options)
-      {
-        boost::program_options::options_description generic("Sample options");
-        generic.add_options()
-          ("ct", boost::program_options::value<std::string>(), 
-           "Orthanc ID of the CT series")
-          ("pet", boost::program_options::value<std::string>(), 
-           "Orthanc ID of the PET series")
-          ("rt", boost::program_options::value<std::string>(), 
-           "Orthanc ID of the DICOM RT-STRUCT series (optional)")
-          ("threads", boost::program_options::value<unsigned int>()->default_value(3), 
-           "Number of download threads for the CT series")
-          ;
-
-        options.add(generic);    
-      }
-
-      virtual void Initialize(BasicApplicationContext& context,
-                              IStatusBar& statusBar,
-                              const boost::program_options::variables_map& parameters)
-      {
-        using namespace OrthancStone;
-
-        processingEvent_ = true;
-
-        if (parameters.count("ct") != 1 ||
-            parameters.count("pet") != 1)
-        {
-          LOG(ERROR) << "The series ID is missing";
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-        }
-
-        std::string ct = parameters["ct"].as<std::string>();
-        std::string pet = parameters["pet"].as<std::string>();
-        unsigned int threads = parameters["threads"].as<unsigned int>();
-
-        VolumeImage& ctVolume = context.AddSeriesVolume(ct, true /* progressive download */, threads);
-        VolumeImage& petVolume = context.AddSeriesVolume(pet, true /* progressive download */, 1);
-
-        // Take the PET volume as the reference for the slices
-        interactorAxial_ = &dynamic_cast<Interactor&>
-          (context.AddInteractor(new Interactor(*this, petVolume, VolumeProjection_Axial, false)));
-        interactorCoronal_ = &dynamic_cast<Interactor&>
-          (context.AddInteractor(new Interactor(*this, petVolume, VolumeProjection_Coronal, false)));
-        interactorSagittal_ = &dynamic_cast<Interactor&>
-          (context.AddInteractor(new Interactor(*this, petVolume, VolumeProjection_Sagittal, true)));
-
-        CreateLayout(context);
-
-        AddLayer(*ctAxial_, ctVolume, true);
-        AddLayer(*ctCoronal_, ctVolume, true);
-        AddLayer(*ctSagittal_, ctVolume, true);
-
-        AddLayer(*petAxial_, petVolume, false);
-        AddLayer(*petCoronal_, petVolume, false);
-        AddLayer(*petSagittal_, petVolume, false);
-
-        AddLayer(*fusionAxial_, ctVolume, true);
-        AddLayer(*fusionAxial_, petVolume, false);
-        AddLayer(*fusionCoronal_, ctVolume, true);
-        AddLayer(*fusionCoronal_, petVolume, false);
-        AddLayer(*fusionSagittal_, ctVolume, true);
-        AddLayer(*fusionSagittal_, petVolume, false);
-
-        if (parameters.count("rt") == 1)
-        {
-          DicomStructureSet& rtStruct = context.AddStructureSet(parameters["rt"].as<std::string>());
-
-          Vector p = rtStruct.GetStructureCenter(0);
-          interactorAxial_->GetCursor().LookupSliceContainingPoint(p);
-
-          ctAxial_->AddLayer(new DicomStructureSetSlicer(rtStruct));
-          petAxial_->AddLayer(new DicomStructureSetSlicer(rtStruct));
-          fusionAxial_->AddLayer(new DicomStructureSetSlicer(rtStruct));
-        }        
-
-        ConnectSiblingLocations(*ctAxial_, *ctCoronal_, *ctSagittal_); 
-        ConnectSiblingLocations(*petAxial_, *petCoronal_, *petSagittal_); 
-        ConnectSiblingLocations(*fusionAxial_, *fusionCoronal_, *fusionSagittal_); 
-
-        interactorAxial_->AddWidget(*ctAxial_);
-        interactorAxial_->AddWidget(*petAxial_);
-        interactorAxial_->AddWidget(*fusionAxial_);
-        
-        interactorCoronal_->AddWidget(*ctCoronal_);
-        interactorCoronal_->AddWidget(*petCoronal_);
-        interactorCoronal_->AddWidget(*fusionCoronal_);
-        
-        interactorSagittal_->AddWidget(*ctSagittal_);
-        interactorSagittal_->AddWidget(*petSagittal_);
-        interactorSagittal_->AddWidget(*fusionSagittal_);
-
-        processingEvent_ = false;
-
-        statusBar.SetMessage("Use the key \"t\" to toggle the fullscreen mode");
-        statusBar.SetMessage("Use the key \"s\" to reinitialize the layout");
-      }
-
-      virtual void NotifySizeChange(const WorldSceneWidget& source,
-                                    ViewportGeometry& view)
-      {
-        view.FitContent();
-      }
-
-      virtual void NotifyViewChange(const WorldSceneWidget& source,
-                                    const ViewportGeometry& view)
-      {
-        if (!processingEvent_)  // Avoid reentrant calls
-        {
-          processingEvent_ = true;
-
-          SynchronizeView(source, view, *ctAxial_, *petAxial_, *fusionAxial_);
-          SynchronizeView(source, view, *ctCoronal_, *petCoronal_, *fusionCoronal_);
-          SynchronizeView(source, view, *ctSagittal_, *petSagittal_, *fusionSagittal_);
-          
-          processingEvent_ = false;
-        }
-      }
-
-      virtual void NotifySliceContentChange(const LayeredSceneWidget& source,
-                                     const SliceGeometry& slice)
-      {
-        if (!processingEvent_)  // Avoid reentrant calls
-        {
-          processingEvent_ = true;
-
-          SynchronizeSlice(source, slice, *ctAxial_, *petAxial_, *fusionAxial_);
-          SynchronizeSlice(source, slice, *ctCoronal_, *petCoronal_, *fusionCoronal_);
-          SynchronizeSlice(source, slice, *ctSagittal_, *petSagittal_, *fusionSagittal_);
-          
-          processingEvent_ = false;
-        }
-      }
-    };
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Qt/SampleMainWindow.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "SampleMainWindow.h"
-
-/**
- * Don't use "ui_MainWindow.h" instead of <ui_MainWindow.h> below, as
- * this makes CMake unable to detect when the UI file changes.
- **/
-#include <ui_SampleMainWindow.h>
-#include "../../../Applications/Samples/SampleApplicationBase.h"
-
-namespace OrthancStone
-{
-  namespace Samples
-  {
-
-    SampleMainWindow::SampleMainWindow(
-      OrthancStone::NativeStoneApplicationContext& context,
-      OrthancStone::Samples::SampleSingleCanvasApplicationBase& stoneSampleApplication,
-      QWidget *parent) :
-      QStoneMainWindow(context, parent),
-      ui_(new Ui::SampleMainWindow),
-      stoneSampleApplication_(stoneSampleApplication)
-    {
-      ui_->setupUi(this);
-      SetCentralStoneWidget(*ui_->cairoCentralWidget);
-    }
-
-    SampleMainWindow::~SampleMainWindow()
-    {
-      delete ui_;
-    }
-
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Qt/SampleMainWindow.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-#pragma once
-
-#include "../../../Qt/QCairoWidget.h"
-#include "../../../Qt/QStoneMainWindow.h"
-
-namespace Ui 
-{
-  class SampleMainWindow;
-}
-
-namespace OrthancStone
-{
-  namespace Samples
-  {
-
-    class SampleSingleCanvasApplicationBase;
-
-    class SampleMainWindow : public QStoneMainWindow
-    {
-      Q_OBJECT
-
-    private:
-      Ui::SampleMainWindow*   ui_;
-      SampleSingleCanvasApplicationBase&  stoneSampleApplication_;
-
-    public:
-      explicit SampleMainWindow(OrthancStone::NativeStoneApplicationContext& context, SampleSingleCanvasApplicationBase& stoneSampleApplication, QWidget *parent = 0);
-      ~SampleMainWindow();
-    };
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Qt/SampleMainWindow.ui	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>SampleMainWindow</class>
- <widget class="QMainWindow" name="SampleMainWindow">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>903</width>
-    <height>634</height>
-   </rect>
-  </property>
-  <property name="minimumSize">
-   <size>
-    <width>500</width>
-    <height>300</height>
-   </size>
-  </property>
-  <property name="baseSize">
-   <size>
-    <width>500</width>
-    <height>300</height>
-   </size>
-  </property>
-  <property name="windowTitle">
-   <string>Stone of Orthanc</string>
-  </property>
-  <property name="layoutDirection">
-   <enum>Qt::LeftToRight</enum>
-  </property>
-  <widget class="QWidget" name="centralwidget">
-   <property name="sizePolicy">
-    <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-     <horstretch>0</horstretch>
-     <verstretch>0</verstretch>
-    </sizepolicy>
-   </property>
-   <property name="layoutDirection">
-    <enum>Qt::LeftToRight</enum>
-   </property>
-   <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0">
-    <property name="sizeConstraint">
-     <enum>QLayout::SetDefaultConstraint</enum>
-    </property>
-    <item>
-     <widget class="QCairoWidget" name="cairoCentralWidget">
-      <property name="minimumSize">
-       <size>
-        <width>0</width>
-        <height>500</height>
-       </size>
-      </property>
-     </widget>
-    </item>
-   </layout>
-  </widget>
-  <widget class="QMenuBar" name="menubar">
-   <property name="geometry">
-    <rect>
-     <x>0</x>
-     <y>0</y>
-     <width>903</width>
-     <height>22</height>
-    </rect>
-   </property>
-   <widget class="QMenu" name="menuTest">
-    <property name="title">
-     <string>Test</string>
-    </property>
-   </widget>
-   <addaction name="menuTest"/>
-  </widget>
-  <widget class="QStatusBar" name="statusbar"/>
- </widget>
- <customwidgets>
-  <customwidget>
-   <class>QCairoWidget</class>
-   <extends>QGraphicsView</extends>
-   <header location="global">QCairoWidget.h</header>
-  </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Qt/SampleMainWindowWithButtons.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "SampleMainWindow.h"
-
-/**
- * Don't use "ui_MainWindow.h" instead of <ui_MainWindow.h> below, as
- * this makes CMake unable to detect when the UI file changes.
- **/
-#include <ui_SampleMainWindowWithButtons.h>
-#include "../../../Applications/Samples/SampleApplicationBase.h"
-
-namespace OrthancStone
-{
-  namespace Samples
-  {
-
-    SampleMainWindowWithButtons::SampleMainWindowWithButtons(
-      OrthancStone::NativeStoneApplicationContext& context,
-      OrthancStone::Samples::SampleSingleCanvasWithButtonsApplicationBase& stoneSampleApplication,
-      QWidget *parent) :
-      QStoneMainWindow(context, parent),
-      ui_(new Ui::SampleMainWindowWithButtons),
-      stoneSampleApplication_(stoneSampleApplication)
-    {
-      ui_->setupUi(this);
-      SetCentralStoneWidget(*ui_->cairoCentralWidget);
-
-#if QT_VERSION >= 0x050000
-      connect(ui_->toolButton1, &QToolButton::clicked, this, &SampleMainWindowWithButtons::tool1Clicked);
-      connect(ui_->toolButton2, &QToolButton::clicked, this, &SampleMainWindowWithButtons::tool2Clicked);
-      connect(ui_->pushButton1, &QPushButton::clicked, this, &SampleMainWindowWithButtons::pushButton1Clicked);
-      connect(ui_->pushButton1, &QPushButton::clicked, this, &SampleMainWindowWithButtons::pushButton2Clicked);
-#else
-      connect(ui_->toolButton1, SIGNAL(clicked()), this, SLOT(tool1Clicked()));
-      connect(ui_->toolButton2, SIGNAL(clicked()), this, SLOT(tool2Clicked()));
-      connect(ui_->pushButton1, SIGNAL(clicked()), this, SLOT(pushButton1Clicked()));
-      connect(ui_->pushButton1, SIGNAL(clicked()), this, SLOT(pushButton2Clicked()));
-#endif
-
-      std::string pushButton1Name;
-      std::string pushButton2Name;
-      std::string tool1Name;
-      std::string tool2Name;
-      stoneSampleApplication_.GetButtonNames(pushButton1Name, pushButton2Name, tool1Name, tool2Name);
-
-      ui_->toolButton1->setText(QString::fromStdString(tool1Name));
-      ui_->toolButton2->setText(QString::fromStdString(tool2Name));
-      ui_->pushButton1->setText(QString::fromStdString(pushButton1Name));
-      ui_->pushButton2->setText(QString::fromStdString(pushButton2Name));
-    }
-
-    SampleMainWindowWithButtons::~SampleMainWindowWithButtons()
-    {
-      delete ui_;
-    }
-
-    void SampleMainWindowWithButtons::tool1Clicked()
-    {
-      stoneSampleApplication_.OnTool1Clicked();
-    }
-
-    void SampleMainWindowWithButtons::tool2Clicked()
-    {
-      stoneSampleApplication_.OnTool2Clicked();
-    }
-
-    void SampleMainWindowWithButtons::pushButton1Clicked()
-    {
-      stoneSampleApplication_.OnPushButton1Clicked();
-    }
-
-    void SampleMainWindowWithButtons::pushButton2Clicked()
-    {
-      stoneSampleApplication_.OnPushButton2Clicked();
-    }
-
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Qt/SampleMainWindowWithButtons.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-#pragma once
-
-#include "../../../Qt/QCairoWidget.h"
-#include "../../../Qt/QStoneMainWindow.h"
-
-namespace Ui 
-{
-  class SampleMainWindowWithButtons;
-}
-
-namespace OrthancStone
-{
-  namespace Samples
-  {
-
-    class SampleSingleCanvasWithButtonsApplicationBase;
-
-    class SampleMainWindowWithButtons : public QStoneMainWindow
-    {
-      Q_OBJECT
-
-    private:
-      Ui::SampleMainWindowWithButtons*   ui_;
-      SampleSingleCanvasWithButtonsApplicationBase&  stoneSampleApplication_;
-
-    public:
-      explicit SampleMainWindowWithButtons(OrthancStone::NativeStoneApplicationContext& context, SampleSingleCanvasWithButtonsApplicationBase& stoneSampleApplication, QWidget *parent = 0);
-      ~SampleMainWindowWithButtons();
-
-    private slots:
-      void tool1Clicked();
-      void tool2Clicked();
-      void pushButton1Clicked();
-      void pushButton2Clicked();
-    };
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Qt/SampleMainWindowWithButtons.ui	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>SampleMainWindowWithButtons</class>
- <widget class="QMainWindow" name="SampleMainWindowWithButtons">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>903</width>
-    <height>634</height>
-   </rect>
-  </property>
-  <property name="minimumSize">
-   <size>
-    <width>500</width>
-    <height>300</height>
-   </size>
-  </property>
-  <property name="baseSize">
-   <size>
-    <width>500</width>
-    <height>300</height>
-   </size>
-  </property>
-  <property name="windowTitle">
-   <string>Stone of Orthanc</string>
-  </property>
-  <property name="layoutDirection">
-   <enum>Qt::LeftToRight</enum>
-  </property>
-  <widget class="QWidget" name="centralwidget">
-   <property name="sizePolicy">
-    <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-     <horstretch>0</horstretch>
-     <verstretch>0</verstretch>
-    </sizepolicy>
-   </property>
-   <property name="layoutDirection">
-    <enum>Qt::LeftToRight</enum>
-   </property>
-   <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,0">
-    <property name="sizeConstraint">
-     <enum>QLayout::SetDefaultConstraint</enum>
-    </property>
-    <item>
-     <widget class="QCairoWidget" name="cairoCentralWidget">
-      <property name="minimumSize">
-       <size>
-        <width>0</width>
-        <height>500</height>
-       </size>
-      </property>
-     </widget>
-    </item>
-    <item>
-     <widget class="QGroupBox" name="horizontalGroupBox">
-      <property name="minimumSize">
-       <size>
-        <width>0</width>
-        <height>100</height>
-       </size>
-      </property>
-      <property name="maximumSize">
-       <size>
-        <width>16777215</width>
-        <height>100</height>
-       </size>
-      </property>
-      <layout class="QHBoxLayout" name="horizontalLayout">
-       <item>
-        <widget class="QToolButton" name="toolButton1">
-         <property name="text">
-          <string>tool1</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QToolButton" name="toolButton2">
-         <property name="text">
-          <string>tool2</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QPushButton" name="pushButton1">
-         <property name="text">
-          <string>action1</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QPushButton" name="pushButton2">
-         <property name="text">
-          <string>action2</string>
-         </property>
-        </widget>
-       </item>
-      </layout>
-     </widget>
-    </item>
-   </layout>
-  </widget>
-  <widget class="QMenuBar" name="menubar">
-   <property name="geometry">
-    <rect>
-     <x>0</x>
-     <y>0</y>
-     <width>903</width>
-     <height>22</height>
-    </rect>
-   </property>
-   <widget class="QMenu" name="menuTest">
-    <property name="title">
-     <string>Test</string>
-    </property>
-   </widget>
-   <addaction name="menuTest"/>
-  </widget>
-  <widget class="QStatusBar" name="statusbar"/>
- </widget>
- <customwidgets>
-  <customwidget>
-   <class>QCairoWidget</class>
-   <extends>QGraphicsView</extends>
-   <header location="global">QCairoWidget.h</header>
-  </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Qt/SampleQtApplicationRunner.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../../Qt/QtStoneApplicationRunner.h"
-
-#if ORTHANC_ENABLE_QT != 1
-#error this file shall be included only with the ORTHANC_ENABLE_QT set to 1
-#endif
-
-namespace OrthancStone
-{
-  namespace Samples
-  {
-    class SampleQtApplicationRunner : public OrthancStone::QtStoneApplicationRunner
-    {
-    protected:
-      virtual void InitializeMainWindow(OrthancStone::NativeStoneApplicationContext& context)
-      {
-        window_.reset(application_.CreateQtMainWindow());
-      }
-    public:
-      SampleQtApplicationRunner(MessageBroker& broker,
-                                SampleApplicationBase& application)
-        : OrthancStone::QtStoneApplicationRunner(broker, application)
-      {
-      }
-
-    };
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SampleApplicationBase.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../../Applications/IStoneApplication.h"
-#include "../../../Framework/Deprecated/Widgets/WorldSceneWidget.h"
-
-#if ORTHANC_ENABLE_WASM==1
-#include "../../../Platforms/Wasm/WasmPlatformApplicationAdapter.h"
-#include "../../../Platforms/Wasm/Defaults.h"
-#endif
-
-#if ORTHANC_ENABLE_QT==1
-#include "Qt/SampleMainWindow.h"
-#include "Qt/SampleMainWindowWithButtons.h"
-#endif
-
-namespace OrthancStone
-{
-  namespace Samples
-  {
-    class SampleApplicationBase : public IStoneApplication
-    {
-    private:
-      boost::shared_ptr<Deprecated::IWidget>  mainWidget_;
-
-    public:
-      virtual void Initialize(StoneApplicationContext* context,
-                              Deprecated::IStatusBar& statusBar,
-                              const boost::program_options::variables_map& parameters) ORTHANC_OVERRIDE
-      {
-      }
-
-      virtual std::string GetTitle() const ORTHANC_OVERRIDE
-      {
-        return "Stone of Orthanc - Sample";
-      }
-
-      /**
-       * In the basic samples, the commands are handled by the platform adapter and NOT
-       * by the application handler
-      */
-      virtual void HandleSerializedMessage(const char* data) ORTHANC_OVERRIDE {};
-
-
-      virtual void Finalize() ORTHANC_OVERRIDE {}
-
-      virtual void SetCentralWidget(boost::shared_ptr<Deprecated::IWidget> widget) ORTHANC_OVERRIDE
-      {
-        mainWidget_ = widget;
-      }
-
-      virtual boost::shared_ptr<Deprecated::IWidget> GetCentralWidget() ORTHANC_OVERRIDE
-      {
-        return mainWidget_;
-      }
-
-#if ORTHANC_ENABLE_WASM==1
-      // default implementations for a single canvas named "canvas" in the HTML and an emtpy WasmApplicationAdapter
-
-      virtual void InitializeWasm() ORTHANC_OVERRIDE
-      {
-        AttachWidgetToWasmViewport("canvas", mainWidget_);
-      }
-
-      virtual WasmPlatformApplicationAdapter* CreateWasmApplicationAdapter(MessageBroker& broker)
-      {
-        return new WasmPlatformApplicationAdapter(broker, *this);
-      }
-#endif
-
-    };
-
-    // this application actually works in Qt and WASM
-    class SampleSingleCanvasWithButtonsApplicationBase : public SampleApplicationBase
-    {
-public:
-      virtual void OnPushButton1Clicked() {}
-      virtual void OnPushButton2Clicked() {}
-      virtual void OnTool1Clicked() {}
-      virtual void OnTool2Clicked() {}
-
-      virtual void GetButtonNames(std::string& pushButton1,
-                                  std::string& pushButton2,
-                                  std::string& tool1,
-                                  std::string& tool2
-                                  ) {
-        pushButton1 = "action1";
-        pushButton2 = "action2";
-        tool1 = "tool1";
-        tool2 = "tool2";
-      }
-
-#if ORTHANC_ENABLE_QT==1
-      virtual QStoneMainWindow* CreateQtMainWindow() {
-        return new SampleMainWindowWithButtons(dynamic_cast<OrthancStone::NativeStoneApplicationContext&>(*context_), *this);
-      }
-#endif
-
-    };
-
-    // this application actually works in SDL and WASM
-    class SampleSingleCanvasApplicationBase : public SampleApplicationBase
-    {
-public:
-
-#if ORTHANC_ENABLE_QT==1
-      virtual QStoneMainWindow* CreateQtMainWindow() {
-        return new SampleMainWindow(dynamic_cast<OrthancStone::NativeStoneApplicationContext&>(*context_), *this);
-      }
-#endif
-    };
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SampleInteractor.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "SampleApplicationBase.h"
-
-#include "../../../Framework/Widgets/LayeredSceneWidget.h"
-#include "../../../Framework/Widgets/IWorldSceneInteractor.h"
-#include "../../../Framework/Toolbox/ParallelSlicesCursor.h"
-
-namespace OrthancStone
-{
-  namespace Samples
-  {
-    /**
-     * This is a basic mouse interactor for sample applications. It
-     * contains a set of parallel slices in the 3D space. The mouse
-     * wheel events make the widget change the slice that is
-     * displayed.
-     **/
-    class SampleInteractor : public IWorldSceneInteractor
-    {
-    private:
-      ParallelSlicesCursor   cursor_;
-
-    public:
-      SampleInteractor(VolumeImage& volume,
-                       VolumeProjection projection, 
-                       bool reverse)
-      {
-        std::unique_ptr<ParallelSlices> slices(volume.GetGeometry(projection, reverse));
-        cursor_.SetGeometry(*slices);
-      }
-
-      SampleInteractor(ISeriesLoader& series, 
-                       bool reverse)
-      {
-        if (reverse)
-        {
-          std::unique_ptr<ParallelSlices> slices(series.GetGeometry().Reverse());
-          cursor_.SetGeometry(*slices);
-        }
-        else
-        {
-          cursor_.SetGeometry(series.GetGeometry());
-        }
-      }
-
-      SampleInteractor(const ParallelSlices& slices)
-      {
-        cursor_.SetGeometry(slices);
-      }
-
-      ParallelSlicesCursor& GetCursor()
-      {
-        return cursor_;
-      }
-
-      void AddWidget(LayeredSceneWidget& widget)
-      {
-        widget.SetInteractor(*this);
-        widget.SetSlice(cursor_.GetCurrentSlice());
-      }
-
-      virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget,
-                                                          const ViewportGeometry& view,
-                                                          MouseButton button,
-                                                          double x,
-                                                          double y,
-                                                          IStatusBar* statusBar)
-      {
-        return NULL;
-      }
-
-      virtual void MouseOver(CairoContext& context,
-                             WorldSceneWidget& widget,
-                             const ViewportGeometry& view,
-                             double x,
-                             double y,
-                             IStatusBar* statusBar)
-      {
-      }
-
-      virtual void MouseWheel(WorldSceneWidget& widget,
-                              MouseWheelDirection direction,
-                              KeyboardModifiers modifiers,
-                              IStatusBar* statusBar)
-      {
-        if (cursor_.ApplyWheelEvent(direction, modifiers))
-        {
-          dynamic_cast<LayeredSceneWidget&>(widget).SetSlice(cursor_.GetCurrentSlice());
-        }
-      }
-
-      virtual void KeyPressed(WorldSceneWidget& widget,
-                              char key,
-                              KeyboardModifiers modifiers,
-                              IStatusBar* statusBar)
-      {
-      }
-
-      void LookupSliceContainingPoint(LayeredSceneWidget& widget,
-                                      const Vector& p)
-      {
-        if (cursor_.LookupSliceContainingPoint(p))
-        {
-          widget.SetSlice(cursor_.GetCurrentSlice());
-        }
-      }
-    };
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SampleList.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-// The macro "ORTHANC_STONE_SAMPLE" must be set by the CMake script
-
-#if ORTHANC_STONE_SAMPLE == 1
-#include "EmptyApplication.h"
-typedef OrthancStone::Samples::EmptyApplication SampleApplication;
-
-#elif ORTHANC_STONE_SAMPLE == 2
-#include "TestPatternApplication.h"
-typedef OrthancStone::Samples::TestPatternApplication SampleApplication;
-
-#elif ORTHANC_STONE_SAMPLE == 3
-#include "SingleFrameApplication.h"
-typedef OrthancStone::Samples::SingleFrameApplication SampleApplication;
-
-#elif ORTHANC_STONE_SAMPLE == 4
-#include "SingleVolumeApplication.h"
-typedef OrthancStone::Samples::SingleVolumeApplication SampleApplication;
-
-#elif ORTHANC_STONE_SAMPLE == 5
-#include "BasicPetCtFusionApplication.h"
-typedef OrthancStone::Samples::BasicPetCtFusionApplication SampleApplication;
-
-#elif ORTHANC_STONE_SAMPLE == 6
-#include "SynchronizedSeriesApplication.h"
-typedef OrthancStone::Samples::SynchronizedSeriesApplication SampleApplication;
-
-#elif ORTHANC_STONE_SAMPLE == 7
-#include "LayoutPetCtFusionApplication.h"
-typedef OrthancStone::Samples::LayoutPetCtFusionApplication SampleApplication;
-
-#elif ORTHANC_STONE_SAMPLE == 8
-#include "SimpleViewerApplicationSingleFile.h"
-typedef OrthancStone::Samples::SimpleViewerApplication SampleApplication;
-
-#elif ORTHANC_STONE_SAMPLE == 9
-#include "SingleFrameEditorApplication.h"
-typedef OrthancStone::Samples::SingleFrameEditorApplication SampleApplication;
-
-#else
-#error Please set the ORTHANC_STONE_SAMPLE macro
-#endif
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SampleMainNative.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "SampleList.h"
-#if ORTHANC_ENABLE_SDL==1
-#include "../../Sdl/SdlStoneApplicationRunner.h"
-#endif
-#if ORTHANC_ENABLE_QT==1
-#include "Qt/SampleQtApplicationRunner.h"
-#endif
-
-int main(int argc, char* argv[]) 
-{
-  boost::shared_ptr<SampleApplication> sampleStoneApplication(new SampleApplication);
-
-#if ORTHANC_ENABLE_SDL==1
-  OrthancStone::SdlStoneApplicationRunner sdlApplicationRunner(sampleStoneApplication);
-  return sdlApplicationRunner.Execute(argc, argv);
-#endif
-  
-#if ORTHANC_ENABLE_QT==1
-  OrthancStone::Samples::SampleQtApplicationRunner qtAppRunner(sampleStoneApplication);
-  return qtAppRunner.Execute(argc, argv);
-#endif
-}
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SampleMainWasm.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "Platforms/Wasm/WasmWebService.h"
-#include "Platforms/Wasm/WasmViewport.h"
-
-#include <emscripten/emscripten.h>
-
-#include "SampleList.h"
-
-
-OrthancStone::IStoneApplication* CreateUserApplication(OrthancStone::MessageBroker& broker) 
-{
-  return new SampleApplication(broker);
-}
-
-OrthancStone::WasmPlatformApplicationAdapter* CreateWasmApplicationAdapter(OrthancStone::MessageBroker& broker, OrthancStone::IStoneApplication* application)
-{
-  return dynamic_cast<SampleApplication*>(application)->CreateWasmApplicationAdapter(broker);
-}
\ No newline at end of file
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Samples-status.md	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-Executable versions
-================
-Generic options
-----------------------
-```
-("help", "Display this help and exit")
-("verbose", "Be verbose in logs")
-("orthanc", boost::program_options::value<std::string>()
-  ->default_value("http://localhost:8042/"),
-  "URL to the Orthanc server")
-("username", "Username for the Orthanc server")
-("password", "Password for the Orthanc server")
-("https-verify", boost::program_options::value<bool>()
-  ->default_value(true), "Check HTTPS certificates")
-```
-OrthancStoneSimpleViewer
--------------------------------------
-- Options:
-    ```
-    - "studyId", std::string, "Orthanc ID of the study"
-    ```
-- study loading works OK
-- Invert does not work:
-```
-void SimpleViewerApplication::ExecuteAction(SimpleViewerApplication::Actions action)
-  {
-    // TODO
-  }
-```
-
-OrthancStoneSimpleViewerSingleFile
--------------------------------------
-- Options:
-    ```
-    - "studyId", std::string, "Orthanc ID of the study"
-    ```
-
-Study loading works.
-
-The `line` and `circle` buttons work and call this:
-```
-virtual void OnTool1Clicked()
-{
-  currentTool_ = Tools_LineMeasure;
-}
-
-virtual void OnTool2Clicked()
-{
-  currentTool_ = Tools_CircleMeasure;
-}
-```
-The `action1` and `action2` buttons are not connected
-
-The following is displayed in the console at launch time:
-```
-W0313 12:20:12.790449 NativeStoneApplicationRunner.cpp:55] Use the key "s" to reinitialize the layout
-W0313 12:20:12.790449 NativeStoneApplicationRunner.cpp:55] Use the key "n" to go to next image in the main viewport
-```
-However, when looking at `MainWidgetInteractor::KeyPressed` (`SimpleViewerApplicationSingleFile.h:169`), only the following is processed:
-- 's': reset layout
-- 'l': select line tool
-- 'c': select circle tool
-
-OrthancStoneSingleFrame
--------------------------------------
-```
-generic.add_options()
-("instance", boost::program_options::value<std::string>(), 
-"Orthanc ID of the instance")
-("frame", boost::program_options::value<unsigned int>()
-  ->default_value(0),
-"Number of the frame, for multi-frame DICOM instances")
-("smooth", boost::program_options::value<bool>()
-  ->default_value(true), 
-"Enable bilinear interpolation to smooth the image");
-```
-only key handled in `KeyPressed` is `s` to call `widget.FitContent()`
-
-
-OrthancStoneSingleFrameEditor
--------------------------------------
-```
-generic.add_options()
-("instance", boost::program_options::value<std::string>(),
-"Orthanc ID of the instance")
-("frame", boost::program_options::value<unsigned int>()
-  ->default_value(0),
-"Number of the frame, for multi-frame DICOM instances");
-```
-Available commands in `KeyPressed` (`SingleFrameEditorApplication.h:280`): 
-- 'a' widget.FitContent()
-- 'c' Crop tool
-- 'm' Mask tool
-- 'd' dump to json and diplay result (?)
-- 'e' export current view to Dicom with dummy tags (?)
-- 'i' wdiget.SwitchInvert
-- 't' Move tool
-- 'n' switch between nearest and bilinear interpolation
-- 'r' Rotate tool
-- 's' Resize tool
-- 'w' Windowing tool
-- 'ctrl+y' redo
-- 'ctrl+z' undo
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/AppStatus.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include <string>
-
-
-namespace SimpleViewer
-{
-  struct AppStatus
-  {
-    std::string patientId;
-    std::string studyDescription;
-    std::string currentInstanceIdInMainViewport;
-    // note: if you add members here, update the serialization code below and deserialization in simple-viewer.ts -> onAppStatusUpdated()
-
-
-    AppStatus()
-    {
-    }
-
-    void ToJson(Json::Value &output) const
-    {
-      output["patientId"] = patientId;
-      output["studyDescription"] = studyDescription;
-      output["currentInstanceIdInMainViewport"] = currentInstanceIdInMainViewport;
-    }
-  };
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/MainWidgetInteractor.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "MainWidgetInteractor.h"
-
-#include "SimpleViewerApplication.h"
-
-namespace SimpleViewer {
-
-  Deprecated::IWorldSceneMouseTracker* MainWidgetInteractor::CreateMouseTracker(Deprecated::WorldSceneWidget& widget,
-                                                                    const Deprecated::ViewportGeometry& view,
-                                                                    MouseButton button,
-                                                                    KeyboardModifiers modifiers,
-                                                                    int viewportX,
-                                                                    int viewportY,
-                                                                    double x,
-                                                                    double y,
-                                                                    Deprecated::IStatusBar* statusBar,
-                                                                    const std::vector<Deprecated::Touch>& displayTouches)
-  {
-    if (button == MouseButton_Left)
-    {
-      if (application_.GetCurrentTool() == Tool_LineMeasure)
-      {
-        return new Deprecated::LineMeasureTracker(statusBar, dynamic_cast<Deprecated::SliceViewerWidget&>(widget).GetSlice(),
-                                      x, y, 255, 0, 0, application_.GetFont());
-      }
-      else if (application_.GetCurrentTool() == Tool_CircleMeasure)
-      {
-        return new Deprecated::CircleMeasureTracker(statusBar, dynamic_cast<Deprecated::SliceViewerWidget&>(widget).GetSlice(),
-                                        x, y, 255, 0, 0, application_.GetFont());
-      }
-      else if (application_.GetCurrentTool() == Tool_Crop)
-      {
-        // TODO
-      }
-      else if (application_.GetCurrentTool() == Tool_Windowing)
-      {
-        // TODO
-      }
-      else if (application_.GetCurrentTool() == Tool_Zoom)
-      {
-        // TODO
-      }
-      else if (application_.GetCurrentTool() == Tool_Pan)
-      {
-        // TODO
-      }
-    }
-    return NULL;
-  }
-
-  void MainWidgetInteractor::MouseOver(CairoContext& context,
-                                       Deprecated::WorldSceneWidget& widget,
-                                       const Deprecated::ViewportGeometry& view,
-                                       double x,
-                                       double y,
-                                       Deprecated::IStatusBar* statusBar)
-  {
-    if (statusBar != NULL)
-    {
-      Vector p = dynamic_cast<Deprecated::SliceViewerWidget&>(widget).GetSlice().MapSliceToWorldCoordinates(x, y);
-
-      char buf[64];
-      sprintf(buf, "X = %.02f Y = %.02f Z = %.02f (in cm)",
-              p[0] / 10.0, p[1] / 10.0, p[2] / 10.0);
-      statusBar->SetMessage(buf);
-    }
-  }
-
-  void MainWidgetInteractor::MouseWheel(Deprecated::WorldSceneWidget& widget,
-                                        MouseWheelDirection direction,
-                                        KeyboardModifiers modifiers,
-                                        Deprecated::IStatusBar* statusBar)
-  {
-  }
-
-  void MainWidgetInteractor::KeyPressed(Deprecated::WorldSceneWidget& widget,
-                                        KeyboardKeys key,
-                                        char keyChar,
-                                        KeyboardModifiers modifiers,
-                                        Deprecated::IStatusBar* statusBar)
-  {
-    switch (keyChar)
-    {
-    case 's':
-      widget.FitContent();
-      break;
-
-    default:
-      break;
-    }
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/MainWidgetInteractor.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#pragma once
-
-#include "../../../../Framework/Deprecated/Widgets/IWorldSceneInteractor.h"
-
-using namespace OrthancStone;
-
-namespace SimpleViewer {
-
-  class SimpleViewerApplication;
-
-  class MainWidgetInteractor : public Deprecated::IWorldSceneInteractor
-  {
-  private:
-    SimpleViewerApplication&  application_;
-
-  public:
-    MainWidgetInteractor(SimpleViewerApplication&  application) :
-      application_(application)
-    {
-    }
-
-    /**
-        WorldSceneWidget: 
-    */
-    virtual Deprecated::IWorldSceneMouseTracker* CreateMouseTracker(Deprecated::WorldSceneWidget& widget,
-                                                                    const Deprecated::ViewportGeometry& view,
-                                                                    MouseButton button,
-                                                                    KeyboardModifiers modifiers,
-                                                                    int viewportX,
-                                                                    int viewportY,
-                                                                    double x,
-                                                                    double y,
-                                                                    Deprecated::IStatusBar* statusBar,
-                                                                    const std::vector<Deprecated::Touch>& displayTouches);
-
-    virtual void MouseOver(CairoContext& context,
-                           Deprecated::WorldSceneWidget& widget,
-                           const Deprecated::ViewportGeometry& view,
-                           double x,
-                           double y,
-                           Deprecated::IStatusBar* statusBar);
-
-    virtual void MouseWheel(Deprecated::WorldSceneWidget& widget,
-                            MouseWheelDirection direction,
-                            KeyboardModifiers modifiers,
-                            Deprecated::IStatusBar* statusBar);
-
-    virtual void KeyPressed(Deprecated::WorldSceneWidget& widget,
-                            KeyboardKeys key,
-                            char keyChar,
-                            KeyboardModifiers modifiers,
-                            Deprecated::IStatusBar* statusBar);
-  };
-
-
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/Qt/SimpleViewerMainWindow.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "SimpleViewerMainWindow.h"
-
-/**
- * Don't use "ui_MainWindow.h" instead of <ui_MainWindow.h> below, as
- * this makes CMake unable to detect when the UI file changes.
- **/
-#include <ui_SimpleViewerMainWindow.h>
-#include "../../SimpleViewerApplication.h"
-
-
-namespace SimpleViewer
-{
-  template<typename T, typename U>
-  bool ExecuteCommand(U* handler, const T& command)
-  {
-    std::string serializedCommand = StoneSerialize(command);
-    StoneDispatchToHandler(serializedCommand, handler);
-  }
-
-  SimpleViewerMainWindow::SimpleViewerMainWindow(
-    OrthancStone::NativeStoneApplicationContext& context,
-    SimpleViewerApplication& stoneApplication,
-    QWidget *parent) :
-    QStoneMainWindow(context, parent),
-    ui_(new Ui::SimpleViewerMainWindow),
-    stoneApplication_(stoneApplication)
-  {
-    ui_->setupUi(this);
-    SetCentralStoneWidget(*ui_->cairoCentralWidget);
-
-#if QT_VERSION >= 0x050000
-    connect(ui_->toolButtonCrop, &QToolButton::clicked, this, &SimpleViewerMainWindow::cropClicked);
-    connect(ui_->pushButtonUndoCrop, &QToolButton::clicked, this, &SimpleViewerMainWindow::undoCropClicked);
-    connect(ui_->toolButtonLine, &QToolButton::clicked, this, &SimpleViewerMainWindow::lineClicked);
-    connect(ui_->toolButtonCircle, &QToolButton::clicked, this, &SimpleViewerMainWindow::circleClicked);
-    connect(ui_->toolButtonWindowing, &QToolButton::clicked, this, &SimpleViewerMainWindow::windowingClicked);
-    connect(ui_->pushButtonRotate, &QPushButton::clicked, this, &SimpleViewerMainWindow::rotateClicked);
-    connect(ui_->pushButtonInvert, &QPushButton::clicked, this, &SimpleViewerMainWindow::invertClicked);
-#else
-    connect(ui_->toolButtonCrop, SIGNAL(clicked()), this, SLOT(cropClicked()));
-    connect(ui_->toolButtonLine, SIGNAL(clicked()), this, SLOT(lineClicked()));
-    connect(ui_->toolButtonCircle, SIGNAL(clicked()), this, SLOT(circleClicked()));
-    connect(ui_->toolButtonWindowing, SIGNAL(clicked()), this, SLOT(windowingClicked()));
-    connect(ui_->pushButtonUndoCrop, SIGNAL(clicked()), this, SLOT(undoCropClicked()));
-    connect(ui_->pushButtonRotate, SIGNAL(clicked()), this, SLOT(rotateClicked()));
-    connect(ui_->pushButtonInvert, SIGNAL(clicked()), this, SLOT(invertClicked()));
-#endif
-  }
-
-  SimpleViewerMainWindow::~SimpleViewerMainWindow()
-  {
-    delete ui_;
-  }
-
-  void SimpleViewerMainWindow::cropClicked()
-  {
-    stoneApplication_.ExecuteCommand(SelectTool(Tool_Crop));
-  }
-
-  void SimpleViewerMainWindow::undoCropClicked()
-  {
-    stoneApplication_.ExecuteCommand(Action(ActionType_UndoCrop));
-  }
-
-  void SimpleViewerMainWindow::lineClicked()
-  {
-    stoneApplication_.ExecuteCommand(SelectTool(Tool_LineMeasure));
-  }
-
-  void SimpleViewerMainWindow::circleClicked()
-  {
-    stoneApplication_.ExecuteCommand(SelectTool(Tool_CircleMeasure));
-  }
-
-  void SimpleViewerMainWindow::windowingClicked()
-  {
-    stoneApplication_.ExecuteCommand(SelectTool(Tool_Windowing));
-  }
-
-  void SimpleViewerMainWindow::rotateClicked()
-  {
-    stoneApplication_.ExecuteCommand(Action(ActionType_Rotate));
-  }
-
-  void SimpleViewerMainWindow::invertClicked()
-  {
-    stoneApplication_.ExecuteCommand(Action(ActionType_Invert));
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/Qt/SimpleViewerMainWindow.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-#pragma once
-
-#include <Applications/Qt/QCairoWidget.h>
-#include <Applications/Qt/QStoneMainWindow.h>
-
-namespace Ui 
-{
-  class SimpleViewerMainWindow;
-}
-
-using namespace OrthancStone;
-
-namespace SimpleViewer
-{
-  class SimpleViewerApplication;
-
-  class SimpleViewerMainWindow : public QStoneMainWindow
-  {
-    Q_OBJECT
-
-  private:
-    Ui::SimpleViewerMainWindow*   ui_;
-    SimpleViewerApplication&      stoneApplication_;
-
-  public:
-    explicit SimpleViewerMainWindow(OrthancStone::NativeStoneApplicationContext& context, SimpleViewerApplication& stoneApplication, QWidget *parent = 0);
-    ~SimpleViewerMainWindow();
-
-  private slots:
-    void cropClicked();
-    void undoCropClicked();
-    void rotateClicked();
-    void windowingClicked();
-    void lineClicked();
-    void circleClicked();
-    void invertClicked();
-  };
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/Qt/SimpleViewerMainWindow.ui	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,151 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>SimpleViewerMainWindow</class>
- <widget class="QMainWindow" name="SimpleViewerMainWindow">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>903</width>
-    <height>634</height>
-   </rect>
-  </property>
-  <property name="minimumSize">
-   <size>
-    <width>500</width>
-    <height>300</height>
-   </size>
-  </property>
-  <property name="baseSize">
-   <size>
-    <width>500</width>
-    <height>300</height>
-   </size>
-  </property>
-  <property name="windowTitle">
-   <string>Stone of Orthanc</string>
-  </property>
-  <property name="layoutDirection">
-   <enum>Qt::LeftToRight</enum>
-  </property>
-  <widget class="QWidget" name="centralwidget">
-   <property name="sizePolicy">
-    <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-     <horstretch>0</horstretch>
-     <verstretch>0</verstretch>
-    </sizepolicy>
-   </property>
-   <property name="layoutDirection">
-    <enum>Qt::LeftToRight</enum>
-   </property>
-   <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,0">
-    <property name="sizeConstraint">
-     <enum>QLayout::SetDefaultConstraint</enum>
-    </property>
-    <item>
-     <widget class="QCairoWidget" name="cairoCentralWidget">
-      <property name="minimumSize">
-       <size>
-        <width>0</width>
-        <height>500</height>
-       </size>
-      </property>
-     </widget>
-    </item>
-    <item>
-     <widget class="QGroupBox" name="horizontalGroupBox">
-      <property name="minimumSize">
-       <size>
-        <width>0</width>
-        <height>100</height>
-       </size>
-      </property>
-      <property name="maximumSize">
-       <size>
-        <width>16777215</width>
-        <height>100</height>
-       </size>
-      </property>
-      <layout class="QHBoxLayout" name="horizontalLayout">
-       <item>
-        <widget class="QToolButton" name="toolButtonWindowing">
-         <property name="text">
-          <string>windowing</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QToolButton" name="toolButtonCrop">
-         <property name="text">
-          <string>crop</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QPushButton" name="pushButtonUndoCrop">
-         <property name="text">
-          <string>undo crop</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QToolButton" name="toolButtonLine">
-         <property name="text">
-          <string>line</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QToolButton" name="toolButtonCircle">
-         <property name="text">
-          <string>circle</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QPushButton" name="pushButtonRotate">
-         <property name="text">
-          <string>rotate</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QPushButton" name="pushButtonInvert">
-         <property name="text">
-          <string>invert</string>
-         </property>
-        </widget>
-       </item>
-      </layout>
-     </widget>
-    </item>
-   </layout>
-  </widget>
-  <widget class="QMenuBar" name="menubar">
-   <property name="geometry">
-    <rect>
-     <x>0</x>
-     <y>0</y>
-     <width>903</width>
-     <height>22</height>
-    </rect>
-   </property>
-   <widget class="QMenu" name="menuTest">
-    <property name="title">
-     <string>Test</string>
-    </property>
-   </widget>
-   <addaction name="menuTest"/>
-  </widget>
-  <widget class="QStatusBar" name="statusbar"/>
- </widget>
- <customwidgets>
-  <customwidget>
-   <class>QCairoWidget</class>
-   <extends>QGraphicsView</extends>
-   <header location="global">QCairoWidget.h</header>
-  </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/Qt/mainQt.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "Applications/Qt/QtStoneApplicationRunner.h"
-
-#include "../../SimpleViewerApplication.h"
-#include "Framework/Messages/MessageBroker.h"
-
-
-int main(int argc, char* argv[]) 
-{
-  OrthancStone::MessageBroker broker;
-  SimpleViewer::SimpleViewerApplication stoneApplication(broker);
-
-  OrthancStone::QtStoneApplicationRunner qtAppRunner(broker, stoneApplication);
-  return qtAppRunner.Execute(argc, argv);
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/SimpleViewerApplication.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,225 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "SimpleViewerApplication.h"
-
-#if ORTHANC_ENABLE_QT == 1
-#  include "Qt/SimpleViewerMainWindow.h"
-#endif
-
-#if ORTHANC_ENABLE_WASM == 1
-#  include <Platforms/Wasm/WasmViewport.h>
-#endif
-
-namespace SimpleViewer
-{
-
-  void SimpleViewerApplication::Initialize(StoneApplicationContext* context,
-                                           Deprecated::IStatusBar& statusBar,
-                                           const boost::program_options::variables_map& parameters)
-  {
-    context_ = context;
-    statusBar_ = &statusBar;
-
-    {// initialize viewports and layout
-      mainLayout_ = new Deprecated::LayoutWidget("main-layout");
-      mainLayout_->SetPadding(10);
-      mainLayout_->SetBackgroundCleared(true);
-      mainLayout_->SetBackgroundColor(0, 0, 0);
-      mainLayout_->SetHorizontal();
-
-      thumbnailsLayout_ = new Deprecated::LayoutWidget("thumbnail-layout");
-      thumbnailsLayout_->SetPadding(10);
-      thumbnailsLayout_->SetBackgroundCleared(true);
-      thumbnailsLayout_->SetBackgroundColor(50, 50, 50);
-      thumbnailsLayout_->SetVertical();
-
-      mainWidget_ = new Deprecated::SliceViewerWidget(IObserver::GetBroker(), "main-viewport");
-      //mainWidget_->RegisterObserver(*this);
-
-      // hierarchy
-      mainLayout_->AddWidget(thumbnailsLayout_);
-      mainLayout_->AddWidget(mainWidget_);
-
-      // sources
-      smartLoader_.reset(new Deprecated::SmartLoader(IObserver::GetBroker(), context->GetOrthancApiClient()));
-      smartLoader_->SetImageQuality(Deprecated::SliceImageQuality_FullPam);
-
-      mainLayout_->SetTransmitMouseOver(true);
-      mainWidgetInteractor_.reset(new MainWidgetInteractor(*this));
-      mainWidget_->SetInteractor(*mainWidgetInteractor_);
-      thumbnailInteractor_.reset(new ThumbnailInteractor(*this));
-    }
-
-    statusBar.SetMessage("Use the key \"s\" to reinitialize the layout");
-    statusBar.SetMessage("Use the key \"n\" to go to next image in the main viewport");
-
-
-    if (parameters.count("studyId") < 1)
-    {
-      LOG(WARNING) << "The study ID is missing, will take the first studyId found in Orthanc";
-      context->GetOrthancApiClient().GetJsonAsync("/studies", new Callable<SimpleViewerApplication, Deprecated::OrthancApiClient::JsonResponseReadyMessage>(*this, &SimpleViewerApplication::OnStudyListReceived));
-    }
-    else
-    {
-      SelectStudy(parameters["studyId"].as<std::string>());
-    }
-  }
-
-
-  void SimpleViewerApplication::DeclareStartupOptions(boost::program_options::options_description& options)
-  {
-    boost::program_options::options_description generic("Sample options");
-    generic.add_options()
-        ("studyId", boost::program_options::value<std::string>(),
-         "Orthanc ID of the study")
-        ;
-
-    options.add(generic);
-  }
-
-  void SimpleViewerApplication::OnStudyListReceived(const Deprecated::OrthancApiClient::JsonResponseReadyMessage& message)
-  {
-    const Json::Value& response = message.GetJson();
-
-    if (response.isArray() &&
-        response.size() >= 1)
-    {
-      SelectStudy(response[0].asString());
-    }
-  }
-  void SimpleViewerApplication::OnStudyReceived(const Deprecated::OrthancApiClient::JsonResponseReadyMessage& message)
-  {
-    const Json::Value& response = message.GetJson();
-
-    if (response.isObject() && response["Series"].isArray())
-    {
-      for (size_t i=0; i < response["Series"].size(); i++)
-      {
-        context_->GetOrthancApiClient().GetJsonAsync("/series/" + response["Series"][(int)i].asString(), new Callable<SimpleViewerApplication, Deprecated::OrthancApiClient::JsonResponseReadyMessage>(*this, &SimpleViewerApplication::OnSeriesReceived));
-      }
-    }
-  }
-
-  void SimpleViewerApplication::OnSeriesReceived(const Deprecated::OrthancApiClient::JsonResponseReadyMessage& message)
-  {
-    const Json::Value& response = message.GetJson();
-
-    if (response.isObject() &&
-        response["Instances"].isArray() &&
-        response["Instances"].size() > 0)
-    {
-      // keep track of all instances IDs
-      const std::string& seriesId = response["ID"].asString();
-      seriesTags_[seriesId] = response;
-      instancesIdsPerSeriesId_[seriesId] = std::vector<std::string>();
-      for (size_t i = 0; i < response["Instances"].size(); i++)
-      {
-        const std::string& instanceId = response["Instances"][static_cast<int>(i)].asString();
-        instancesIdsPerSeriesId_[seriesId].push_back(instanceId);
-      }
-
-      // load the first instance in the thumbnail
-      LoadThumbnailForSeries(seriesId, instancesIdsPerSeriesId_[seriesId][0]);
-
-      // if this is the first thumbnail loaded, load the first instance in the mainWidget
-      if (mainWidget_->GetLayerCount() == 0)
-      {
-        smartLoader_->SetFrameInWidget(*mainWidget_, 0, instancesIdsPerSeriesId_[seriesId][0], 0);
-      }
-    }
-  }
-
-  void SimpleViewerApplication::LoadThumbnailForSeries(const std::string& seriesId, const std::string& instanceId)
-  {
-    LOG(INFO) << "Loading thumbnail for series " << seriesId;
-    
-    Deprecated::SliceViewerWidget* thumbnailWidget = 
-      new Deprecated::SliceViewerWidget(IObserver::GetBroker(), "thumbnail-series-" + seriesId);
-    thumbnails_.push_back(thumbnailWidget);
-    thumbnailsLayout_->AddWidget(thumbnailWidget);
-    
-    thumbnailWidget->RegisterObserverCallback(
-      new Callable<SimpleViewerApplication, Deprecated::SliceViewerWidget::GeometryChangedMessage>
-      (*this, &SimpleViewerApplication::OnWidgetGeometryChanged));
-    
-    smartLoader_->SetFrameInWidget(*thumbnailWidget, 0, instanceId, 0);
-    thumbnailWidget->SetInteractor(*thumbnailInteractor_);
-  }
-
-  void SimpleViewerApplication::SelectStudy(const std::string& studyId)
-  {
-    context_->GetOrthancApiClient().GetJsonAsync("/studies/" + studyId, new Callable<SimpleViewerApplication, Deprecated::OrthancApiClient::JsonResponseReadyMessage>(*this, &SimpleViewerApplication::OnStudyReceived));
-  }
-
-  void SimpleViewerApplication::OnWidgetGeometryChanged(const Deprecated::SliceViewerWidget::GeometryChangedMessage& message)
-  {
-    // TODO: The "const_cast" could probably be replaced by "mainWidget_"
-    const_cast<Deprecated::SliceViewerWidget&>(message.GetOrigin()).FitContent();
-  }
-
-  void SimpleViewerApplication::SelectSeriesInMainViewport(const std::string& seriesId)
-  {
-    smartLoader_->SetFrameInWidget(*mainWidget_, 0, instancesIdsPerSeriesId_[seriesId][0], 0);
-  }
-
-  bool SimpleViewerApplication::Handle(const StoneSampleCommands::SelectTool& value)
-  {
-    currentTool_ = value.tool;
-    return true;
-  }
-
-  bool SimpleViewerApplication::Handle(const StoneSampleCommands::Action& value)
-  {
-    switch (value.type)
-    {
-    case ActionType_Invert:
-      // TODO
-      break;
-    case ActionType_UndoCrop:
-      // TODO
-      break;
-    case ActionType_Rotate:
-      // TODO
-      break;
-    default:
-      throw std::runtime_error("Action type not supported");
-    }
-    return true;
-  }
-
-#if ORTHANC_ENABLE_QT==1
-  QStoneMainWindow* SimpleViewerApplication::CreateQtMainWindow()
-  {
-    return new SimpleViewerMainWindow(dynamic_cast<OrthancStone::NativeStoneApplicationContext&>(*context_), *this);
-  }
-#endif
-
-#if ORTHANC_ENABLE_WASM==1
-  void SimpleViewerApplication::InitializeWasm() {
-
-    AttachWidgetToWasmViewport("canvasThumbnails", thumbnailsLayout_);
-    AttachWidgetToWasmViewport("canvasMain", mainWidget_);
-  }
-#endif
-
-
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/SimpleViewerApplication.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,175 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
- /*
- This header contains the command definitions for the sample applications
- */
-#include "Applications/Samples/StoneSampleCommands_generated.hpp"
-using namespace StoneSampleCommands;
-
-#include "Applications/IStoneApplication.h"
-
-#include "../../../../Framework/Deprecated/Layers/CircleMeasureTracker.h"
-#include "../../../../Framework/Deprecated/Layers/LineMeasureTracker.h"
-#include "../../../../Framework/Deprecated/SmartLoader.h"
-#include "../../../../Framework/Deprecated/Widgets/LayoutWidget.h"
-#include "../../../../Framework/Deprecated/Widgets/SliceViewerWidget.h"
-#include "../../../../Framework/Messages/IObserver.h"
-
-#if ORTHANC_ENABLE_WASM==1
-#include "Platforms/Wasm/WasmPlatformApplicationAdapter.h"
-#include "Platforms/Wasm/Defaults.h"
-#endif
-
-#if ORTHANC_ENABLE_QT==1
-#include "Qt/SimpleViewerMainWindow.h"
-#endif
-
-#include <Core/Images/Font.h>
-#include <Core/Logging.h>
-
-#include "ThumbnailInteractor.h"
-#include "MainWidgetInteractor.h"
-#include "AppStatus.h"
-
-using namespace OrthancStone;
-
-
-namespace SimpleViewer
-{
-
-  class SimpleViewerApplication
-    : public IStoneApplication
-    , public IObserver
-    , public IObservable
-    , public StoneSampleCommands::IHandler
-  {
-  public:
-
-    struct StatusUpdatedMessage : public IMessage
-    {
-      ORTHANC_STONE_MESSAGE(__FILE__, __LINE__);
-
-      const AppStatus& status_;
-
-      StatusUpdatedMessage(const AppStatus& status)
-        : status_(status)
-      {
-      }
-    };
-
-  private:
-    Tool                                currentTool_;
-
-    std::unique_ptr<MainWidgetInteractor> mainWidgetInteractor_;
-    std::unique_ptr<ThumbnailInteractor>  thumbnailInteractor_;
-    Deprecated::LayoutWidget*                       mainLayout_;
-    Deprecated::LayoutWidget*                       thumbnailsLayout_;
-    Deprecated::SliceViewerWidget*                  mainWidget_;
-    std::vector<Deprecated::SliceViewerWidget*>     thumbnails_;
-    std::map<std::string, std::vector<std::string> > instancesIdsPerSeriesId_;
-    std::map<std::string, Json::Value>  seriesTags_;
-    unsigned int                        currentInstanceIndex_;
-    Deprecated::WidgetViewport*       wasmViewport1_;
-    Deprecated::WidgetViewport*       wasmViewport2_;
-
-    Deprecated::IStatusBar*                         statusBar_;
-    std::unique_ptr<Deprecated::SmartLoader>          smartLoader_;
-
-    Orthanc::Font                       font_;
-
-  public:
-    SimpleViewerApplication(MessageBroker& broker) :
-      IObserver(broker),
-      IObservable(broker),
-      currentTool_(StoneSampleCommands::Tool_LineMeasure),
-      mainLayout_(NULL),
-      currentInstanceIndex_(0),
-      wasmViewport1_(NULL),
-      wasmViewport2_(NULL)
-    {
-      font_.LoadFromResource(Orthanc::EmbeddedResources::FONT_UBUNTU_MONO_BOLD_16);
-    }
-
-    virtual void Finalize() ORTHANC_OVERRIDE {}
-    virtual Deprecated::IWidget* GetCentralWidget() ORTHANC_OVERRIDE {return mainLayout_;}
-
-    virtual void DeclareStartupOptions(boost::program_options::options_description& options) ORTHANC_OVERRIDE;
-    virtual void Initialize(StoneApplicationContext* context,
-                            Deprecated::IStatusBar& statusBar,
-                            const boost::program_options::variables_map& parameters) ORTHANC_OVERRIDE;
-
-    void OnStudyListReceived(const Deprecated::OrthancApiClient::JsonResponseReadyMessage& message);
-
-    void OnStudyReceived(const Deprecated::OrthancApiClient::JsonResponseReadyMessage& message);
-
-    void OnSeriesReceived(const Deprecated::OrthancApiClient::JsonResponseReadyMessage& message);
-
-    void LoadThumbnailForSeries(const std::string& seriesId, const std::string& instanceId);
-
-    void SelectStudy(const std::string& studyId);
-
-    void OnWidgetGeometryChanged(const Deprecated::SliceViewerWidget::GeometryChangedMessage& message);
-
-    void SelectSeriesInMainViewport(const std::string& seriesId);
-
-
-    Tool GetCurrentTool() const
-    {
-      return currentTool_;
-    }
-
-    const Orthanc::Font& GetFont() const
-    {
-      return font_;
-    }
-
-    // ExecuteAction method was empty (its body was a single "TODO" comment)
-    virtual bool Handle(const SelectTool& value) ORTHANC_OVERRIDE;
-    virtual bool Handle(const Action& value) ORTHANC_OVERRIDE;
-
-    template<typename T>
-    bool ExecuteCommand(const T& cmd)
-    {
-      std::string cmdStr = StoneSampleCommands::StoneSerialize(cmd);
-      return StoneSampleCommands::StoneDispatchToHandler(cmdStr, this);
-    }
-
-    virtual void HandleSerializedMessage(const char* data) ORTHANC_OVERRIDE
-    {
-      StoneSampleCommands::StoneDispatchToHandler(data, this);
-    }
-
-    virtual std::string GetTitle() const ORTHANC_OVERRIDE {return "SimpleViewer";}
-
-#if ORTHANC_ENABLE_WASM==1
-    virtual void InitializeWasm() ORTHANC_OVERRIDE;
-#endif
-
-#if ORTHANC_ENABLE_QT==1
-    virtual QStoneMainWindow* CreateQtMainWindow();
-#endif
-  };
-
-
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/ThumbnailInteractor.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "ThumbnailInteractor.h"
-
-#include "SimpleViewerApplication.h"
-
-namespace SimpleViewer {
-
-  Deprecated::IWorldSceneMouseTracker* ThumbnailInteractor::CreateMouseTracker(Deprecated::WorldSceneWidget& widget,
-                                                                   const Deprecated::ViewportGeometry& view,
-                                                                   MouseButton button,
-                                                                   KeyboardModifiers modifiers,
-                                                                   int viewportX,
-                                                                   int viewportY,
-                                                                   double x,
-                                                                   double y,
-                                                                   Deprecated::IStatusBar* statusBar,
-                                                                   const std::vector<Deprecated::Touch>& displayTouches)
-  {
-    if (button == MouseButton_Left)
-    {
-      statusBar->SetMessage("selected thumbnail " + widget.GetName());
-      std::string seriesId = widget.GetName().substr(strlen("thumbnail-series-"));
-      application_.SelectSeriesInMainViewport(seriesId);
-    }
-    return NULL;
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/ThumbnailInteractor.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,77 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../../../Framework/Deprecated/Widgets/IWorldSceneInteractor.h"
-
-using namespace OrthancStone;
-
-namespace SimpleViewer {
-
-  class SimpleViewerApplication;
-
-  class ThumbnailInteractor : public Deprecated::IWorldSceneInteractor
-  {
-  private:
-    SimpleViewerApplication&  application_;
-  public:
-    ThumbnailInteractor(SimpleViewerApplication&  application) :
-      application_(application)
-    {
-    }
-
-    virtual Deprecated::IWorldSceneMouseTracker* CreateMouseTracker(Deprecated::WorldSceneWidget& widget,
-                                                                    const Deprecated::ViewportGeometry& view,
-                                                                    MouseButton button,
-                                                                    KeyboardModifiers modifiers,
-                                                                    int viewportX,
-                                                                    int viewportY,
-                                                                    double x,
-                                                                    double y,
-                                                                    Deprecated::IStatusBar* statusBar,
-                                                                    const std::vector<Deprecated::Touch>& displayTouches);
-
-    virtual void MouseOver(CairoContext& context,
-                           Deprecated::WorldSceneWidget& widget,
-                           const Deprecated::ViewportGeometry& view,
-                           double x,
-                           double y,
-                           Deprecated::IStatusBar* statusBar)
-    {}
-
-    virtual void MouseWheel(Deprecated::WorldSceneWidget& widget,
-                            MouseWheelDirection direction,
-                            KeyboardModifiers modifiers,
-                            Deprecated::IStatusBar* statusBar)
-    {}
-
-    virtual void KeyPressed(Deprecated::WorldSceneWidget& widget,
-                            KeyboardKeys key,
-                            char keyChar,
-                            KeyboardModifiers modifiers,
-                            Deprecated::IStatusBar* statusBar)
-    {}
-
-  };
-
-
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/Wasm/SimpleViewerWasmApplicationAdapter.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "SimpleViewerWasmApplicationAdapter.h"
-
-namespace SimpleViewer
-{
-
-  SimpleViewerWasmApplicationAdapter::SimpleViewerWasmApplicationAdapter(MessageBroker &broker, SimpleViewerApplication &application)
-      : WasmPlatformApplicationAdapter(broker, application),
-        viewerApplication_(application)
-  {
-    application.RegisterObserverCallback(new Callable<SimpleViewerWasmApplicationAdapter, SimpleViewerApplication::StatusUpdatedMessage>(*this, &SimpleViewerWasmApplicationAdapter::OnStatusUpdated));
-  }
-
-  void SimpleViewerWasmApplicationAdapter::OnStatusUpdated(const SimpleViewerApplication::StatusUpdatedMessage &message)
-  {
-    Json::Value statusJson;
-    message.status_.ToJson(statusJson);
-
-    Json::Value event;
-    event["event"] = "appStatusUpdated";
-    event["data"] = statusJson;
-
-    Json::StreamWriterBuilder builder;
-    std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
-    std::ostringstream outputStr;
-
-    writer->write(event, &outputStr);
-
-    NotifyStatusUpdateFromCppToWebWithString(outputStr.str());
-  }
-
-} // namespace SimpleViewer
\ No newline at end of file
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/Wasm/SimpleViewerWasmApplicationAdapter.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#pragma once
-
-#include <string>
-#include "../../../../../../Framework/Messages/IObserver.h"
-#include <Platforms/Wasm/WasmPlatformApplicationAdapter.h>
-
-#include "../../SimpleViewerApplication.h"
-
-namespace SimpleViewer {
-
-  class SimpleViewerWasmApplicationAdapter : public WasmPlatformApplicationAdapter
-    {
-      SimpleViewerApplication&  viewerApplication_;
-
-    public:
-      SimpleViewerWasmApplicationAdapter(MessageBroker& broker, SimpleViewerApplication& application);
-
-    private:
-      void OnStatusUpdated(const SimpleViewerApplication::StatusUpdatedMessage& message);
-
-    };
-
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/Wasm/mainWasm.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "Platforms/Wasm/WasmWebService.h"
-#include "Platforms/Wasm/WasmViewport.h"
-
-#include <emscripten/emscripten.h>
-
-#include "../../SimpleViewerApplication.h"
-#include "SimpleViewerWasmApplicationAdapter.h"
-
-
-OrthancStone::IStoneApplication* CreateUserApplication(OrthancStone::MessageBroker& broker) {
-  
-  return new SimpleViewer::SimpleViewerApplication(broker);
-}
-
-OrthancStone::WasmPlatformApplicationAdapter* CreateWasmApplicationAdapter(OrthancStone::MessageBroker& broker, IStoneApplication* application)
-{
-  return new SimpleViewer::SimpleViewerWasmApplicationAdapter(broker, *(dynamic_cast<SimpleViewer::SimpleViewerApplication*>(application)));
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/Wasm/simple-viewer.html	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-<!doctype html>
-
-<html lang="us">
-  <head>
-    <meta charset="utf-8" />
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-
-    <!-- Disable pinch zoom on mobile devices -->
-    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
-    <meta name="HandheldFriendly" content="true" />
-
-    <title>Simple Viewer</title>
-    <link href="styles.css" rel="stylesheet" />
-
-<body>
-  <div id="breadcrumb">
-    <span id="label-patient-id"></span>
-    <span id="label-study-description"></span>
-    <span id="label-series-description"></span>
-  </div>
-  <div style="height: calc(100% - 50px)">
-    <div style="width: 20%; height: 100%; display: inline-block">
-      <canvas id="canvasThumbnails"></canvas>
-    </div>
-    <div style="width: 70%; height: 100%; display: inline-block">
-      <canvas id="canvasMain"></canvas>
-    </div>
-  </div>
-  <div id="toolbox" style="height: 50px">
-    <button tool-selector="line-measure" class="tool-selector">line</button>
-    <button tool-selector="circle-measure" class="tool-selector">circle</button>
-    <button tool-selector="crop" class="tool-selector">crop</button>
-    <button tool-selector="windowing" class="tool-selector">windowing</button>
-    <button tool-selector="zoom" class="tool-selector">zoom</button>
-    <button tool-selector="pan" class="tool-selector">pan</button>
-    <button action-trigger="rotate-left" class="action-trigger">rotate left</button>
-    <button action-trigger="rotate-right" class="action-trigger">rotate right</button>
-    <button action-trigger="invert" class="action-trigger">invert</button>
-  </div>
-  <script type="text/javascript" src="app-simple-viewer.js"></script>
-</body>
-
-</html>
\ No newline at end of file
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/Wasm/simple-viewer.ts	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-import wasmApplicationRunner = require('../../../../Platforms/Wasm/wasm-application-runner');
-
-wasmApplicationRunner.InitializeWasmApplication("OrthancStoneSimpleViewer", "/orthanc");
-
-function SelectTool(toolName: string) {
-  var command = {
-    command: "selectTool:" + toolName,
-    commandType: "generic-no-arg-command",
-    args: {
-    }                                                                                                                       
-  };
-  wasmApplicationRunner.SendSerializedMessageToStoneApplication(JSON.stringify(command));
-}
-
-function PerformAction(actionName: string) {
-  var command = {
-    command: "action:" + actionName,
-    commandType: "generic-no-arg-command",
-    args: {
-    }
-  };
-  wasmApplicationRunner.SendSerializedMessageToStoneApplication(JSON.stringify(command));
-}
-
-class SimpleViewerUI {
-
-  private _labelPatientId: HTMLSpanElement;
-  private _labelStudyDescription: HTMLSpanElement;
-
-  public constructor() {
-    // install "SelectTool" handlers
-    document.querySelectorAll("[tool-selector]").forEach((e) => {
-      (e as HTMLButtonElement).addEventListener("click", () => {
-        SelectTool(e.attributes["tool-selector"].value);
-      });
-    });
-
-    // install "PerformAction" handlers
-    document.querySelectorAll("[action-trigger]").forEach((e) => {
-      (e as HTMLButtonElement).addEventListener("click", () => {
-        PerformAction(e.attributes["action-trigger"].value);
-      });
-    });
-
-    // connect all ui elements to members
-    this._labelPatientId = document.getElementById("label-patient-id") as HTMLSpanElement;
-    this._labelStudyDescription = document.getElementById("label-study-description") as HTMLSpanElement;
-  }
-
-  public onAppStatusUpdated(status: any) {
-    this._labelPatientId.innerText = status["patientId"];
-    this._labelStudyDescription.innerText = status["studyDescription"];
-    // this.highlighThumbnail(status["currentInstanceIdInMainViewport"]);
-  }
-
-}
-
-var ui = new SimpleViewerUI();
-
-// this method is called "from the C++ code" when the StoneApplication is updated.
-// it can be used to update the UI of the application
-function UpdateWebApplicationWithString(statusUpdateMessageString: string) {
-  console.log("updating web application with string: ", statusUpdateMessageString);
-  let statusUpdateMessage = JSON.parse(statusUpdateMessageString);
-
-  if ("event" in statusUpdateMessage) {
-    let eventName = statusUpdateMessage["event"];
-    if (eventName == "appStatusUpdated") {
-      ui.onAppStatusUpdated(statusUpdateMessage["data"]);
-    }
-  }
-}
-
-function UpdateWebApplicationWithSerializedMessage(statusUpdateMessageString: string) {
-  console.log("updating web application with serialized message: ", statusUpdateMessageString);
-  console.log("<not supported in the simple viewer!>");
-}
-
-// make it available to other js scripts in the application
-(<any> window).UpdateWebApplicationWithString = UpdateWebApplicationWithString;
-(<any> window).UpdateWebApplicationWithSerializedMessage = UpdateWebApplicationWithSerializedMessage;
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/Wasm/styles.css	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-html, body {
-    width: 100%;
-    height: 100%;
-    margin: 0px;
-    border: 0;
-    overflow: hidden; /*  Disable scrollbars */
-    display: block;  /* No floating content on sides */
-    background-color: black;
-    color: white;
-    font-family: Arial, Helvetica, sans-serif;
-}
-
-canvas {
-    left:0px;
-    top:0px;
-}
-
-#canvas-group {
-    padding:5px;
-    background-color: grey;
-}
-
-#status-group {
-    padding:5px;
-}
-
-#worklist-group {
-    padding:5px;
-}
-
-.vsol-button {
-    height: 40px;
-}
-
-#thumbnails-group ul li {
-    display: inline;
-    list-style: none;
-}
-
-.thumbnail {
-    width: 100px;
-    height: 100px;
-    padding: 3px;
-}
-
-.thumbnail-selected {
-    border-width: 1px;
-    border-color: red;
-    border-style: solid;
-}
-
-#template-thumbnail-li {
-    display: none !important;
-}
\ No newline at end of file
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewer/Wasm/tsconfig-simple-viewer.json	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-{
-    "extends" : "../../Web/tsconfig-samples",
-    "compilerOptions": {
-    },
-    "include" : [
-        "simple-viewer.ts",
-        "../../build-wasm/ApplicationCommands_generated.ts"
-    ]
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SimpleViewerApplicationSingleFile.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,461 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "SampleApplicationBase.h"
-
-#include "../../../Framework/Deprecated/Layers/CircleMeasureTracker.h"
-#include "../../../Framework/Deprecated/Layers/LineMeasureTracker.h"
-#include "../../../Framework/Deprecated/SmartLoader.h"
-#include "../../../Framework/Deprecated/Widgets/LayoutWidget.h"
-#include "../../../Framework/Deprecated/Widgets/SliceViewerWidget.h"
-#include "../../../Framework/Messages/IObserver.h"
-
-#if ORTHANC_ENABLE_WASM==1
-#include "../../../Platforms/Wasm/WasmPlatformApplicationAdapter.h"
-#include "../../../Platforms/Wasm/Defaults.h"
-#endif
-
-#include <Core/Images/Font.h>
-#include <Core/Logging.h>
-
-namespace OrthancStone
-{
-  namespace Samples
-  {
-    class SimpleViewerApplication :
-      public SampleSingleCanvasWithButtonsApplicationBase,
-      public ObserverBase<SimpleViewerApplication>
-    {
-    private:
-      class ThumbnailInteractor : public Deprecated::IWorldSceneInteractor
-      {
-      private:
-        SimpleViewerApplication&  application_;
-
-      public:
-        ThumbnailInteractor(SimpleViewerApplication&  application) :
-          application_(application)
-        {
-        }
-
-        virtual Deprecated::IWorldSceneMouseTracker* CreateMouseTracker(Deprecated::WorldSceneWidget& widget,
-                                                            const Deprecated::ViewportGeometry& view,
-                                                            MouseButton button,
-                                                            KeyboardModifiers modifiers,
-                                                            int viewportX,
-                                                            int viewportY,
-                                                            double x,
-                                                            double y,
-                                                            Deprecated::IStatusBar* statusBar,
-                                                            const std::vector<Deprecated::Touch>& displayTouches)
-        {
-          if (button == MouseButton_Left)
-          {
-            statusBar->SetMessage("selected thumbnail " + widget.GetName());
-            std::string seriesId = widget.GetName().substr(strlen("thumbnail-series-"));
-            application_.SelectSeriesInMainViewport(seriesId);
-          }
-          return NULL;
-        }
-
-        virtual void MouseOver(CairoContext& context,
-                               Deprecated::WorldSceneWidget& widget,
-                               const Deprecated::ViewportGeometry& view,
-                               double x,
-                               double y,
-                               Deprecated::IStatusBar* statusBar)
-        {
-        }
-
-        virtual void MouseWheel(Deprecated::WorldSceneWidget& widget,
-                                MouseWheelDirection direction,
-                                KeyboardModifiers modifiers,
-                                Deprecated::IStatusBar* statusBar)
-        {
-        }
-
-        virtual void KeyPressed(Deprecated::WorldSceneWidget& widget,
-                                KeyboardKeys key,
-                                char keyChar,
-                                KeyboardModifiers modifiers,
-                                Deprecated::IStatusBar* statusBar)
-        {
-        }
-      };
-
-      class MainWidgetInteractor : public Deprecated::IWorldSceneInteractor
-      {
-      private:
-        SimpleViewerApplication&  application_;
-        
-      public:
-        MainWidgetInteractor(SimpleViewerApplication&  application) :
-          application_(application)
-        {
-        }
-        
-        virtual Deprecated::IWorldSceneMouseTracker* CreateMouseTracker(Deprecated::WorldSceneWidget& widget,
-                                                            const Deprecated::ViewportGeometry& view,
-                                                            MouseButton button,
-                                                            KeyboardModifiers modifiers,
-                                                            int viewportX,
-                                                            int viewportY,
-                                                            double x,
-                                                            double y,
-                                                            Deprecated::IStatusBar* statusBar,
-                                                            const std::vector<Deprecated::Touch>& displayTouches)
-        {
-          if (button == MouseButton_Left)
-          {
-            if (application_.currentTool_ == Tool_LineMeasure)
-            {
-              return new Deprecated::LineMeasureTracker(statusBar, dynamic_cast<Deprecated::SliceViewerWidget&>(widget).GetSlice(),
-                                            x, y, 255, 0, 0, application_.GetFont());
-            }
-            else if (application_.currentTool_ == Tool_CircleMeasure)
-            {
-              return new Deprecated::CircleMeasureTracker(statusBar, dynamic_cast<Deprecated::SliceViewerWidget&>(widget).GetSlice(),
-                                              x, y, 255, 0, 0, application_.GetFont());
-            }
-          }
-          return NULL;
-        }
-
-        virtual void MouseOver(CairoContext& context,
-                               Deprecated::WorldSceneWidget& widget,
-                               const Deprecated::ViewportGeometry& view,
-                               double x,
-                               double y,
-                               Deprecated::IStatusBar* statusBar)
-        {
-          if (statusBar != NULL)
-          {
-            Vector p = dynamic_cast<Deprecated::SliceViewerWidget&>(widget).GetSlice().MapSliceToWorldCoordinates(x, y);
-            
-            char buf[64];
-            sprintf(buf, "X = %.02f Y = %.02f Z = %.02f (in cm)",
-                    p[0] / 10.0, p[1] / 10.0, p[2] / 10.0);
-            statusBar->SetMessage(buf);
-          }
-        }
-
-        virtual void MouseWheel(Deprecated::WorldSceneWidget& widget,
-                                MouseWheelDirection direction,
-                                KeyboardModifiers modifiers,
-                                Deprecated::IStatusBar* statusBar)
-        {
-        }
-
-        virtual void KeyPressed(Deprecated::WorldSceneWidget& widget,
-                                KeyboardKeys key,
-                                char keyChar,
-                                KeyboardModifiers modifiers,
-                                Deprecated::IStatusBar* statusBar)
-        {
-          switch (keyChar)
-          {
-            case 's':
-              widget.FitContent();
-              break;
-
-            case 'l':
-              application_.currentTool_ = Tool_LineMeasure;
-              break;
-
-            case 'c':
-              application_.currentTool_ = Tool_CircleMeasure;
-              break;
-
-            default:
-              break;
-          }
-        }
-      };
-
-
-#if ORTHANC_ENABLE_WASM==1
-      class SimpleViewerApplicationAdapter : public WasmPlatformApplicationAdapter
-      {
-        SimpleViewerApplication&  viewerApplication_;
-
-      public:
-        SimpleViewerApplicationAdapter(SimpleViewerApplication& application)
-          : WasmPlatformApplicationAdapter(application),
-            viewerApplication_(application)
-        {
-        }
-
-        virtual void HandleSerializedMessageFromWeb(std::string& output, const std::string& input) 
-        {
-          if (input == "select-tool:line-measure")
-          {
-            viewerApplication_.currentTool_ = Tool_LineMeasure;
-            NotifyStatusUpdateFromCppToWebWithString("currentTool=line-measure");
-          }
-          else if (input == "select-tool:circle-measure")
-          {
-            viewerApplication_.currentTool_ = Tool_CircleMeasure;
-            NotifyStatusUpdateFromCppToWebWithString("currentTool=circle-measure");
-          }
-
-          output = "ok";
-        }
-
-        virtual void NotifySerializedMessageFromCppToWeb(const std::string& statusUpdateMessage) 
-        {
-          UpdateStoneApplicationStatusFromCppWithSerializedMessage(statusUpdateMessage.c_str());
-        }
-
-        virtual void NotifyStatusUpdateFromCppToWebWithString(const std::string& statusUpdateMessage) 
-        {
-          UpdateStoneApplicationStatusFromCppWithString(statusUpdateMessage.c_str());
-        }
-
-      };
-#endif
-      enum Tool {
-        Tool_LineMeasure,
-        Tool_CircleMeasure
-      };
-
-      Tool                                 currentTool_;
-      std::unique_ptr<MainWidgetInteractor>  mainWidgetInteractor_;
-      std::unique_ptr<ThumbnailInteractor>   thumbnailInteractor_;
-      Deprecated::LayoutWidget*                        mainLayout_;
-      Deprecated::LayoutWidget*                        thumbnailsLayout_;
-      std::vector<boost::shared_ptr<Deprecated::SliceViewerWidget> >      thumbnails_;
-
-      std::map<std::string, std::vector<std::string> > instancesIdsPerSeriesId_;
-      std::map<std::string, Json::Value> seriesTags_;
-
-      unsigned int                         currentInstanceIndex_;
-      Deprecated::WidgetViewport*        wasmViewport1_;
-      Deprecated::WidgetViewport*        wasmViewport2_;
-
-      Deprecated::IStatusBar*                          statusBar_;
-      std::unique_ptr<Deprecated::SmartLoader>           smartLoader_;
-
-      Orthanc::Font                        font_;
-
-    public:
-      SimpleViewerApplication() :
-        currentTool_(Tool_LineMeasure),
-        mainLayout_(NULL),
-        currentInstanceIndex_(0),
-        wasmViewport1_(NULL),
-        wasmViewport2_(NULL)
-      {
-        font_.LoadFromResource(Orthanc::EmbeddedResources::FONT_UBUNTU_MONO_BOLD_16);
-//        DeclareIgnoredMessage(MessageType_Widget_ContentChanged);
-      }
-
-      virtual void DeclareStartupOptions(boost::program_options::options_description& options)
-      {
-        boost::program_options::options_description generic("Sample options");
-        generic.add_options()
-          ("studyId", boost::program_options::value<std::string>(),
-           "Orthanc ID of the study")
-          ;
-
-        options.add(generic);
-      }
-
-      virtual void Initialize(StoneApplicationContext* context,
-                              Deprecated::IStatusBar& statusBar,
-                              const boost::program_options::variables_map& parameters)
-      {
-        using namespace OrthancStone;
-
-        context_ = context;
-        statusBar_ = &statusBar;
-
-        {// initialize viewports and layout
-          mainLayout_ = new Deprecated::LayoutWidget("main-layout");
-          mainLayout_->SetPadding(10);
-          mainLayout_->SetBackgroundCleared(true);
-          mainLayout_->SetBackgroundColor(0, 0, 0);
-          mainLayout_->SetHorizontal();
-
-          boost::shared_ptr<Deprecated::LayoutWidget> thumbnailsLayout_(new Deprecated::LayoutWidget("thumbnail-layout"));
-          thumbnailsLayout_->SetPadding(10);
-          thumbnailsLayout_->SetBackgroundCleared(true);
-          thumbnailsLayout_->SetBackgroundColor(50, 50, 50);
-          thumbnailsLayout_->SetVertical();
-
-          boost::shared_ptr<Deprecated::SliceViewerWidget> widget
-            (new Deprecated::SliceViewerWidget("main-viewport"));
-          SetCentralWidget(widget);
-          //mainWidget_->RegisterObserver(*this);
-
-          // hierarchy
-          mainLayout_->AddWidget(thumbnailsLayout_);
-          mainLayout_->AddWidget(widget);
-
-          // sources
-          smartLoader_.reset(new Deprecated::SmartLoader(context->GetOrthancApiClient()));
-          smartLoader_->SetImageQuality(Deprecated::SliceImageQuality_FullPam);
-
-          mainLayout_->SetTransmitMouseOver(true);
-          mainWidgetInteractor_.reset(new MainWidgetInteractor(*this));
-          widget->SetInteractor(*mainWidgetInteractor_);
-          thumbnailInteractor_.reset(new ThumbnailInteractor(*this));
-        }
-
-        statusBar.SetMessage("Use the key \"s\" to reinitialize the layout");
-        statusBar.SetMessage("Use the key \"n\" to go to next image in the main viewport");
-
-
-        if (parameters.count("studyId") < 1)
-        {
-          LOG(WARNING) << "The study ID is missing, will take the first studyId found in Orthanc";
-          context->GetOrthancApiClient()->GetJsonAsync(
-            "/studies",
-            new Deprecated::DeprecatedCallable<SimpleViewerApplication, Deprecated::OrthancApiClient::JsonResponseReadyMessage>
-            (GetSharedObserver(), &SimpleViewerApplication::OnStudyListReceived));
-        }
-        else
-        {
-          SelectStudy(parameters["studyId"].as<std::string>());
-        }
-      }
-
-      void OnStudyListReceived(const Deprecated::OrthancApiClient::JsonResponseReadyMessage& message)
-      {
-        const Json::Value& response = message.GetJson();
-
-        if (response.isArray() &&
-            response.size() >= 1)
-        {
-          SelectStudy(response[0].asString());
-        }
-      }
-      
-      void OnStudyReceived(const Deprecated::OrthancApiClient::JsonResponseReadyMessage& message)
-      {
-        const Json::Value& response = message.GetJson();
-
-        if (response.isObject() && response["Series"].isArray())
-        {
-          for (size_t i=0; i < response["Series"].size(); i++)
-          {
-            context_->GetOrthancApiClient()->GetJsonAsync(
-              "/series/" + response["Series"][(int)i].asString(),
-              new Deprecated::DeprecatedCallable<SimpleViewerApplication, Deprecated::OrthancApiClient::JsonResponseReadyMessage>
-              (GetSharedObserver(), &SimpleViewerApplication::OnSeriesReceived));
-          }
-        }
-      }
-
-      void OnSeriesReceived(const Deprecated::OrthancApiClient::JsonResponseReadyMessage& message)
-      {
-        const Json::Value& response = message.GetJson();
-
-        if (response.isObject() &&
-            response["Instances"].isArray() &&
-            response["Instances"].size() > 0)
-        {
-          // keep track of all instances IDs
-          const std::string& seriesId = response["ID"].asString();
-          seriesTags_[seriesId] = response;
-          instancesIdsPerSeriesId_[seriesId] = std::vector<std::string>();
-          for (size_t i = 0; i < response["Instances"].size(); i++)
-          {
-            const std::string& instanceId = response["Instances"][static_cast<int>(i)].asString();
-            instancesIdsPerSeriesId_[seriesId].push_back(instanceId);
-          }
-
-          // load the first instance in the thumbnail
-          LoadThumbnailForSeries(seriesId, instancesIdsPerSeriesId_[seriesId][0]);
-
-          // if this is the first thumbnail loaded, load the first instance in the mainWidget
-          Deprecated::SliceViewerWidget& widget = dynamic_cast<Deprecated::SliceViewerWidget&>(*GetCentralWidget());
-          if (widget.GetLayerCount() == 0)
-          {
-            smartLoader_->SetFrameInWidget(widget, 0, instancesIdsPerSeriesId_[seriesId][0], 0);
-          }
-        }
-      }
-
-      void LoadThumbnailForSeries(const std::string& seriesId, const std::string& instanceId)
-      {
-        LOG(INFO) << "Loading thumbnail for series " << seriesId;
-        boost::shared_ptr<Deprecated::SliceViewerWidget> thumbnailWidget(new Deprecated::SliceViewerWidget("thumbnail-series-" + seriesId));
-        thumbnails_.push_back(thumbnailWidget);
-        thumbnailsLayout_->AddWidget(thumbnailWidget);
-        Register<Deprecated::SliceViewerWidget::GeometryChangedMessage>(*thumbnailWidget, &SimpleViewerApplication::OnWidgetGeometryChanged);
-        smartLoader_->SetFrameInWidget(*thumbnailWidget, 0, instanceId, 0);
-        thumbnailWidget->SetInteractor(*thumbnailInteractor_);
-      }
-
-      void SelectStudy(const std::string& studyId)
-      {
-        LOG(INFO) << "Selecting study: " << studyId;
-        context_->GetOrthancApiClient()->GetJsonAsync(
-          "/studies/" + studyId, new Deprecated::DeprecatedCallable<SimpleViewerApplication, Deprecated::OrthancApiClient::JsonResponseReadyMessage>
-          (GetSharedObserver(), &SimpleViewerApplication::OnStudyReceived));
-      }
-
-      void OnWidgetGeometryChanged(const Deprecated::SliceViewerWidget::GeometryChangedMessage& message)
-      {
-        // TODO: The "const_cast" could probably be replaced by "mainWidget"
-        const_cast<Deprecated::SliceViewerWidget&>(message.GetOrigin()).FitContent();
-      }
-
-      void SelectSeriesInMainViewport(const std::string& seriesId)
-      {
-        Deprecated::SliceViewerWidget& widget = dynamic_cast<Deprecated::SliceViewerWidget&>(*GetCentralWidget());
-        smartLoader_->SetFrameInWidget(widget, 0, instancesIdsPerSeriesId_[seriesId][0], 0);
-      }
-
-      const Orthanc::Font& GetFont() const
-      {
-        return font_;
-      }
-      
-      virtual void OnPushButton1Clicked() {}
-      virtual void OnPushButton2Clicked() {}
-      virtual void OnTool1Clicked() { currentTool_ = Tool_LineMeasure;}
-      virtual void OnTool2Clicked() { currentTool_ = Tool_CircleMeasure;}
-
-      virtual void GetButtonNames(std::string& pushButton1,
-                                  std::string& pushButton2,
-                                  std::string& tool1,
-                                  std::string& tool2)
-      {
-        tool1 = "line";
-        tool2 = "circle";
-        pushButton1 = "action1";
-        pushButton2 = "action2";
-      }
-
-#if ORTHANC_ENABLE_WASM==1
-      virtual void InitializeWasm()
-      {
-        AttachWidgetToWasmViewport("canvas", thumbnailsLayout_);
-        AttachWidgetToWasmViewport("canvas2", widget);
-      }
-#endif
-
-    };
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SingleFrameApplication.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,268 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "SampleApplicationBase.h"
-
-#include "../../../Framework/Deprecated/Layers/DicomSeriesVolumeSlicer.h"
-#include "../../../Framework/Deprecated/Widgets/SliceViewerWidget.h"
-
-#include <Core/Logging.h>
-#include <Core/OrthancException.h>
-
-#include <boost/math/constants/constants.hpp>
-
-
-namespace OrthancStone
-{
-  namespace Samples
-  {
-    class SingleFrameApplication :
-      public SampleSingleCanvasApplicationBase,
-      public ObserverBase<SingleFrameApplication>
-    {
-    private:
-      class Interactor : public Deprecated::IWorldSceneInteractor
-      {
-      private:
-        SingleFrameApplication&  application_;
-        
-      public:
-        Interactor(SingleFrameApplication&  application) :
-          application_(application)
-        {
-        }
-        
-        virtual Deprecated::IWorldSceneMouseTracker* CreateMouseTracker(Deprecated::WorldSceneWidget& widget,
-                                                                        const Deprecated::ViewportGeometry& view,
-                                                                        MouseButton button,
-                                                                        KeyboardModifiers modifiers,
-                                                                        int viewportX,
-                                                                        int viewportY,
-                                                                        double x,
-                                                                        double y,
-                                                                        Deprecated::IStatusBar* statusBar,
-                                                                        const std::vector<Deprecated::Touch>& displayTouches)
-        {
-          return NULL;
-        }
-
-        virtual void MouseOver(CairoContext& context,
-                               Deprecated::WorldSceneWidget& widget,
-                               const Deprecated::ViewportGeometry& view,
-                               double x,
-                               double y,
-                               Deprecated::IStatusBar* statusBar)
-        {
-          if (statusBar != NULL)
-          {
-            Vector p = dynamic_cast<Deprecated::SliceViewerWidget&>(widget).GetSlice().MapSliceToWorldCoordinates(x, y);
-            
-            char buf[64];
-            sprintf(buf, "X = %.02f Y = %.02f Z = %.02f (in cm)", 
-                    p[0] / 10.0, p[1] / 10.0, p[2] / 10.0);
-            statusBar->SetMessage(buf);
-          }
-        }
-
-        virtual void MouseWheel(Deprecated::WorldSceneWidget& widget,
-                                MouseWheelDirection direction,
-                                KeyboardModifiers modifiers,
-                                Deprecated::IStatusBar* statusBar)
-        {
-          int scale = (modifiers & KeyboardModifiers_Control ? 10 : 1);
-          
-          switch (direction)
-          {
-            case MouseWheelDirection_Up:
-              application_.OffsetSlice(-scale);
-              break;
-
-            case MouseWheelDirection_Down:
-              application_.OffsetSlice(scale);
-              break;
-
-            default:
-              break;
-          }
-        }
-
-        virtual void KeyPressed(Deprecated::WorldSceneWidget& widget,
-                                KeyboardKeys key,
-                                char keyChar,
-                                KeyboardModifiers modifiers,
-                                Deprecated::IStatusBar* statusBar)
-        {
-          switch (keyChar)
-          {
-            case 's':
-              widget.FitContent();
-              break;
-
-            default:
-              break;
-          }
-        }
-      };
-
-
-      void OffsetSlice(int offset)
-      {
-        if (source_)
-        {
-          int slice = static_cast<int>(slice_) + offset;
-
-          if (slice < 0)
-          {
-            slice = 0;
-          }
-
-          if (slice >= static_cast<int>(source_->GetSlicesCount()))
-          {
-            slice = static_cast<int>(source_->GetSlicesCount()) - 1;
-          }
-
-          if (slice != static_cast<int>(slice_)) 
-          {
-            SetSlice(slice);
-          }   
-        }
-      }
-
-
-      void SetSlice(size_t index)
-      {
-        if (source_ &&
-            index < source_->GetSlicesCount())
-        {
-          slice_ = static_cast<unsigned int>(index);
-          
-#if 1
-          widget_->SetSlice(source_->GetSlice(slice_).GetGeometry());
-#else
-          // TEST for scene extents - Rotate the axes
-          double a = 15.0 / 180.0 * boost::math::constants::pi<double>();
-
-#if 1
-          Vector x; GeometryToolbox::AssignVector(x, cos(a), sin(a), 0);
-          Vector y; GeometryToolbox::AssignVector(y, -sin(a), cos(a), 0);
-#else
-          // Flip the normal
-          Vector x; GeometryToolbox::AssignVector(x, cos(a), sin(a), 0);
-          Vector y; GeometryToolbox::AssignVector(y, sin(a), -cos(a), 0);
-#endif
-          
-          SliceGeometry s(source_->GetSlice(slice_).GetGeometry().GetOrigin(), x, y);
-          widget_->SetSlice(s);
-#endif
-        }
-      }
-        
-      
-      void OnMainWidgetGeometryReady(const Deprecated::IVolumeSlicer::GeometryReadyMessage& message)
-      {
-        // Once the geometry of the series is downloaded from Orthanc,
-        // display its middle slice, and adapt the viewport to fit this
-        // slice
-        if (source_ &&
-            source_.get() == &message.GetOrigin())
-        {
-          SetSlice(source_->GetSlicesCount() / 2);
-        }
-
-        widget_->FitContent();
-      }
-
-      boost::shared_ptr<Deprecated::SliceViewerWidget>  widget_;
-      std::unique_ptr<Interactor>         mainWidgetInteractor_;
-      boost::shared_ptr<Deprecated::DicomSeriesVolumeSlicer> source_;
-      unsigned int                      slice_;
-
-    public:
-      SingleFrameApplication() :
-        slice_(0)
-      {
-      }
-      
-      virtual void DeclareStartupOptions(boost::program_options::options_description& options)
-      {
-        boost::program_options::options_description generic("Sample options");
-        generic.add_options()
-          ("instance", boost::program_options::value<std::string>(), 
-           "Orthanc ID of the instance")
-          ("frame", boost::program_options::value<unsigned int>()->default_value(0),
-           "Number of the frame, for multi-frame DICOM instances")
-          ("smooth", boost::program_options::value<bool>()->default_value(true), 
-           "Enable bilinear interpolation to smooth the image")
-          ;
-
-        options.add(generic);    
-      }
-
-      virtual void Initialize(StoneApplicationContext* context,
-                              Deprecated::IStatusBar& statusBar,
-                              const boost::program_options::variables_map& parameters)
-      {
-        using namespace OrthancStone;
-
-        context_ = context;
-
-        statusBar.SetMessage("Use the key \"s\" to reinitialize the layout");
-
-        if (parameters.count("instance") != 1)
-        {
-          LOG(ERROR) << "The instance ID is missing";
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-        }
-
-        std::string instance = parameters["instance"].as<std::string>();
-        int frame = parameters["frame"].as<unsigned int>();
-
-        widget_.reset(new Deprecated::SliceViewerWidget("main-widget"));
-        SetCentralWidget(widget_);
-
-        boost::shared_ptr<Deprecated::DicomSeriesVolumeSlicer> layer(new Deprecated::DicomSeriesVolumeSlicer);
-        layer->Connect(context->GetOrthancApiClient());
-        source_ = layer;
-
-        layer->LoadFrame(instance, frame);
-        Register<Deprecated::IVolumeSlicer::GeometryReadyMessage>(*layer, &SingleFrameApplication::OnMainWidgetGeometryReady);
-        widget_->AddLayer(layer);
-
-        Deprecated::RenderStyle s;
-
-        if (parameters["smooth"].as<bool>())
-        {
-          s.interpolation_ = ImageInterpolation_Bilinear;
-        }
-
-        widget_->SetLayerStyle(0, s);
-        widget_->SetTransmitMouseOver(true);
-
-        mainWidgetInteractor_.reset(new Interactor(*this));
-        widget_->SetInteractor(*mainWidgetInteractor_);
-      }
-    };
-
-
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SingleFrameEditorApplication.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,531 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "SampleApplicationBase.h"
-
-#include "../../../Framework/Radiography/RadiographyLayerCropTracker.h"
-#include "../../../Framework/Radiography/RadiographyLayerMaskTracker.h"
-#include "../../../Framework/Radiography/RadiographyLayerMoveTracker.h"
-#include "../../../Framework/Radiography/RadiographyLayerResizeTracker.h"
-#include "../../../Framework/Radiography/RadiographyLayerRotateTracker.h"
-#include "../../../Framework/Radiography/RadiographyMaskLayer.h"
-#include "../../../Framework/Radiography/RadiographyScene.h"
-#include "../../../Framework/Radiography/RadiographySceneCommand.h"
-#include "../../../Framework/Radiography/RadiographySceneReader.h"
-#include "../../../Framework/Radiography/RadiographySceneWriter.h"
-#include "../../../Framework/Radiography/RadiographyWidget.h"
-#include "../../../Framework/Radiography/RadiographyWindowingTracker.h"
-#include "../../../Framework/Toolbox/TextRenderer.h"
-
-#include <Core/HttpClient.h>
-#include <Core/Logging.h>
-#include <Core/OrthancException.h>
-#include <Core/Images/PngWriter.h>
-#include <Core/Images/PngReader.h>
-
-
-// Export using PAM is faster than using PNG, but requires Orthanc
-// core >= 1.4.3
-#define EXPORT_USING_PAM  1
-
-
-namespace OrthancStone
-{
-  namespace Samples
-  {
-    class RadiographyEditorInteractor :
-        public Deprecated::IWorldSceneInteractor,
-        public ObserverBase<RadiographyEditorInteractor>
-    {
-    private:
-      enum Tool
-      {
-        Tool_Move,
-        Tool_Rotate,
-        Tool_Crop,
-        Tool_Resize,
-        Tool_Mask,
-        Tool_Windowing
-      };
-
-
-      StoneApplicationContext*  context_;
-      UndoRedoStack             undoRedoStack_;
-      Tool                      tool_;
-      RadiographyMaskLayer*     maskLayer_;
-
-
-      static double GetHandleSize()
-      {
-        return 10.0;
-      }
-
-
-    public:
-      RadiographyEditorInteractor() :
-        context_(NULL),
-        tool_(Tool_Move),
-        maskLayer_(NULL)
-      {
-      }
-
-      void SetContext(StoneApplicationContext& context)
-      {
-        context_ = &context;
-      }
-
-      void SetMaskLayer(RadiographyMaskLayer* maskLayer)
-      {
-        maskLayer_ = maskLayer;
-      }
-      virtual Deprecated::IWorldSceneMouseTracker* CreateMouseTracker(Deprecated::WorldSceneWidget& worldWidget,
-                                                                      const Deprecated::ViewportGeometry& view,
-                                                                      MouseButton button,
-                                                                      KeyboardModifiers modifiers,
-                                                                      int viewportX,
-                                                                      int viewportY,
-                                                                      double x,
-                                                                      double y,
-                                                                      Deprecated::IStatusBar* statusBar,
-                                                                      const std::vector<Deprecated::Touch>& displayTouches)
-      {
-        RadiographyWidget& widget = dynamic_cast<RadiographyWidget&>(worldWidget);
-
-        if (button == MouseButton_Left)
-        {
-          size_t selected;
-
-          if (tool_ == Tool_Windowing)
-          {
-            return new RadiographyWindowingTracker(
-                  undoRedoStack_,
-                  widget.GetScene(),
-                  widget,
-                  OrthancStone::ImageInterpolation_Nearest,
-                  viewportX, viewportY,
-                  RadiographyWindowingTracker::Action_DecreaseWidth,
-                  RadiographyWindowingTracker::Action_IncreaseWidth,
-                  RadiographyWindowingTracker::Action_DecreaseCenter,
-                  RadiographyWindowingTracker::Action_IncreaseCenter);
-          }
-          else if (!widget.LookupSelectedLayer(selected))
-          {
-            // No layer is currently selected
-            size_t layer;
-            if (widget.GetScene().LookupLayer(layer, x, y))
-            {
-              widget.Select(layer);
-            }
-
-            return NULL;
-          }
-          else if (tool_ == Tool_Crop ||
-                   tool_ == Tool_Resize ||
-                   tool_ == Tool_Mask)
-          {
-            RadiographyScene::LayerAccessor accessor(widget.GetScene(), selected);
-            
-            ControlPoint controlPoint;
-            if (accessor.GetLayer().LookupControlPoint(controlPoint, x, y, view.GetZoom(), GetHandleSize()))
-            {
-              switch (tool_)
-              {
-              case Tool_Crop:
-                return new RadiographyLayerCropTracker
-                    (undoRedoStack_, widget.GetScene(), view, selected, controlPoint);
-
-              case Tool_Mask:
-                return new RadiographyLayerMaskTracker
-                    (undoRedoStack_, widget.GetScene(), view, selected, controlPoint);
-
-              case Tool_Resize:
-                return new RadiographyLayerResizeTracker
-                    (undoRedoStack_, widget.GetScene(), selected, controlPoint,
-                     (modifiers & KeyboardModifiers_Shift));
-
-              default:
-                throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-              }
-            }
-            else
-            {
-              size_t layer;
-
-              if (widget.GetScene().LookupLayer(layer, x, y))
-              {
-                widget.Select(layer);
-              }
-              else
-              {
-                widget.Unselect();
-              }
-
-              return NULL;
-            }
-          }
-          else
-          {
-            size_t layer;
-
-            if (widget.GetScene().LookupLayer(layer, x, y))
-            {
-              if (layer == selected)
-              {
-                switch (tool_)
-                {
-                case Tool_Move:
-                  return new RadiographyLayerMoveTracker
-                      (undoRedoStack_, widget.GetScene(), layer, x, y,
-                       (modifiers & KeyboardModifiers_Shift));
-
-                case Tool_Rotate:
-                  return new RadiographyLayerRotateTracker
-                      (undoRedoStack_, widget.GetScene(), view, layer, x, y,
-                       (modifiers & KeyboardModifiers_Shift));
-
-                default:
-                  break;
-                }
-
-                return NULL;
-              }
-              else
-              {
-                widget.Select(layer);
-                return NULL;
-              }
-            }
-            else
-            {
-              widget.Unselect();
-              return NULL;
-            }
-          }
-        }
-        else
-        {
-          return NULL;
-        }
-        return NULL;
-      }
-
-      virtual void MouseOver(CairoContext& context,
-                             Deprecated::WorldSceneWidget& worldWidget,
-                             const Deprecated::ViewportGeometry& view,
-                             double x,
-                             double y,
-                             Deprecated::IStatusBar* statusBar)
-      {
-        RadiographyWidget& widget = dynamic_cast<RadiographyWidget&>(worldWidget);
-
-#if 0
-        if (statusBar != NULL)
-        {
-          char buf[64];
-          sprintf(buf, "X = %.02f Y = %.02f (in cm)", x / 10.0, y / 10.0);
-          statusBar->SetMessage(buf);
-        }
-#endif
-
-        size_t selected;
-
-        if (widget.LookupSelectedLayer(selected) &&
-            (tool_ == Tool_Crop ||
-             tool_ == Tool_Resize ||
-             tool_ == Tool_Mask))
-        {
-          RadiographyScene::LayerAccessor accessor(widget.GetScene(), selected);
-
-          ControlPoint controlPoint;
-          if (accessor.GetLayer().LookupControlPoint(controlPoint, x, y, view.GetZoom(), GetHandleSize()))
-          {
-            double z = 1.0 / view.GetZoom();
-
-            context.SetSourceColor(255, 0, 0);
-            cairo_t* cr = context.GetObject();
-            cairo_set_line_width(cr, 2.0 * z);
-            cairo_move_to(cr, controlPoint.x - GetHandleSize() * z, controlPoint.y - GetHandleSize() * z);
-            cairo_line_to(cr, controlPoint.x + GetHandleSize() * z, controlPoint.y - GetHandleSize() * z);
-            cairo_line_to(cr, controlPoint.x + GetHandleSize() * z, controlPoint.y + GetHandleSize() * z);
-            cairo_line_to(cr, controlPoint.x - GetHandleSize() * z, controlPoint.y + GetHandleSize() * z);
-            cairo_line_to(cr, controlPoint.x - GetHandleSize() * z, controlPoint.y - GetHandleSize() * z);
-            cairo_stroke(cr);
-          }
-        }
-      }
-
-      virtual void MouseWheel(Deprecated::WorldSceneWidget& widget,
-                              MouseWheelDirection direction,
-                              KeyboardModifiers modifiers,
-                              Deprecated::IStatusBar* statusBar)
-      {
-      }
-
-      virtual void KeyPressed(Deprecated::WorldSceneWidget& worldWidget,
-                              KeyboardKeys key,
-                              char keyChar,
-                              KeyboardModifiers modifiers,
-                              Deprecated::IStatusBar* statusBar)
-      {
-        RadiographyWidget& widget = dynamic_cast<RadiographyWidget&>(worldWidget);
-
-        switch (keyChar)
-        {
-        case 'a':
-          widget.FitContent();
-          break;
-
-        case 'c':
-          tool_ = Tool_Crop;
-          break;
-
-        case 'm':
-          tool_ = Tool_Mask;
-          widget.Select(1);
-          break;
-
-        case 'd':
-        {
-          // dump to json and reload
-          Json::Value snapshot;
-          RadiographySceneWriter writer;
-          writer.Write(snapshot, widget.GetScene());
-
-          LOG(INFO) << "JSON export was successful: "
-                    << snapshot.toStyledString();
-
-          boost::shared_ptr<RadiographyScene> scene(new RadiographyScene);
-          RadiographySceneReader reader(*scene, *context_->GetOrthancApiClient());
-          reader.Read(snapshot);
-
-          widget.SetScene(scene);
-        };break;
-
-        case 'e':
-        {
-          Orthanc::DicomMap tags;
-
-          // Minimal set of tags to generate a valid CR image
-          tags.SetValue(Orthanc::DICOM_TAG_ACCESSION_NUMBER, "NOPE", false);
-          tags.SetValue(Orthanc::DICOM_TAG_BODY_PART_EXAMINED, "PELVIS", false);
-          tags.SetValue(Orthanc::DICOM_TAG_INSTANCE_NUMBER, "1", false);
-          //tags.SetValue(Orthanc::DICOM_TAG_LATERALITY, "", false);
-          tags.SetValue(Orthanc::DICOM_TAG_MANUFACTURER, "OSIMIS", false);
-          tags.SetValue(Orthanc::DICOM_TAG_MODALITY, "CR", false);
-          tags.SetValue(Orthanc::DICOM_TAG_PATIENT_BIRTH_DATE, "20000101", false);
-          tags.SetValue(Orthanc::DICOM_TAG_PATIENT_ID, "hello", false);
-          tags.SetValue(Orthanc::DICOM_TAG_PATIENT_NAME, "HELLO^WORLD", false);
-          tags.SetValue(Orthanc::DICOM_TAG_PATIENT_ORIENTATION, "", false);
-          tags.SetValue(Orthanc::DICOM_TAG_PATIENT_SEX, "M", false);
-          tags.SetValue(Orthanc::DICOM_TAG_REFERRING_PHYSICIAN_NAME, "HOUSE^MD", false);
-          tags.SetValue(Orthanc::DICOM_TAG_SERIES_NUMBER, "1", false);
-          tags.SetValue(Orthanc::DICOM_TAG_SOP_CLASS_UID, "1.2.840.10008.5.1.4.1.1.1", false);
-          tags.SetValue(Orthanc::DICOM_TAG_STUDY_ID, "STUDY", false);
-          tags.SetValue(Orthanc::DICOM_TAG_VIEW_POSITION, "", false);
-
-          if (context_ != NULL)
-          {
-            widget.GetScene().ExportDicom(*context_->GetOrthancApiClient(),
-                                          tags, std::string(), 0.1, 0.1, widget.IsInverted(),
-                                          false /* autoCrop */, widget.GetInterpolation(), EXPORT_USING_PAM);
-          }
-
-          break;
-        }
-
-        case 'i':
-          widget.SwitchInvert();
-          break;
-
-        case 't':
-          tool_ = Tool_Move;
-          break;
-
-        case 'n':
-        {
-          switch (widget.GetInterpolation())
-          {
-          case ImageInterpolation_Nearest:
-            LOG(INFO) << "Switching to bilinear interpolation";
-            widget.SetInterpolation(ImageInterpolation_Bilinear);
-            break;
-
-          case ImageInterpolation_Bilinear:
-            LOG(INFO) << "Switching to nearest neighbor interpolation";
-            widget.SetInterpolation(ImageInterpolation_Nearest);
-            break;
-
-          default:
-            throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-          }
-          
-          break;
-        }
-
-        case 'r':
-          tool_ = Tool_Rotate;
-          break;
-
-        case 's':
-          tool_ = Tool_Resize;
-          break;
-
-        case 'w':
-          tool_ = Tool_Windowing;
-          break;
-
-        case 'y':
-          if (modifiers & KeyboardModifiers_Control)
-          {
-            undoRedoStack_.Redo();
-            widget.NotifyContentChanged();
-          }
-          break;
-
-        case 'z':
-          if (modifiers & KeyboardModifiers_Control)
-          {
-            undoRedoStack_.Undo();
-            widget.NotifyContentChanged();
-          }
-          break;
-
-        default:
-          break;
-        }
-      }
-    };
-
-
-
-    class SingleFrameEditorApplication :
-        public SampleSingleCanvasApplicationBase,
-        public IObserver
-    {
-    private:
-      boost::shared_ptr<RadiographyScene>   scene_;
-      RadiographyEditorInteractor           interactor_;
-      RadiographyMaskLayer*                 maskLayer_;
-
-    public:
-      virtual ~SingleFrameEditorApplication()
-      {
-        LOG(WARNING) << "Destroying the application";
-      }
-      
-      virtual void DeclareStartupOptions(boost::program_options::options_description& options)
-      {
-        boost::program_options::options_description generic("Sample options");
-        generic.add_options()
-            ("instance", boost::program_options::value<std::string>(),
-             "Orthanc ID of the instance")
-            ("frame", boost::program_options::value<unsigned int>()->default_value(0),
-             "Number of the frame, for multi-frame DICOM instances")
-            ;
-
-        options.add(generic);
-      }
-
-      virtual void Initialize(StoneApplicationContext* context,
-                              Deprecated::IStatusBar& statusBar,
-                              const boost::program_options::variables_map& parameters)
-      {
-        using namespace OrthancStone;
-
-        context_ = context;
-        interactor_.SetContext(*context);
-
-        statusBar.SetMessage("Use the key \"a\" to reinitialize the layout");
-        statusBar.SetMessage("Use the key \"c\" to crop");
-        statusBar.SetMessage("Use the key \"e\" to export DICOM to the Orthanc server");
-        statusBar.SetMessage("Use the key \"f\" to switch full screen");
-        statusBar.SetMessage("Use the key \"i\" to invert contrast");
-        statusBar.SetMessage("Use the key \"m\" to modify the mask");
-        statusBar.SetMessage("Use the key \"n\" to switch between nearest neighbor and bilinear interpolation");
-        statusBar.SetMessage("Use the key \"r\" to rotate objects");
-        statusBar.SetMessage("Use the key \"s\" to resize objects (not applicable to DICOM layers)");
-        statusBar.SetMessage("Use the key \"t\" to move (translate) objects");
-        statusBar.SetMessage("Use the key \"w\" to change windowing");
-        
-        statusBar.SetMessage("Use the key \"ctrl-z\" to undo action");
-        statusBar.SetMessage("Use the key \"ctrl-y\" to redo action");
-
-        if (parameters.count("instance") != 1)
-        {
-          LOG(ERROR) << "The instance ID is missing";
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-        }
-
-        std::string instance = parameters["instance"].as<std::string>();
-        //int frame = parameters["frame"].as<unsigned int>();
-
-        scene_.reset(new RadiographyScene);
-        
-        RadiographyLayer& dicomLayer = scene_->LoadDicomFrame(*context->GetOrthancApiClient(), instance, 0, false, NULL);
-        //scene_->LoadDicomFrame(instance, frame, false); //.SetPan(200, 0);
-        // = scene_->LoadDicomFrame(context->GetOrthancApiClient(), "61f3143e-96f34791-ad6bbb8d-62559e75-45943e1b", 0, false, NULL);
-
-#if !defined(ORTHANC_ENABLE_WASM) || ORTHANC_ENABLE_WASM != 1
-        Orthanc::HttpClient::ConfigureSsl(true, "/etc/ssl/certs/ca-certificates.crt");
-#endif
-        
-        //scene_->LoadDicomWebFrame(context->GetWebService());
-        
-        std::vector<Orthanc::ImageProcessing::ImagePoint> mask;
-        mask.push_back(Orthanc::ImageProcessing::ImagePoint(1100, 100));
-        mask.push_back(Orthanc::ImageProcessing::ImagePoint(1100, 1000));
-        mask.push_back(Orthanc::ImageProcessing::ImagePoint(2000, 1000));
-        mask.push_back(Orthanc::ImageProcessing::ImagePoint(2200, 150));
-        mask.push_back(Orthanc::ImageProcessing::ImagePoint(1500, 550));
-        maskLayer_ = dynamic_cast<RadiographyMaskLayer*>(&(scene_->LoadMask(mask, dynamic_cast<RadiographyDicomLayer&>(dicomLayer), 128.0f, NULL)));
-        interactor_.SetMaskLayer(maskLayer_);
-
-        {
-          std::unique_ptr<Orthanc::ImageAccessor> renderedTextAlpha(TextRenderer::Render(Orthanc::EmbeddedResources::UBUNTU_FONT, 100,
-                                                                                    "%öÇaA&#"));
-          RadiographyLayer& layer = scene_->LoadAlphaBitmap(renderedTextAlpha.release(), NULL);
-          dynamic_cast<RadiographyAlphaLayer&>(layer).SetForegroundValue(200.0f * 256.0f);
-        }
-
-        {
-          RadiographyTextLayer::RegisterFont("ubuntu", Orthanc::EmbeddedResources::UBUNTU_FONT);
-          RadiographyLayer& layer = scene_->LoadText("Hello\nworld", "ubuntu", 20, 128, NULL, false);
-          layer.SetResizeable(true);
-        }
-        
-        {
-          RadiographyLayer& layer = scene_->LoadTestBlock(100, 50, NULL);
-          layer.SetResizeable(true);
-          layer.SetPan(0, 200);
-        }
-        
-        boost::shared_ptr<RadiographyWidget> widget(new RadiographyWidget(scene_, "main-widget"));
-        widget->SetTransmitMouseOver(true);
-        widget->SetInteractor(interactor_);
-        SetCentralWidget(widget);
-
-        //scene_->SetWindowing(128, 256);
-      }
-    };
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SingleVolumeApplication.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,277 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "SampleApplicationBase.h"
-#include "../../../Framework/dev.h"
-#include "../../../Framework/Layers/LineMeasureTracker.h"
-#include "../../../Framework/Layers/CircleMeasureTracker.h"
-
-#include <Core/Toolbox.h>
-#include <Core/Logging.h>
-
-#include <Plugins/Samples/Common/OrthancHttpConnection.h>   // TODO REMOVE
-#include "../../../Framework/Layers/DicomStructureSetSlicer.h"   // TODO REMOVE
-#include "../../../Framework/Toolbox/MessagingToolbox.h"   // TODO REMOVE
-
-namespace OrthancStone
-{
-  namespace Samples
-  {
-    class SingleVolumeApplication : public SampleApplicationBase
-    {
-    private:
-      class Interactor : public VolumeImageInteractor
-      {
-      private:
-        SliceViewerWidget&  widget_;
-        size_t        layer_;
-        
-      protected:
-        virtual void NotifySliceContentChange(const ISlicedVolume& volume,
-                                       const size_t& sliceIndex,
-                                       const Slice& slice)
-        {
-          const OrthancVolumeImage& image = dynamic_cast<const OrthancVolumeImage&>(volume);
-
-          RenderStyle s = widget_.GetLayerStyle(layer_);
-
-          if (image.FitWindowingToRange(s, slice.GetConverter()))
-          {
-            //printf("Windowing: %f => %f\n", s.customWindowCenter_, s.customWindowWidth_);
-            widget_.SetLayerStyle(layer_, s);
-          }
-        }
-
-        virtual void MouseOver(CairoContext& context,
-                               WorldSceneWidget& widget,
-                               const ViewportGeometry& view,
-                               double x,
-                               double y,
-                               IStatusBar* statusBar)
-        {
-          const SliceViewerWidget& w = dynamic_cast<const SliceViewerWidget&>(widget);
-          Vector p = w.GetSlice().MapSliceToWorldCoordinates(x, y);
-          printf("%f %f %f\n", p[0], p[1], p[2]);
-        }
-      
-      public:
-        Interactor(OrthancVolumeImage& volume,
-                   SliceViewerWidget& widget,
-                   VolumeProjection projection,
-                   size_t layer) :
-          VolumeImageInteractor(volume, widget, projection),
-          widget_(widget),
-          layer_(layer)
-        {
-        }
-      };
-
-
-    public:
-      virtual void DeclareStartupOptions(boost::program_options::options_description& options)
-      {
-        boost::program_options::options_description generic("Sample options");
-        generic.add_options()
-          ("series", boost::program_options::value<std::string>(), 
-           "Orthanc ID of the series")
-          ("instance", boost::program_options::value<std::string>(), 
-           "Orthanc ID of a multi-frame instance that describes a 3D volume")
-          ("threads", boost::program_options::value<unsigned int>()->default_value(3), 
-           "Number of download threads")
-          ("projection", boost::program_options::value<std::string>()->default_value("axial"), 
-           "Projection of interest (can be axial, sagittal or coronal)")
-          ("reverse", boost::program_options::value<bool>()->default_value(false), 
-           "Reverse the normal direction of the volume")
-          ;
-
-        options.add(generic);    
-      }
-
-      virtual void Initialize(IStatusBar& statusBar,
-                              const boost::program_options::variables_map& parameters)
-      {
-        using namespace OrthancStone;
-
-        if (parameters.count("series") > 1 ||
-            parameters.count("instance") > 1)
-        {
-          LOG(ERROR) << "Only one series or instance is allowed";
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-        }
-
-        if (parameters.count("series") == 1 &&
-            parameters.count("instance") == 1)
-        {
-          LOG(ERROR) << "Cannot specify both a series and an instance";
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-        }
-
-        std::string series;
-        if (parameters.count("series") == 1)
-        {
-          series = parameters["series"].as<std::string>();
-        }
-        
-        std::string instance;
-        if (parameters.count("instance") == 1)
-        {
-          instance = parameters["instance"].as<std::string>();
-        }
-        
-        if (series.empty() &&
-            instance.empty())
-        {
-          LOG(ERROR) << "The series ID or instance ID is missing";
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-        }
-
-        //unsigned int threads = parameters["threads"].as<unsigned int>();
-        //bool reverse = parameters["reverse"].as<bool>();
-
-        std::string tmp = parameters["projection"].as<std::string>();
-        Orthanc::Toolbox::ToLowerCase(tmp);
-
-        VolumeProjection projection;
-        if (tmp == "axial")
-        {
-          projection = VolumeProjection_Axial;
-        }
-        else if (tmp == "sagittal")
-        {
-          projection = VolumeProjection_Sagittal;
-        }
-        else if (tmp == "coronal")
-        {
-          projection = VolumeProjection_Coronal;
-        }
-        else
-        {
-          LOG(ERROR) << "Unknown projection: " << tmp;
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-        }
-
-        std::unique_ptr<SliceViewerWidget> widget(new SliceViewerWidget);
-
-#if 1
-        std::unique_ptr<OrthancVolumeImage> volume(new OrthancVolumeImage(context.GetWebService(), true));
-        if (series.empty())
-        {
-          volume->ScheduleLoadInstance(instance);
-        }
-        else
-        {
-          volume->ScheduleLoadSeries(series);
-        }
-
-        widget->AddLayer(new VolumeImageMPRSlicer(*volume));
-
-        context_->AddInteractor(new Interactor(*volume, *widget, projection, 0));
-        context_->AddSlicedVolume(volume.release());
-
-        if (1)
-        {
-          RenderStyle s;
-          //s.drawGrid_ = true;
-          s.alpha_ = 1;
-          s.windowing_ = ImageWindowing_Bone;
-          widget->SetLayerStyle(0, s);
-        }
-        else
-        {
-          RenderStyle s;
-          s.alpha_ = 1;
-          s.applyLut_ = true;
-          s.lut_ = Orthanc::EmbeddedResources::COLORMAP_JET;
-          s.interpolation_ = ImageInterpolation_Bilinear;
-          widget->SetLayerStyle(0, s);
-        }
-#else
-        std::unique_ptr<OrthancVolumeImage> ct(new OrthancVolumeImage(context_->GetWebService(), false));
-        //ct->ScheduleLoadSeries("15a6f44a-ac7b88fe-19c462d9-dddd918e-b01550d8");  // 0178023P
-        //ct->ScheduleLoadSeries("dd069910-4f090474-7d2bba07-e5c10783-f9e4fb1d");
-        //ct->ScheduleLoadSeries("a04ecf01-79b2fc33-58239f7e-ad9db983-28e81afa");  // IBA
-        //ct->ScheduleLoadSeries("03677739-1d8bca40-db1daf59-d74ff548-7f6fc9c0");  // 0522c0001 TCIA
-        ct->ScheduleLoadSeries("295e8a13-dfed1320-ba6aebb2-9a13e20f-1b3eb953");  // Captain
-        
-        std::unique_ptr<OrthancVolumeImage> pet(new OrthancVolumeImage(context_->GetWebService(), true));
-        //pet->ScheduleLoadSeries("48d2997f-8e25cd81-dd715b64-bd79cdcc-e8fcee53");  // 0178023P
-        //pet->ScheduleLoadSeries("aabad2e7-80702b5d-e599d26c-4f13398e-38d58a9e");
-        //pet->ScheduleLoadInstance("830a69ff-8e4b5ee3-b7f966c8-bccc20fb-d322dceb"); // IBA 1
-        //pet->ScheduleLoadInstance("337876a1-a68a9718-f15abccd-38faafa1-b99b496a"); // IBA 2
-        //pet->ScheduleLoadInstance("830a69ff-8e4b5ee3-b7f966c8-bccc20fb-d322dceb");  // IBA 3
-        //pet->ScheduleLoadInstance("269f26f4-0c83eeeb-2e67abbd-5467a40f-f1bec90c");  // 0522c0001 TCIA
-        pet->ScheduleLoadInstance("f080888c-0ab7528a-f7d9c28c-84980eb1-ff3b0ae6");  // Captain 1
-        //pet->ScheduleLoadInstance("4f78055b-6499a2c5-1e089290-394acc05-3ec781c1");  // Captain 2
-
-        std::unique_ptr<StructureSetLoader> rtStruct(new StructureSetLoader(context_->GetWebService()));
-        //rtStruct->ScheduleLoadInstance("c2ebc17b-6b3548db-5e5da170-b8ecab71-ea03add3");  // 0178023P
-        //rtStruct->ScheduleLoadInstance("54460695-ba3885ee-ddf61ac0-f028e31d-a6e474d9");  // IBA
-        //rtStruct->ScheduleLoadInstance("17cd032b-ad92a438-ca05f06a-f9e96668-7e3e9e20");  // 0522c0001 TCIA
-        rtStruct->ScheduleLoadInstance("96c889ab-29fe5c54-dda6e66c-3949e4da-58f90d75");  // Captain
-        
-        widget->AddLayer(new VolumeImageMPRSlicer(*ct));
-        widget->AddLayer(new VolumeImageMPRSlicer(*pet));
-        widget->AddLayer(new DicomStructureSetSlicer(*rtStruct));
-        
-        context_->AddInteractor(new Interactor(*pet, *widget, projection, 1));
-        //context_->AddInteractor(new VolumeImageInteractor(*ct, *widget, projection));
-
-        context_->AddSlicedVolume(ct.release());
-        context_->AddSlicedVolume(pet.release());
-        context_->AddVolumeLoader(rtStruct.release());
-
-        {
-          RenderStyle s;
-          //s.drawGrid_ = true;
-          s.alpha_ = 1;
-          s.windowing_ = ImageWindowing_Bone;
-          widget->SetLayerStyle(0, s);
-        }
-
-        {
-          RenderStyle s;
-          //s.drawGrid_ = true;
-          s.SetColor(255, 0, 0);  // Draw missing PET layer in red
-          s.alpha_ = 0.5;
-          s.applyLut_ = true;
-          s.lut_ = Orthanc::EmbeddedResources::COLORMAP_JET;
-          s.interpolation_ = ImageInterpolation_Bilinear;
-          s.windowing_ = ImageWindowing_Custom;
-          s.customWindowCenter_ = 0;
-          s.customWindowWidth_ = 128;
-          widget->SetLayerStyle(1, s);
-        }
-#endif
-
-
-        statusBar.SetMessage("Use the keys \"b\", \"l\" and \"d\" to change Hounsfield windowing");
-        statusBar.SetMessage("Use the keys \"t\" to track the (X,Y,Z) mouse coordinates");
-        statusBar.SetMessage("Use the keys \"m\" to measure distances");
-        statusBar.SetMessage("Use the keys \"c\" to draw circles");
-
-        widget->SetTransmitMouseOver(true);
-        context_->SetCentralWidget(widget.release());
-      }
-    };
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/StoneSampleCommands.yml	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-#
-#        1         2         3         4         5         6         7         8
-# 345678901234567890123456789012345678901234567890123456789012345678901234567890
-#
-rootName: StoneSampleCommands
-
-# +---------------------------------+
-# | Messages from TypeScript to C++ |
-# +---------------------------------+
-
-enum Tool:
-  - LineMeasure
-  - CircleMeasure
-  - Crop
-  - Windowing
-  - Zoom
-  - Pan
-  - Move
-  - Rotate
-  - Resize
-  - Mask
-
-struct SelectTool:
-  __handler: cpp
-  tool: Tool
-
-enum ActionType:
-  - UndoCrop
-  - Rotate
-  - Invert
-
-struct Action:
-  __handler: cpp
-  type: ActionType
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/StoneSampleCommands_generate.py	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-import sys
-import os
-
-# add the generation script location to the search paths
-sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'Resources', 'CodeGeneration'))
-
-# import the code generation tooling script
-import stonegentool
-
-schemaFile = os.path.join(os.path.dirname(__file__), 'StoneSampleCommands.yml')
-outDir = os.path.dirname(__file__)
-
-# ignition!
-stonegentool.Process(schemaFile, outDir)
-
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/StoneSampleCommands_generated.hpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,703 +0,0 @@
-/*
-         1         2         3         4         5         6         7
-12345678901234567890123456789012345678901234567890123456789012345678901234567890
-
-Generated on 2019-03-18 12:07:42.696093 by stonegentool
-
-*/
-#pragma once
-
-#include <exception>
-#include <iostream>
-#include <string>
-#include <sstream>
-#include <assert.h>
-#include <memory>
-#include <json/json.h>
-
-//#define STONEGEN_NO_CPP11 1
-
-#ifdef STONEGEN_NO_CPP11
-#define StoneSmartPtr std::unique_ptr
-#else 
-#define StoneSmartPtr std::unique_ptr
-#endif 
-
-namespace StoneSampleCommands
-{
-  /** Throws in case of problem */
-  inline void _StoneDeserializeValue(int32_t& destValue, const Json::Value& jsonValue)
-  {
-    destValue = jsonValue.asInt();
-  }
-
-  inline Json::Value _StoneSerializeValue(int32_t value)
-  {
-    Json::Value result(value);
-    return result;
-  }
-
-  inline void _StoneDeserializeValue(Json::Value& destValue, const Json::Value& jsonValue)
-  {
-    destValue = jsonValue;
-  }
-
-  inline Json::Value _StoneSerializeValue(Json::Value value)
-  {
-    return value;
-  }
-
-  /** Throws in case of problem */
-  inline void _StoneDeserializeValue(double& destValue, const Json::Value& jsonValue)
-  {
-    destValue = jsonValue.asDouble();
-  }
-
-  inline Json::Value _StoneSerializeValue(double value)
-  {
-    Json::Value result(value);
-    return result;
-  }
-
-  /** Throws in case of problem */
-  inline void _StoneDeserializeValue(bool& destValue, const Json::Value& jsonValue)
-  {
-    destValue = jsonValue.asBool();
-  }
-
-  inline Json::Value _StoneSerializeValue(bool value)
-  {
-    Json::Value result(value);
-    return result;
-  }
-
-  /** Throws in case of problem */
-  inline void _StoneDeserializeValue(
-       std::string& destValue
-     , const Json::Value& jsonValue)
-  {
-    destValue = jsonValue.asString();
-  }
-
-  inline Json::Value _StoneSerializeValue(const std::string& value)
-  {
-    // the following is better than 
-    Json::Value result(value.data(),value.data()+value.size());
-    return result;
-  }
-
-  inline std::string MakeIndent(size_t indent)
-  {
-    char* txt = reinterpret_cast<char*>(malloc(indent+1)); // NO EXCEPTION BELOW!!!!!!!!!!!!
-    for(size_t i = 0; i < indent; ++i)
-      txt[i] = ' ';
-    txt[indent] = 0;
-    std::string retVal(txt);
-    free(txt); // NO EXCEPTION ABOVE !!!!!!!!!!
-    return retVal;
-  }
-
-  // generic dumper
-  template<typename T>
-  std::ostream& StoneDumpValue(std::ostream& out, const T& value, size_t indent)
-  {
-    out << MakeIndent(indent) << value;
-    return out;
-  }
-
-  // string dumper
-  inline std::ostream& StoneDumpValue(std::ostream& out, const std::string& value, size_t indent)
-  {
-    out << MakeIndent(indent) << "\"" << value  << "\"";
-    return out;
-  }
-
-  /** Throws in case of problem */
-  template<typename T>
-  void _StoneDeserializeValue(
-    std::map<std::string, T>& destValue, const Json::Value& jsonValue)
-  {
-    destValue.clear();
-    for (
-      Json::Value::const_iterator itr = jsonValue.begin();
-      itr != jsonValue.end();
-      itr++)
-    {
-      std::string key;
-      _StoneDeserializeValue(key, itr.key());
-
-      T innerDestValue;
-      _StoneDeserializeValue(innerDestValue, *itr);
-
-      destValue[key] = innerDestValue;
-    }
-  }
-
-  template<typename T>
-  Json::Value _StoneSerializeValue(const std::map<std::string,T>& value)
-  {
-    Json::Value result(Json::objectValue);
-
-    for (typename std::map<std::string, T>::const_iterator it = value.cbegin();
-      it != value.cend(); ++it)
-    {
-      // it->first it->second
-      result[it->first] = _StoneSerializeValue(it->second);
-    }
-    return result;
-  }
-
-  template<typename T>
-  std::ostream& StoneDumpValue(std::ostream& out, const std::map<std::string,T>& value, size_t indent)
-  {
-    out << MakeIndent(indent) << "{\n";
-    for (typename std::map<std::string, T>::const_iterator it = value.cbegin();
-      it != value.cend(); ++it)
-    {
-      out << MakeIndent(indent+2) << "\"" << it->first << "\" : ";
-      StoneDumpValue(out, it->second, indent+2);
-    }
-    out << MakeIndent(indent) << "}\n";
-    return out;
-  }
-
-  /** Throws in case of problem */
-  template<typename T>
-  void _StoneDeserializeValue(
-    std::vector<T>& destValue, const Json::Value& jsonValue)
-  {
-    destValue.clear();
-    destValue.reserve(jsonValue.size());
-    for (Json::Value::ArrayIndex i = 0; i != jsonValue.size(); i++)
-    {
-      T innerDestValue;
-      _StoneDeserializeValue(innerDestValue, jsonValue[i]);
-      destValue.push_back(innerDestValue);
-    }
-  }
-
-  template<typename T>
-  Json::Value _StoneSerializeValue(const std::vector<T>& value)
-  {
-    Json::Value result(Json::arrayValue);
-    for (size_t i = 0; i < value.size(); ++i)
-    {
-      result.append(_StoneSerializeValue(value[i]));
-    }
-    return result;
-  }
-
-  template<typename T>
-  std::ostream& StoneDumpValue(std::ostream& out, const std::vector<T>& value, size_t indent)
-  {
-    out << MakeIndent(indent) << "[\n";
-    for (size_t i = 0; i < value.size(); ++i)
-    {
-      StoneDumpValue(out, value[i], indent+2);
-    }
-    out << MakeIndent(indent) << "]\n";
-    return out;
-  }
-
-  inline void StoneCheckSerializedValueTypeGeneric(const Json::Value& value)
-  {
-    if ((!value.isMember("type")) || (!value["type"].isString()))
-    {
-      std::stringstream ss;
-      ss << "Cannot deserialize value ('type' key invalid)";
-      throw std::runtime_error(ss.str());
-    }
-  }
-
-  inline void StoneCheckSerializedValueType(
-    const Json::Value& value, std::string typeStr)
-  {
-    StoneCheckSerializedValueTypeGeneric(value);
-
-    std::string actTypeStr = value["type"].asString();
-    if (actTypeStr != typeStr)
-    {
-      std::stringstream ss;
-      ss << "Cannot deserialize type" << actTypeStr
-        << "into " << typeStr;
-      throw std::runtime_error(ss.str());
-    }
-  }
-
-  // end of generic methods
-
-// end of generic methods
-
-  enum Tool {
-    Tool_LineMeasure,
-    Tool_CircleMeasure,
-    Tool_Crop,
-    Tool_Windowing,
-    Tool_Zoom,
-    Tool_Pan,
-    Tool_Move,
-    Tool_Rotate,
-    Tool_Resize,
-    Tool_Mask,
-  };
-
-  inline std::string ToString(const Tool& value)
-  {
-    if( value == Tool_LineMeasure)
-    {
-      return std::string("LineMeasure");
-    }
-    if( value == Tool_CircleMeasure)
-    {
-      return std::string("CircleMeasure");
-    }
-    if( value == Tool_Crop)
-    {
-      return std::string("Crop");
-    }
-    if( value == Tool_Windowing)
-    {
-      return std::string("Windowing");
-    }
-    if( value == Tool_Zoom)
-    {
-      return std::string("Zoom");
-    }
-    if( value == Tool_Pan)
-    {
-      return std::string("Pan");
-    }
-    if( value == Tool_Move)
-    {
-      return std::string("Move");
-    }
-    if( value == Tool_Rotate)
-    {
-      return std::string("Rotate");
-    }
-    if( value == Tool_Resize)
-    {
-      return std::string("Resize");
-    }
-    if( value == Tool_Mask)
-    {
-      return std::string("Mask");
-    }
-    std::stringstream ss;
-    ss << "Value \"" << value << "\" cannot be converted to Tool. Possible values are: "
-        << " LineMeasure = " << static_cast<int64_t>(Tool_LineMeasure)  << ", " 
-        << " CircleMeasure = " << static_cast<int64_t>(Tool_CircleMeasure)  << ", " 
-        << " Crop = " << static_cast<int64_t>(Tool_Crop)  << ", " 
-        << " Windowing = " << static_cast<int64_t>(Tool_Windowing)  << ", " 
-        << " Zoom = " << static_cast<int64_t>(Tool_Zoom)  << ", " 
-        << " Pan = " << static_cast<int64_t>(Tool_Pan)  << ", " 
-        << " Move = " << static_cast<int64_t>(Tool_Move)  << ", " 
-        << " Rotate = " << static_cast<int64_t>(Tool_Rotate)  << ", " 
-        << " Resize = " << static_cast<int64_t>(Tool_Resize)  << ", " 
-        << " Mask = " << static_cast<int64_t>(Tool_Mask)  << ", " 
-        << std::endl;
-    std::string msg = ss.str();
-    throw std::runtime_error(msg);
-  }
-
-  inline void FromString(Tool& value, std::string strValue)
-  {
-    if( strValue == std::string("LineMeasure") )
-    {
-      value = Tool_LineMeasure;
-      return;
-    }
-    if( strValue == std::string("CircleMeasure") )
-    {
-      value = Tool_CircleMeasure;
-      return;
-    }
-    if( strValue == std::string("Crop") )
-    {
-      value = Tool_Crop;
-      return;
-    }
-    if( strValue == std::string("Windowing") )
-    {
-      value = Tool_Windowing;
-      return;
-    }
-    if( strValue == std::string("Zoom") )
-    {
-      value = Tool_Zoom;
-      return;
-    }
-    if( strValue == std::string("Pan") )
-    {
-      value = Tool_Pan;
-      return;
-    }
-    if( strValue == std::string("Move") )
-    {
-      value = Tool_Move;
-      return;
-    }
-    if( strValue == std::string("Rotate") )
-    {
-      value = Tool_Rotate;
-      return;
-    }
-    if( strValue == std::string("Resize") )
-    {
-      value = Tool_Resize;
-      return;
-    }
-    if( strValue == std::string("Mask") )
-    {
-      value = Tool_Mask;
-      return;
-    }
-
-    std::stringstream ss;
-    ss << "String \"" << strValue << "\" cannot be converted to Tool. Possible values are: LineMeasure CircleMeasure Crop Windowing Zoom Pan Move Rotate Resize Mask ";
-    std::string msg = ss.str();
-    throw std::runtime_error(msg);
-  }
-
-
-  inline void _StoneDeserializeValue(
-    Tool& destValue, const Json::Value& jsonValue)
-  {
-    FromString(destValue, jsonValue.asString());
-  }
-
-  inline Json::Value _StoneSerializeValue(const Tool& value)
-  {
-    std::string strValue = ToString(value);
-    return Json::Value(strValue);
-  }
-
-  inline std::ostream& StoneDumpValue(std::ostream& out, const Tool& value, size_t indent = 0)
-  {
-    if( value == Tool_LineMeasure)
-    {
-      out << MakeIndent(indent) << "LineMeasure" << std::endl;
-    }
-    if( value == Tool_CircleMeasure)
-    {
-      out << MakeIndent(indent) << "CircleMeasure" << std::endl;
-    }
-    if( value == Tool_Crop)
-    {
-      out << MakeIndent(indent) << "Crop" << std::endl;
-    }
-    if( value == Tool_Windowing)
-    {
-      out << MakeIndent(indent) << "Windowing" << std::endl;
-    }
-    if( value == Tool_Zoom)
-    {
-      out << MakeIndent(indent) << "Zoom" << std::endl;
-    }
-    if( value == Tool_Pan)
-    {
-      out << MakeIndent(indent) << "Pan" << std::endl;
-    }
-    if( value == Tool_Move)
-    {
-      out << MakeIndent(indent) << "Move" << std::endl;
-    }
-    if( value == Tool_Rotate)
-    {
-      out << MakeIndent(indent) << "Rotate" << std::endl;
-    }
-    if( value == Tool_Resize)
-    {
-      out << MakeIndent(indent) << "Resize" << std::endl;
-    }
-    if( value == Tool_Mask)
-    {
-      out << MakeIndent(indent) << "Mask" << std::endl;
-    }
-    return out;
-  }
-
-
-  enum ActionType {
-    ActionType_UndoCrop,
-    ActionType_Rotate,
-    ActionType_Invert,
-  };
-
-  inline std::string ToString(const ActionType& value)
-  {
-    if( value == ActionType_UndoCrop)
-    {
-      return std::string("UndoCrop");
-    }
-    if( value == ActionType_Rotate)
-    {
-      return std::string("Rotate");
-    }
-    if( value == ActionType_Invert)
-    {
-      return std::string("Invert");
-    }
-    std::stringstream ss;
-    ss << "Value \"" << value << "\" cannot be converted to ActionType. Possible values are: "
-        << " UndoCrop = " << static_cast<int64_t>(ActionType_UndoCrop)  << ", " 
-        << " Rotate = " << static_cast<int64_t>(ActionType_Rotate)  << ", " 
-        << " Invert = " << static_cast<int64_t>(ActionType_Invert)  << ", " 
-        << std::endl;
-    std::string msg = ss.str();
-    throw std::runtime_error(msg);
-  }
-
-  inline void FromString(ActionType& value, std::string strValue)
-  {
-    if( strValue == std::string("UndoCrop") )
-    {
-      value = ActionType_UndoCrop;
-      return;
-    }
-    if( strValue == std::string("Rotate") )
-    {
-      value = ActionType_Rotate;
-      return;
-    }
-    if( strValue == std::string("Invert") )
-    {
-      value = ActionType_Invert;
-      return;
-    }
-
-    std::stringstream ss;
-    ss << "String \"" << strValue << "\" cannot be converted to ActionType. Possible values are: UndoCrop Rotate Invert ";
-    std::string msg = ss.str();
-    throw std::runtime_error(msg);
-  }
-
-
-  inline void _StoneDeserializeValue(
-    ActionType& destValue, const Json::Value& jsonValue)
-  {
-    FromString(destValue, jsonValue.asString());
-  }
-
-  inline Json::Value _StoneSerializeValue(const ActionType& value)
-  {
-    std::string strValue = ToString(value);
-    return Json::Value(strValue);
-  }
-
-  inline std::ostream& StoneDumpValue(std::ostream& out, const ActionType& value, size_t indent = 0)
-  {
-    if( value == ActionType_UndoCrop)
-    {
-      out << MakeIndent(indent) << "UndoCrop" << std::endl;
-    }
-    if( value == ActionType_Rotate)
-    {
-      out << MakeIndent(indent) << "Rotate" << std::endl;
-    }
-    if( value == ActionType_Invert)
-    {
-      out << MakeIndent(indent) << "Invert" << std::endl;
-    }
-    return out;
-  }
-
-
-
-#ifdef _MSC_VER
-#pragma region SelectTool
-#endif //_MSC_VER
-
-  struct SelectTool
-  {
-    Tool tool;
-
-    SelectTool(Tool tool = Tool())
-    {
-      this->tool = tool;
-    }
-  };
-
-  inline void _StoneDeserializeValue(SelectTool& destValue, const Json::Value& value)
-  {
-    _StoneDeserializeValue(destValue.tool, value["tool"]);
-    }
-
-  inline Json::Value _StoneSerializeValue(const SelectTool& value)
-  {
-    Json::Value result(Json::objectValue);
-    result["tool"] = _StoneSerializeValue(value.tool);
-
-    return result;
-  }
-
-  inline std::ostream& StoneDumpValue(std::ostream& out, const SelectTool& value, size_t indent = 0)
-  {
-    out << MakeIndent(indent) << "{\n";
-    out << MakeIndent(indent) << "tool:\n";
-    StoneDumpValue(out, value.tool,indent+2);
-    out << "\n";
-
-    out << MakeIndent(indent) << "}\n";
-    return out;
-  }
-
-  inline void StoneDeserialize(SelectTool& destValue, const Json::Value& value)
-  {
-    StoneCheckSerializedValueType(value, "StoneSampleCommands.SelectTool");
-    _StoneDeserializeValue(destValue, value["value"]);
-  }
-
-  inline Json::Value StoneSerializeToJson(const SelectTool& value)
-  {
-    Json::Value result(Json::objectValue);
-    result["type"] = "StoneSampleCommands.SelectTool";
-    result["value"] = _StoneSerializeValue(value);
-    return result;
-  }
-
-  inline std::string StoneSerialize(const SelectTool& value)
-  {
-    Json::Value resultJson = StoneSerializeToJson(value);
-    std::string resultStr = resultJson.toStyledString();
-    return resultStr;
-  }
-
-#ifdef _MSC_VER
-#pragma endregion SelectTool
-#endif //_MSC_VER
-
-#ifdef _MSC_VER
-#pragma region Action
-#endif //_MSC_VER
-
-  struct Action
-  {
-    ActionType type;
-
-    Action(ActionType type = ActionType())
-    {
-      this->type = type;
-    }
-  };
-
-  inline void _StoneDeserializeValue(Action& destValue, const Json::Value& value)
-  {
-    _StoneDeserializeValue(destValue.type, value["type"]);
-    }
-
-  inline Json::Value _StoneSerializeValue(const Action& value)
-  {
-    Json::Value result(Json::objectValue);
-    result["type"] = _StoneSerializeValue(value.type);
-
-    return result;
-  }
-
-  inline std::ostream& StoneDumpValue(std::ostream& out, const Action& value, size_t indent = 0)
-  {
-    out << MakeIndent(indent) << "{\n";
-    out << MakeIndent(indent) << "type:\n";
-    StoneDumpValue(out, value.type,indent+2);
-    out << "\n";
-
-    out << MakeIndent(indent) << "}\n";
-    return out;
-  }
-
-  inline void StoneDeserialize(Action& destValue, const Json::Value& value)
-  {
-    StoneCheckSerializedValueType(value, "StoneSampleCommands.Action");
-    _StoneDeserializeValue(destValue, value["value"]);
-  }
-
-  inline Json::Value StoneSerializeToJson(const Action& value)
-  {
-    Json::Value result(Json::objectValue);
-    result["type"] = "StoneSampleCommands.Action";
-    result["value"] = _StoneSerializeValue(value);
-    return result;
-  }
-
-  inline std::string StoneSerialize(const Action& value)
-  {
-    Json::Value resultJson = StoneSerializeToJson(value);
-    std::string resultStr = resultJson.toStyledString();
-    return resultStr;
-  }
-
-#ifdef _MSC_VER
-#pragma endregion Action
-#endif //_MSC_VER
-
-#ifdef _MSC_VER
-#pragma region Dispatching code
-#endif //_MSC_VER
-
-  class IHandler
-  {
-  public:
-    virtual bool Handle(const SelectTool& value) = 0;
-    virtual bool Handle(const Action& value) = 0;
-  };
-
-  /** Service function for StoneDispatchToHandler */
-  inline bool StoneDispatchJsonToHandler(
-    const Json::Value& jsonValue, IHandler* handler)
-  {
-    StoneCheckSerializedValueTypeGeneric(jsonValue);
-    std::string type = jsonValue["type"].asString();
-    if (type == "")
-    {
-      // this should never ever happen
-      throw std::runtime_error("Caught empty type while dispatching");
-    }
-    else if (type == "StoneSampleCommands.SelectTool")
-    {
-      SelectTool value;
-      _StoneDeserializeValue(value, jsonValue["value"]);
-      return handler->Handle(value);
-    }
-    else if (type == "StoneSampleCommands.Action")
-    {
-      Action value;
-      _StoneDeserializeValue(value, jsonValue["value"]);
-      return handler->Handle(value);
-    }
-    else
-    {
-      return false;
-    }
-  }
-
-  /** Takes a serialized type and passes this to the handler */
-  inline bool StoneDispatchToHandler(std::string strValue, IHandler* handler)
-  {
-    Json::Value readValue;
-
-    Json::CharReaderBuilder builder;
-    Json::CharReader* reader = builder.newCharReader();
-
-    StoneSmartPtr<Json::CharReader> ptr(reader);
-
-    std::string errors;
-
-    bool ok = reader->parse(
-      strValue.c_str(),
-      strValue.c_str() + strValue.size(),
-      &readValue,
-      &errors
-    );
-    if (!ok)
-    {
-      std::stringstream ss;
-      ss << "Jsoncpp parsing error: " << errors;
-      throw std::runtime_error(ss.str());
-    }
-    return StoneDispatchJsonToHandler(readValue, handler);
-  }
-
-#ifdef _MSC_VER
-#pragma endregion Dispatching code
-#endif //_MSC_VER
-}
\ No newline at end of file
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/StoneSampleCommands_generated.ts	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,333 +0,0 @@
-/*
-         1         2         3         4         5         6         7
-12345678901234567890123456789012345678901234567890123456789012345678901234567890
-
-Generated on 2019-03-18 12:07:42.696093 by stonegentool
-
-*/
-
-function StoneCheckSerializedValueType(value: any, typeStr: string)
-{
-  StoneCheckSerializedValueTypeGeneric(value);
-
-  if (value['type'] != typeStr)
-  {
-    throw new Error(
-      `Cannot deserialize type ${value['type']} into ${typeStr}`);
-  }
-}
-
-function isString(val: any) :boolean
-{
-  return ((typeof val === 'string') || (val instanceof String));
-}
-
-function StoneCheckSerializedValueTypeGeneric(value: any)
-{
-  // console.//log("+-------------------------------------------------+");
-  // console.//log("|            StoneCheckSerializedValueTypeGeneric |");
-  // console.//log("+-------------------------------------------------+");
-  // console.//log("value = ");
-  // console.//log(value);
-  if ( (!('type' in value)) || (!isString(value.type)) )
-  {
-    throw new Error(
-      "Cannot deserialize value ('type' key invalid)");
-  }
-}
-
-// end of generic methods
-
-export enum Tool {
-  LineMeasure = "LineMeasure",
-  CircleMeasure = "CircleMeasure",
-  Crop = "Crop",
-  Windowing = "Windowing",
-  Zoom = "Zoom",
-  Pan = "Pan",
-  Move = "Move",
-  Rotate = "Rotate",
-  Resize = "Resize",
-  Mask = "Mask"
-};
-
-export function Tool_FromString(strValue:string) : Tool
-{
-  if( strValue == "LineMeasure" )
-  {
-    return Tool.LineMeasure;
-  }
-  if( strValue == "CircleMeasure" )
-  {
-    return Tool.CircleMeasure;
-  }
-  if( strValue == "Crop" )
-  {
-    return Tool.Crop;
-  }
-  if( strValue == "Windowing" )
-  {
-    return Tool.Windowing;
-  }
-  if( strValue == "Zoom" )
-  {
-    return Tool.Zoom;
-  }
-  if( strValue == "Pan" )
-  {
-    return Tool.Pan;
-  }
-  if( strValue == "Move" )
-  {
-    return Tool.Move;
-  }
-  if( strValue == "Rotate" )
-  {
-    return Tool.Rotate;
-  }
-  if( strValue == "Resize" )
-  {
-    return Tool.Resize;
-  }
-  if( strValue == "Mask" )
-  {
-    return Tool.Mask;
-  }
-
-  let msg : string =  `String ${strValue} cannot be converted to Tool. Possible values are: LineMeasure, CircleMeasure, Crop, Windowing, Zoom, Pan, Move, Rotate, Resize, Mask`;
-  throw new Error(msg);
-}
-
-export function Tool_ToString(value:Tool) : string
-{
-  if( value == Tool.LineMeasure )
-  {
-    return "LineMeasure";
-  }
-  if( value == Tool.CircleMeasure )
-  {
-    return "CircleMeasure";
-  }
-  if( value == Tool.Crop )
-  {
-    return "Crop";
-  }
-  if( value == Tool.Windowing )
-  {
-    return "Windowing";
-  }
-  if( value == Tool.Zoom )
-  {
-    return "Zoom";
-  }
-  if( value == Tool.Pan )
-  {
-    return "Pan";
-  }
-  if( value == Tool.Move )
-  {
-    return "Move";
-  }
-  if( value == Tool.Rotate )
-  {
-    return "Rotate";
-  }
-  if( value == Tool.Resize )
-  {
-    return "Resize";
-  }
-  if( value == Tool.Mask )
-  {
-    return "Mask";
-  }
-
-  let msg : string = `Value ${value} cannot be converted to Tool. Possible values are: `;
-  {
-    let _LineMeasure_enumValue : string = Tool.LineMeasure; // enums are strings in stonecodegen, so this will work.
-    let msg_LineMeasure : string = `LineMeasure (${_LineMeasure_enumValue}), `;
-    msg = msg + msg_LineMeasure;
-  }
-  {
-    let _CircleMeasure_enumValue : string = Tool.CircleMeasure; // enums are strings in stonecodegen, so this will work.
-    let msg_CircleMeasure : string = `CircleMeasure (${_CircleMeasure_enumValue}), `;
-    msg = msg + msg_CircleMeasure;
-  }
-  {
-    let _Crop_enumValue : string = Tool.Crop; // enums are strings in stonecodegen, so this will work.
-    let msg_Crop : string = `Crop (${_Crop_enumValue}), `;
-    msg = msg + msg_Crop;
-  }
-  {
-    let _Windowing_enumValue : string = Tool.Windowing; // enums are strings in stonecodegen, so this will work.
-    let msg_Windowing : string = `Windowing (${_Windowing_enumValue}), `;
-    msg = msg + msg_Windowing;
-  }
-  {
-    let _Zoom_enumValue : string = Tool.Zoom; // enums are strings in stonecodegen, so this will work.
-    let msg_Zoom : string = `Zoom (${_Zoom_enumValue}), `;
-    msg = msg + msg_Zoom;
-  }
-  {
-    let _Pan_enumValue : string = Tool.Pan; // enums are strings in stonecodegen, so this will work.
-    let msg_Pan : string = `Pan (${_Pan_enumValue}), `;
-    msg = msg + msg_Pan;
-  }
-  {
-    let _Move_enumValue : string = Tool.Move; // enums are strings in stonecodegen, so this will work.
-    let msg_Move : string = `Move (${_Move_enumValue}), `;
-    msg = msg + msg_Move;
-  }
-  {
-    let _Rotate_enumValue : string = Tool.Rotate; // enums are strings in stonecodegen, so this will work.
-    let msg_Rotate : string = `Rotate (${_Rotate_enumValue}), `;
-    msg = msg + msg_Rotate;
-  }
-  {
-    let _Resize_enumValue : string = Tool.Resize; // enums are strings in stonecodegen, so this will work.
-    let msg_Resize : string = `Resize (${_Resize_enumValue}), `;
-    msg = msg + msg_Resize;
-  }
-  {
-    let _Mask_enumValue : string = Tool.Mask; // enums are strings in stonecodegen, so this will work.
-    let msg_Mask : string = `Mask (${_Mask_enumValue})`;
-    msg = msg + msg_Mask;
-  }
-  throw new Error(msg);
-}
-
-export enum ActionType {
-  UndoCrop = "UndoCrop",
-  Rotate = "Rotate",
-  Invert = "Invert"
-};
-
-export function ActionType_FromString(strValue:string) : ActionType
-{
-  if( strValue == "UndoCrop" )
-  {
-    return ActionType.UndoCrop;
-  }
-  if( strValue == "Rotate" )
-  {
-    return ActionType.Rotate;
-  }
-  if( strValue == "Invert" )
-  {
-    return ActionType.Invert;
-  }
-
-  let msg : string =  `String ${strValue} cannot be converted to ActionType. Possible values are: UndoCrop, Rotate, Invert`;
-  throw new Error(msg);
-}
-
-export function ActionType_ToString(value:ActionType) : string
-{
-  if( value == ActionType.UndoCrop )
-  {
-    return "UndoCrop";
-  }
-  if( value == ActionType.Rotate )
-  {
-    return "Rotate";
-  }
-  if( value == ActionType.Invert )
-  {
-    return "Invert";
-  }
-
-  let msg : string = `Value ${value} cannot be converted to ActionType. Possible values are: `;
-  {
-    let _UndoCrop_enumValue : string = ActionType.UndoCrop; // enums are strings in stonecodegen, so this will work.
-    let msg_UndoCrop : string = `UndoCrop (${_UndoCrop_enumValue}), `;
-    msg = msg + msg_UndoCrop;
-  }
-  {
-    let _Rotate_enumValue : string = ActionType.Rotate; // enums are strings in stonecodegen, so this will work.
-    let msg_Rotate : string = `Rotate (${_Rotate_enumValue}), `;
-    msg = msg + msg_Rotate;
-  }
-  {
-    let _Invert_enumValue : string = ActionType.Invert; // enums are strings in stonecodegen, so this will work.
-    let msg_Invert : string = `Invert (${_Invert_enumValue})`;
-    msg = msg + msg_Invert;
-  }
-  throw new Error(msg);
-}
-
-
-
-export class SelectTool {
-  tool:Tool;
-
-  constructor() {
-  }
-
-  public StoneSerialize(): string {
-    let container: object = {};
-    container['type'] = 'StoneSampleCommands.SelectTool';
-    container['value'] = this;
-    return JSON.stringify(container);
-  }
-
-  public static StoneDeserialize(valueStr: string) : SelectTool
-  {
-    let value: any = JSON.parse(valueStr);
-    StoneCheckSerializedValueType(value, 'StoneSampleCommands.SelectTool');
-    let result: SelectTool = value['value'] as SelectTool;
-    return result;
-  }
-}
-export class Action {
-  type:ActionType;
-
-  constructor() {
-  }
-
-  public StoneSerialize(): string {
-    let container: object = {};
-    container['type'] = 'StoneSampleCommands.Action';
-    container['value'] = this;
-    return JSON.stringify(container);
-  }
-
-  public static StoneDeserialize(valueStr: string) : Action
-  {
-    let value: any = JSON.parse(valueStr);
-    StoneCheckSerializedValueType(value, 'StoneSampleCommands.Action');
-    let result: Action = value['value'] as Action;
-    return result;
-  }
-}
-
-export interface IHandler {
-};
-
-/** Service function for StoneDispatchToHandler */
-export function StoneDispatchJsonToHandler(
-  jsonValue: any, handler: IHandler): boolean
-{
-  StoneCheckSerializedValueTypeGeneric(jsonValue);
-  let type: string = jsonValue["type"];
-  if (type == "")
-  {
-    // this should never ever happen
-    throw new Error("Caught empty type while dispatching");
-  }
-  else
-  {
-    return false;
-  }
-}
-
-/** Takes a serialized type and passes this to the handler */
-export function StoneDispatchToHandler(
-  strValue: string, handler: IHandler): boolean
-{
-  // console.//log("+------------------------------------------------+");
-  // console.//log("|            StoneDispatchToHandler              |");
-  // console.//log("+------------------------------------------------+");
-  // console.//log("strValue = ");
-  // console.//log(strValue);
-  let jsonValue: any = JSON.parse(strValue)
-  return StoneDispatchJsonToHandler(jsonValue, handler);
-}
\ No newline at end of file
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/SynchronizedSeriesApplication.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "SampleInteractor.h"
-
-#include "../../../Framework/Toolbox/OrthancSeriesLoader.h"
-#include "../../../Framework/Layers/SeriesFrameRendererFactory.h"
-#include "../../../Framework/Layers/ReferenceLineFactory.h"
-#include "../../../Framework/Widgets/LayoutWidget.h"
-
-#include <Core/Logging.h>
-
-namespace OrthancStone
-{
-  namespace Samples
-  {
-    class SynchronizedSeriesApplication : public SampleApplicationBase
-    {
-    private:   
-      LayeredSceneWidget* CreateSeriesWidget(BasicApplicationContext& context,
-                                             const std::string& series)
-      {
-        std::unique_ptr<ISeriesLoader> loader
-          (new OrthancSeriesLoader(context.GetWebService().GetConnection(), series));
-
-        std::unique_ptr<SampleInteractor> interactor(new SampleInteractor(*loader, false));
-
-        std::unique_ptr<LayeredSceneWidget> widget(new LayeredSceneWidget);
-        widget->AddLayer(new SeriesFrameRendererFactory(loader.release(), false));
-        widget->SetSlice(interactor->GetCursor().GetCurrentSlice());
-        widget->SetInteractor(*interactor);
-
-        context.AddInteractor(interactor.release());
-
-        return widget.release();
-      }
-
-    public:
-      virtual void DeclareCommandLineOptions(boost::program_options::options_description& options)
-      {
-        boost::program_options::options_description generic("Sample options");
-        generic.add_options()
-          ("a", boost::program_options::value<std::string>(), 
-           "Orthanc ID of the 1st series")
-          ("b", boost::program_options::value<std::string>(), 
-           "Orthanc ID of the 2nd series")
-          ("c", boost::program_options::value<std::string>(), 
-           "Orthanc ID of the 3rd series")
-          ;
-
-        options.add(generic);    
-      }
-
-      virtual void Initialize(BasicApplicationContext& context,
-                              IStatusBar& statusBar,
-                              const boost::program_options::variables_map& parameters)
-      {
-        if (parameters.count("a") != 1 ||
-            parameters.count("b") != 1 ||
-            parameters.count("c") != 1)
-        {
-          LOG(ERROR) << "At least one of the three series IDs is missing";
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-        }
-
-        std::unique_ptr<LayeredSceneWidget> a(CreateSeriesWidget(context, parameters["a"].as<std::string>()));
-        std::unique_ptr<LayeredSceneWidget> b(CreateSeriesWidget(context, parameters["b"].as<std::string>()));
-        std::unique_ptr<LayeredSceneWidget> c(CreateSeriesWidget(context, parameters["c"].as<std::string>()));
-
-        ReferenceLineFactory::Configure(*a, *b);
-        ReferenceLineFactory::Configure(*a, *c);
-        ReferenceLineFactory::Configure(*b, *c);
-
-        std::unique_ptr<LayoutWidget> layout(new LayoutWidget);
-        layout->SetPadding(5);
-        layout->AddWidget(a.release());
-
-        std::unique_ptr<LayoutWidget> layoutB(new LayoutWidget);
-        layoutB->SetVertical();
-        layoutB->SetPadding(5);
-        layoutB->AddWidget(b.release());
-        layoutB->AddWidget(c.release());
-        layout->AddWidget(layoutB.release());
-
-        context.SetCentralWidget(layout.release());        
-      }
-    };
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/TestPatternApplication.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "SampleApplicationBase.h"
-
-#include "../../../Framework/Widgets/TestCairoWidget.h"
-#include "../../../Framework/Widgets/TestWorldSceneWidget.h"
-#include "../../../Framework/Widgets/LayoutWidget.h"
-
-namespace OrthancStone
-{
-  namespace Samples
-  {
-    class TestPatternApplication : public SampleApplicationBase
-    {
-    public:
-      virtual void DeclareStartupOptions(boost::program_options::options_description& options)
-      {
-        boost::program_options::options_description generic("Sample options");
-        generic.add_options()
-          ("animate", boost::program_options::value<bool>()->default_value(true), "Animate the test pattern")
-          ;
-
-        options.add(generic);    
-      }
-
-      virtual void Initialize(IStatusBar& statusBar,
-                              const boost::program_options::variables_map& parameters)
-      {
-        using namespace OrthancStone;
-
-        std::unique_ptr<LayoutWidget> layout(new LayoutWidget);
-        layout->SetPadding(10);
-        layout->SetBackgroundCleared(true);
-        layout->AddWidget(new TestCairoWidget(parameters["animate"].as<bool>()));
-        layout->AddWidget(new TestWorldSceneWidget(parameters["animate"].as<bool>()));
-
-        context_->SetCentralWidget(layout.release());
-        context_->SetUpdateDelay(25);  // If animation, update the content each 25ms
-      }
-    };
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/index.html	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-<!doctype html>
-
-<html lang="us">
-  <head>
-    <meta charset="utf-8" />
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-
-    <!-- Disable pinch zoom on mobile devices -->
-    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
-    <meta name="HandheldFriendly" content="true" />
-
-    <title>Wasm Samples</title>
-
-<body>
-    <ul>
-      <li><a href="simple-viewer/simple-viewer.html">Simple Viewer Project (you may add ?studyId=XXX in the url)</a></li>
-      <li><a href="single-frame.html?instance=XXX">Single frame application (you must replace XXX by a valid instance id in the url)</a></li>
-      <li><a href="single-frame-editor.html?instance=XXX">Single frame editor application (you must replace XXX by a valid instance id in the url)</a></li>
-      <li><a href="simple-viewer-single-file.html">Simple Viewer Single file (to be replaced by other samples)</a></li>
-    </ul>
-</body>
-
-</html>
\ No newline at end of file
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/samples-styles.css	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-html, body {
-  width: 100%;
-  height: 100%;
-  margin: 0px;
-  border: 0;
-  overflow: hidden; /*  Disable scrollbars */
-  display: block;  /* No floating content on sides */
-  background-color: black;
-  color: white;
-  font-family: Arial, Helvetica, sans-serif;
-}
-
-canvas {
-  left:0px;
-  top:0px;
-}
\ No newline at end of file
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/simple-viewer-single-file.html	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-<!doctype html>
-
-<html lang="us">
-
-<head>
-  <meta charset="utf-8" />
-  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-
-  <!-- Disable pinch zoom on mobile devices -->
-  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
-  <meta name="HandheldFriendly" content="true" />
-
-  <title>Simple Viewer</title>
-  <link href="samples-styles.css" rel="stylesheet" />
-
-<body>
-  <div id="breadcrumb">
-    <span id="patient-id"></span>
-    <span id="study-description"></span>
-    <span id="series-description"></span>
-  </div>
-  <div style="height: calc(100% - 50px)">
-    <div style="width: 20%; height: 100%; display: inline-block">
-      <canvas id="canvas"></canvas>
-    </div>
-    <div style="width: 70%; height: 100%; display: inline-block">
-      <canvas id="canvas2"></canvas>
-    </div>
-  </div>
-  <div id="toolbox" style="height: 50px">
-    <input tool-selector="line-measure" type="radio" name="radio-tool-selector" class="tool-selector">line
-    <input tool-selector="circle-measure" type="radio" name="radio-tool-selector" class="tool-selector">circle
-    <button action-trigger="action1" class="action-trigger">action1</button>
-    <button action-trigger="action2" class="action-trigger">action2</button>
-  </div>
-  <script type="text/javascript" src="app-simple-viewer-single-file.js"></script>
-</body>
-
-</html>
\ No newline at end of file
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/simple-viewer-single-file.ts	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-import wasmApplicationRunner = require('../../../Platforms/Wasm/wasm-application-runner');
-
-wasmApplicationRunner.InitializeWasmApplication("OrthancStoneSimpleViewerSingleFile", "/orthanc");
-
-function SelectTool(toolName: string) {
-    var command = {
-        command: "selectTool",
-        args: {
-            toolName: toolName
-        }
-    };
-    wasmApplicationRunner.SendSerializedMessageToStoneApplication(JSON.stringify(command));
-
-}
-
-function PerformAction(commandName: string) {
-    var command = {
-        command: commandName,
-        commandType: "simple",
-        args: {}
-    };
-    wasmApplicationRunner.SendSerializedMessageToStoneApplication(JSON.stringify(command));
-}
-
-//initializes the buttons
-//-----------------------
-// install "SelectTool" handlers
-document.querySelectorAll("[tool-selector]").forEach((e) => {
-    console.log(e);
-    (e as HTMLInputElement).addEventListener("click", () => {
-        console.log(e);
-        SelectTool(e.attributes["tool-selector"].value);
-    });
-});
-
-// install "PerformAction" handlers
-document.querySelectorAll("[action-trigger]").forEach((e) => {
-    (e as HTMLInputElement).addEventListener("click", () => {
-        PerformAction(e.attributes["action-trigger"].value);
-    });
-});
-
-// this method is called "from the C++ code" when the StoneApplication is updated.
-// it can be used to update the UI of the application
-function UpdateWebApplicationWithString(statusUpdateMessage: string) {
-  console.log(statusUpdateMessage);
-  
-  if (statusUpdateMessage.startsWith("series-description=")) {
-      document.getElementById("series-description").innerText = statusUpdateMessage.split("=")[1];
-  }
-}
-
-function UpdateWebApplicationWithSerializedMessage(statusUpdateMessageString: string) {
-  console.log("updating web application with serialized message: ", statusUpdateMessageString);
-  console.log("<not supported in the simple viewer (single file)!>");
-}
-
-// make it available to other js scripts in the application
-(<any> window).UpdateWebApplicationWithString = UpdateWebApplicationWithString;
-
-(<any> window).UpdateWebApplicationWithSerializedMessage = UpdateWebApplicationWithSerializedMessage;
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/simple-viewer-single-file.tsconfig.json	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-{
-    "extends" : "./tsconfig-samples",
-    "compilerOptions": {
-        // "outFile": "../build-web/app-simple-viewer-single-file.js"
-    },
-    "include" : [
-        "simple-viewer-single-file.ts"
-    ]
-}
\ No newline at end of file
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/single-frame-editor.html	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-<!doctype html>
-
-<html lang="us">
-  <head>
-    <meta charset="utf-8" />
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-
-    <!-- Disable pinch zoom on mobile devices -->
-    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
-    <meta name="HandheldFriendly" content="true" />
-
-    <title>Simple Viewer</title>
-    <link href="samples-styles.css" rel="stylesheet" />
-
-<body>
-  <div style="width: 100%; height: 100%">
-    <canvas id="canvas"></canvas>
-  </div>
-  <script type="text/javascript" src="app-single-frame-editor.js"></script>
-</body>
-
-</html>
\ No newline at end of file
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/single-frame-editor.ts	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-import wasmApplicationRunner = require('../../../Platforms/Wasm/wasm-application-runner');
-
-wasmApplicationRunner.InitializeWasmApplication("OrthancStoneSingleFrameEditor", "/orthanc");
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/single-frame-editor.tsconfig.json	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-{
-    "extends" : "./tsconfig-samples",
-    "compilerOptions": {
-    },
-    "include" : [
-        "single-frame-editor.ts"
-    ]
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/single-frame.html	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-<!doctype html>
-
-<html lang="us">
-  <head>
-    <meta charset="utf-8" />
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-
-    <!-- Disable pinch zoom on mobile devices -->
-    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
-    <meta name="HandheldFriendly" content="true" />
-
-    <title>Simple Viewer</title>
-    <link href="samples-styles.css" rel="stylesheet" />
-
-<body>
-  <div style="width: 100%; height: 100%">
-    <canvas id="canvas"></canvas>
-  </div>
-  <script type="text/javascript" src="app-single-frame.js"></script>
-</body>
-
-</html>
\ No newline at end of file
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/single-frame.ts	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-import wasmApplicationRunner = require('../../../Platforms/Wasm/wasm-application-runner');
-
-wasmApplicationRunner.InitializeWasmApplication("OrthancStoneSingleFrame", "/orthanc");
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/single-frame.tsconfig.json	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-{
-    "extends" : "./tsconfig-samples",
-    "compilerOptions": {
-    },
-    "include" : [
-        "single-frame.ts"
-    ]
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/Web/tsconfig-samples.json	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-{
-    "extends" : "../../../Platforms/Wasm/tsconfig-stone",
-    "compilerOptions": {
-        "sourceMap": false,
-        "lib" : [
-            "es2017",
-            "dom",
-            "dom.iterable"
-        ]
-    }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/build-wasm.sh	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#!/bin/bash
-#
-# usage:
-# to build all targets in Debug:
-# ./build-wasm.sh
-#
-# to build a single target in release:
-# ./build-wasm.sh OrthancStoneSingleFrameEditor Release
-
-set -e
-
-target=${1:-all}
-buildType=${2:-Debug}
-
-currentDir=$(pwd)
-samplesRootDir=$(pwd)
-
-mkdir -p $samplesRootDir/build-wasm
-cd $samplesRootDir/build-wasm
-
-source ~/apps/emsdk/emsdk_env.sh
-cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=~/apps/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_BUILD_TYPE=$buildType -DSTONE_SOURCES_DIR=$currentDir/../../../orthanc-stone -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT=$currentDir/../../../orthanc -DALLOW_DOWNLOADS=ON .. -DENABLE_WASM=ON
-ninja $target
-
-echo "-- building the web application -- "
-cd $currentDir
-./build-web.sh
\ No newline at end of file
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/build-wasm.sh.old	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-#!/bin/bash
-#
-# usage:
-# to build all targets:
-# ./build-wasm.sh
-#
-# to build a single target:
-# ./build-wasm.sh OrthancStoneSingleFrameEditor
-
-set -e
-
-target=${1:-all}
-
-currentDir=$(pwd)
-samplesRootDir=$(pwd)
-
-mkdir -p $samplesRootDir/build-wasm
-cd $samplesRootDir/build-wasm
-
-source ~/apps/emsdk/emsdk_env.sh
-cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN}/cmake/Modules/Platform/Emscripten.cmake \
-  -DCMAKE_BUILD_TYPE=Release \
-  -DSTONE_SOURCES_DIR=$currentDir/../../../orthanc-stone \
-  -DORTHANC_FRAMEWORK_SOURCE=path \
-  -DORTHANC_FRAMEWORK_ROOT=$currentDir/../../../orthanc \
-  -DALLOW_DOWNLOADS=ON .. \
-  -DENABLE_WASM=ON
-
-ninja $target
-
-echo "-- building the web application -- "
-cd $currentDir
-./build-web.sh
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/build-web-ext.sh	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-#!/bin/bash
-
-set -e
-
-target=${1:-all}
-# this script currently assumes that the wasm code has been built on its side and is availabie in build-wasm/
-
-currentDir=$(pwd)
-
-scriptDirRel=$(dirname $0)
-#echo $scriptDirRel
-scriptDirAbs=$(realpath $scriptDirRel)
-echo $scriptDirAbs
-
-samplesRootDir=scriptDirAbs
-
-outputDir=$samplesRootDir/build-web/
-mkdir -p $outputDir
-
-# files used by all single files samples
-cp $samplesRootDir/Web/index.html $outputDir
-cp $samplesRootDir/Web/samples-styles.css $outputDir
-
-# build simple-viewer-single-file (obsolete project)
-if [[ $target == "all" || $target == "OrthancStoneSimpleViewerSingleFile" ]]; then
-  cp $samplesRootDir/Web/simple-viewer-single-file.html $outputDir
-  tsc --allowJs --project $samplesRootDir/Web/simple-viewer-single-file.tsconfig.json
-  cp $currentDir/build-wasm/OrthancStoneSimpleViewerSingleFile.js  $outputDir
-  cp $currentDir/build-wasm/OrthancStoneSimpleViewerSingleFile.wasm  $outputDir
-fi
-
-# build single-frame
-if [[ $target == "all" || $target == "OrthancStoneSingleFrame" ]]; then
-  cp $samplesRootDir/Web/single-frame.html $outputDir
-  tsc --allowJs --project $samplesRootDir/Web/single-frame.tsconfig.json
-  cp $currentDir/build-wasm/OrthancStoneSingleFrame.js  $outputDir
-  cp $currentDir/build-wasm/OrthancStoneSingleFrame.wasm  $outputDir
-fi
-
-# build single-frame-editor
-if [[ $target == "all" || $target == "OrthancStoneSingleFrameEditor" ]]; then
-  cp $samplesRootDir/Web/single-frame-editor.html $outputDir
-  tsc --allowJs --project $samplesRootDir/Web/single-frame-editor.tsconfig.json
-  cp $currentDir/build-wasm/OrthancStoneSingleFrameEditor.js  $outputDir
-  cp $currentDir/build-wasm/OrthancStoneSingleFrameEditor.wasm  $outputDir
-fi
-
-# build simple-viewer project
-if [[ $target == "all" || $target == "OrthancStoneSimpleViewer" ]]; then
-  mkdir -p $outputDir/simple-viewer/
-  cp $samplesRootDir/SimpleViewer/Wasm/simple-viewer.html $outputDir/simple-viewer/
-  cp $samplesRootDir/SimpleViewer/Wasm/styles.css $outputDir/simple-viewer/
-  tsc --allowJs --project $samplesRootDir/SimpleViewer/Wasm/tsconfig-simple-viewer.json
-  cp $currentDir/build-wasm/OrthancStoneSimpleViewer.js  $outputDir/simple-viewer/
-  cp $currentDir/build-wasm/OrthancStoneSimpleViewer.wasm  $outputDir/simple-viewer/
-fi
-
-cd $currentDir
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/build-web.sh	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-#!/bin/bash
-
-set -e
-
-target=${1:-all}
-# this script currently assumes that the wasm code has been built on its side and is availabie in build-wasm/
-
-currentDir=$(pwd)
-samplesRootDir=$(pwd)
-
-echo "*************************************************************************"
-echo "samplesRootDir = $samplesRootDir"
-echo "*************************************************************************"
-
-outputDir=$samplesRootDir/build-web/
-mkdir -p "$outputDir"
-
-# files used by all single files samples
-cp "$samplesRootDir/Web/index.html" "$outputDir"
-cp "$samplesRootDir/Web/samples-styles.css" "$outputDir"
-
-# # build simple-viewer-single-file (obsolete project)
-# if [[ $target == "all" || $target == "OrthancStoneSimpleViewerSingleFile" ]]; then
-#   cp $samplesRootDir/Web/simple-viewer-single-file.html $outputDir
-#   tsc --project $samplesRootDir/Web/simple-viewer-single-file.tsconfig.json --outDir "$outputDir"
-#   browserify \
-#       "$outputDir/Platforms/Wasm/wasm-application-runner.js" \
-#       "$outputDir/Applications/Samples/Web/simple-viewer-single-file.js" \
-#       -o "$outputDir/app-simple-viewer-single-file.js"
-#   cp "$currentDir/build-wasm/OrthancStoneSimpleViewerSingleFile.js"  $outputDir
-#   cp "$currentDir/build-wasm/OrthancStoneSimpleViewerSingleFile.wasm"  $outputDir
-# fi
-
-# # build single-frame
-# if [[ $target == "all" || $target == "OrthancStoneSingleFrame" ]]; then
-#   cp $samplesRootDir/Web/single-frame.html $outputDir
-#   tsc --project $samplesRootDir/Web/single-frame.tsconfig.json --outDir "$outputDir"
-#   browserify \
-#       "$outputDir/Platforms/Wasm/wasm-application-runner.js" \
-#       "$outputDir/Applications/Samples/Web/single-frame.js" \
-#       -o "$outputDir/app-single-frame.js"
-#   cp "$currentDir/build-wasm/OrthancStoneSingleFrame.js"  $outputDir
-#   cp "$currentDir/build-wasm/OrthancStoneSingleFrame.wasm"  $outputDir
-# fi
-
-# build single-frame-editor
-if [[ $target == "all" || $target == "OrthancStoneSingleFrameEditor" ]]; then
-  cp $samplesRootDir/Web/single-frame-editor.html $outputDir
-  tsc --project $samplesRootDir/Web/single-frame-editor.tsconfig.json --outDir "$outputDir"
-  browserify \
-      "$outputDir/Platforms/Wasm/wasm-application-runner.js" \
-      "$outputDir/Applications/Samples/Web/single-frame-editor.js" \
-      -o "$outputDir/app-single-frame-editor.js"
-  cp "$currentDir/build-wasm/OrthancStoneSingleFrameEditor.js"  $outputDir
-  cp "$currentDir/build-wasm/OrthancStoneSingleFrameEditor.wasm"  $outputDir
-fi
-
-# build simple-viewer project
-if [[ $target == "all" || $target == "OrthancStoneSimpleViewer" ]]; then
-  mkdir -p $outputDir/simple-viewer/
-  cp $samplesRootDir/SimpleViewer/Wasm/simple-viewer.html $outputDir/simple-viewer/
-  cp $samplesRootDir/SimpleViewer/Wasm/styles.css $outputDir/simple-viewer/
-  
-  # the root dir must contain all the source files for the whole project
-  tsc --module commonjs --allowJs --project "$samplesRootDir/SimpleViewer/Wasm/tsconfig-simple-viewer.json" --rootDir "$samplesRootDir/../.." --outDir "$outputDir/simple-viewer/"
-  browserify \
-    "$outputDir/simple-viewer/Platforms/Wasm/wasm-application-runner.js" \
-    "$outputDir/simple-viewer/Applications/Samples/SimpleViewer/Wasm/simple-viewer.js" \
-    -o "$outputDir/simple-viewer/app-simple-viewer.js"
-  cp "$currentDir/build-wasm/OrthancStoneSimpleViewer.js"  "$outputDir/simple-viewer/"
-  cp "$currentDir/build-wasm/OrthancStoneSimpleViewer.wasm"  "$outputDir/simple-viewer/"
-fi
-
-cd $currentDir
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/get-requirements-windows.ps1	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-
-if ($true) {
-
-    Write-Error "This script is obsolete. Please work under WSL and run build-wasm.sh"
-
-} else {
-
-    param(
-        [IO.DirectoryInfo] $EmsdkRootDir = "C:\Emscripten",
-        [bool] $Overwrite = $false
-      )
-    
-    if (Test-Path -Path $EmsdkRootDir) {
-        if( $Override) {
-            Remove-Item -Path $EmsdkRootDir -Force -Recurse
-        } else {
-            throw "The `"$EmsdkRootDir`" folder may not exist! Use the Overwrite flag to bypass this check."
-        }
-    }
-    
-    # TODO: detect whether git is installed
-    # choco install -y git
-    
-    Write-Host "Will retrieve the Emscripten SDK to the `"$EmsdkRootDir`" folder"
-    
-    $EmsdkParentDir = split-path -Parent $EmsdkRootDir
-    $EmsdkRootName = split-path -Leaf $EmsdkRootDir
-    
-    Push-Location $EmsdkParentDir
-    
-    git clone https://github.com/juj/emsdk.git $EmsdkRootName
-    cd $EmsdkRootName
-    
-    git pull
-    
-    ./emsdk install latest
-    
-    ./emsdk activate latest
-    
-    echo "INFO: the ~/.emscripten file has been configured for this installation of Emscripten."
-    
-    Write-Host "emsdk is now installed in $EmsdkRootDir"
-    
-    Pop-Location
-
-}
-
-
-
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/nginx.local.conf	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-# Local config to serve the WASM samples static files and reverse proxy Orthanc.
-# Uses port 9977 instead of 80.
-
-# `events` section is mandatory
-events {
-  worker_connections 1024; # Default: 1024
-}
-
-http {
-
-  # prevent nginx sync issues on OSX
-  proxy_buffering off;
-
-  server {
-    listen 9977 default_server;
-    client_max_body_size 4G;
-
-    # location may have to be adjusted depending on your OS and nginx install
-    include /etc/nginx/mime.types;
-    # if not in your system mime.types, add this line to support WASM:
-    # types {
-    #    application/wasm                      wasm; 
-    # }
-
-    # serve WASM static files
-    root build-web/;
-    location / {
-	}
-
-    # reverse proxy orthanc
-	location /orthanc/ {
-		rewrite /orthanc(.*) $1 break;
-		proxy_pass http://127.0.0.1:8042;
-		proxy_set_header Host $http_host;
-		proxy_set_header my-auth-header good-token;
-		proxy_request_buffering off;
-		proxy_max_temp_file_size 0;
-		client_max_body_size 0;
-	}
-
-
-  }
-  
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/package-lock.json	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-{
-  "requires": true,
-  "lockfileVersion": 1,
-  "dependencies": {
-    "typescript": {
-      "version": "3.2.2",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.2.tgz",
-      "integrity": "sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg=="
-    }
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/CMakeLists.txt	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-cmake_minimum_required(VERSION 2.8.3)
-project(RtViewerDemo)
-
-if(MSVC)
-  add_definitions(/MP)
-  if (CMAKE_BUILD_TYPE MATCHES DEBUG)
-    add_definitions(/JMC)
-  endif()
-endif()
-
-message("-------------------------------------------------------------------------------------------------------------------")
-message("ORTHANC_FRAMEWORK_ROOT is set to ${ORTHANC_FRAMEWORK_ROOT}")
-message("-------------------------------------------------------------------------------------------------------------------")
-
-if(NOT DEFINED ORTHANC_FRAMEWORK_ROOT)
-  message(FATAL_ERROR "The location of the Orthanc source repository must be set in the ORTHANC_FRAMEWORK_ROOT CMake variable")
-endif()
-
-message("-------------------------------------------------------------------------------------------------------------------")
-message("STONE_SOURCES_DIR is set to ${STONE_SOURCES_DIR}")
-message("-------------------------------------------------------------------------------------------------------------------")
-
-if(NOT DEFINED STONE_SOURCES_DIR)
-  message(FATAL_ERROR "The location of the Stone of Orthanc source repository must be set in the STONE_SOURCES_DIR CMake variable")
-endif()
-
-include(${STONE_SOURCES_DIR}/Resources/CMake/OrthancStoneParameters.cmake)
-
-if (OPENSSL_NO_CAPIENG)
-add_definitions(-DOPENSSL_NO_CAPIENG=1)
-endif()
-
-set(ENABLE_SDL OFF CACHE BOOL "Target SDL Native application")
-set(ENABLE_QT OFF CACHE BOOL "Target Qt Native application")
-set(ENABLE_WASM OFF CACHE BOOL "Target WASM application")
-
-if (ENABLE_WASM)
-  #####################################################################
-  ## Configuration of the Emscripten compiler for WebAssembly target
-  #####################################################################
-
-  set(WASM_FLAGS "-s WASM=1")
-  set(WASM_FLAGS "${WASM_FLAGS} -s STRICT=1") # drops support for all deprecated build options
-  set(WASM_FLAGS "${WASM_FLAGS} -s FILESYSTEM=1") # if we don't include it, gen_uuid.c fails to build because srand, getpid(), ... are not defined
-  set(WASM_FLAGS "${WASM_FLAGS} -s DISABLE_EXCEPTION_CATCHING=0") # actually enable exception catching 
-  set(WASM_FLAGS "${WASM_FLAGS} -s ERROR_ON_MISSING_LIBRARIES=1")
-
-  if (CMAKE_BUILD_TYPE MATCHES DEBUG)
-    set(WASM_FLAGS "${WASM_FLAGS} -g4") # generate debug information
-    set(WASM_FLAGS "${WASM_FLAGS} -s ASSERTIONS=2") # more runtime checks
-  else()
-    set(WASM_FLAGS "${WASM_FLAGS} -Os") # optimize for web (speed and size)
-  endif()
-
-  set(WASM_MODULE_NAME "StoneFrameworkModule" CACHE STRING "Name of the WebAssembly module")
-
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WASM_FLAGS}")
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WASM_FLAGS}")
-
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${WASM_FLAGS}")  # not always clear which flags are for the compiler and which one are for the linker -> pass them all to the linker too
-  # set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --js-library ${STONE_SOURCES_DIR}/Applications/Samples/samples-library.js")
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --js-library ${STONE_SOURCES_DIR}/Platforms/Wasm/WasmWebService.js")
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --js-library ${STONE_SOURCES_DIR}/Platforms/Wasm/WasmDelayedCallExecutor.js")
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --js-library ${STONE_SOURCES_DIR}/Platforms/Wasm/default-library.js")
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXTRA_EXPORTED_RUNTIME_METHODS='[\"ccall\", \"cwrap\"]'")
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXPORT_NAME='\"${WASM_MODULE_NAME}\"'")
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ALLOW_MEMORY_GROWTH=1")
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s TOTAL_MEMORY=536870912")
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s TOTAL_STACK=128000000")
-
-  add_definitions(-DORTHANC_ENABLE_WASM=1)
-  set(ORTHANC_SANDBOXED ON)
-
-elseif (ENABLE_QT OR ENABLE_SDL)
-
-  set(ENABLE_NATIVE ON)
-  set(ORTHANC_SANDBOXED OFF)
-  set(ENABLE_CRYPTO_OPTIONS ON)
-  set(ENABLE_GOOGLE_TEST ON)
-  set(ENABLE_WEB_CLIENT ON)
-
-endif()
-
-
-#####################################################################
-## Configuration for Orthanc
-#####################################################################
-
-if (ORTHANC_STONE_VERSION STREQUAL "mainline")
-  set(ORTHANC_FRAMEWORK_VERSION "mainline")
-  set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "hg")
-else()
-  set(ORTHANC_FRAMEWORK_VERSION "1.4.1")
-  set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "web")
-endif()
-
-set(ORTHANC_FRAMEWORK_SOURCE "${ORTHANC_FRAMEWORK_DEFAULT_SOURCE}" CACHE STRING "Source of the Orthanc source code (can be \"hg\", \"archive\", \"web\" or \"path\")")
-set(ORTHANC_FRAMEWORK_ARCHIVE "" CACHE STRING "Path to the Orthanc archive, if ORTHANC_FRAMEWORK_SOURCE is \"archive\"")
-set(ORTHANC_FRAMEWORK_ROOT "" CACHE STRING "Path to the Orthanc source directory, if ORTHANC_FRAMEWORK_SOURCE is \"path\"")
-
-add_definitions(
-  -DORTHANC_ENABLE_LOGGING_PLUGIN=0
-  )
-
-
-#####################################################################
-## Build a static library containing the Orthanc Stone framework
-#####################################################################
-
-LIST(APPEND ORTHANC_BOOST_COMPONENTS program_options)
-
-include(${STONE_SOURCES_DIR}/Resources/CMake/OrthancStoneConfiguration.cmake)
-
-add_library(OrthancStone STATIC
-  ${ORTHANC_STONE_SOURCES}
-  )
-
-#####################################################################
-## Build all the sample applications
-#####################################################################
-
-include_directories(${ORTHANC_STONE_ROOT})
-
-list(APPEND RTVIEWERDEMO_APPLICATION_SOURCES
-  ${ORTHANC_STONE_ROOT}/Applications/Samples/SampleInteractor.h
-  ${ORTHANC_STONE_ROOT}/Applications/Samples/SampleApplicationBase.h
-  )
-
-if (ENABLE_WASM)
-  list(APPEND RTVIEWERDEMO_APPLICATION_SOURCES
-    ${STONE_WASM_SOURCES}
-    )
-endif()
-
-add_executable(RtViewerDemo
-  main.cpp
-  ${RTVIEWERDEMO_APPLICATION_SOURCES}
-)
-set_target_properties(RtViewerDemo PROPERTIES COMPILE_DEFINITIONS ORTHANC_STONE_SAMPLE=3)
-target_include_directories(RtViewerDemo PRIVATE ${ORTHANC_STONE_ROOT})
-target_link_libraries(RtViewerDemo OrthancStone)
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/build-sdl-msvc15.ps1	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-if (-not (Test-Path "build-sdl-msvc15")) {
-  mkdir -p "build-sdl-msvc15"
-}
-
-cd build-sdl-msvc15
-
-cmake -G "Visual Studio 15 2017 Win64" -DSTATIC_BUILD=ON -DOPENSSL_NO_CAPIENG=ON -DORTHANC_FRAMEWORK_SOURCE=path -DSTONE_SOURCES_DIR="$($pwd)\..\..\..\.." -DORTHANC_FRAMEWORK_ROOT="$($pwd)\..\..\..\..\..\orthanc" -DALLOW_DOWNLOADS=ON -DENABLE_SDL=ON .. 
-
-if (!$?) {
-	Write-Error 'cmake configuration failed' -ErrorAction Stop
-}
-
-cmake --build . --target RtViewerDemo --config Debug
-
-if (!$?) {
-	Write-Error 'cmake build failed' -ErrorAction Stop
-}
-
-cd Debug
-
-.\RtViewerDemo.exe --ct-series=a04ecf01-79b2fc33-58239f7e-ad9db983-28e81afa --dose-instance=830a69ff-8e4b5ee3-b7f966c8-bccc20fb-d322dceb --struct-instance=54460695-ba3885ee-ddf61ac0-f028e31d-a6e474d9
-
-
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/build-wasm.sh	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-#!/bin/bash
-#
-# usage:
-# build-wasm BUILD_TYPE
-# where BUILD_TYPE is Debug, RelWithDebInfo or Release
-
-set -e
-
-buildType=${1:-Debug}
-
-currentDir=$(pwd)
-currentDirAbs=$(realpath $currentDir)
-
-mkdir -p build-wasm
-cd build-wasm
-
-source ~/apps/emsdk/emsdk_env.sh
-cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN}/cmake/Modules/Platform/Emscripten.cmake \
--DCMAKE_BUILD_TYPE=$buildType -DSTONE_SOURCES_DIR=$currentDirAbs/../../../../orthanc-stone \
--DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT=$currentDirAbs/../../../../orthanc \
--DALLOW_DOWNLOADS=ON .. -DENABLE_WASM=ON
-
-ninja $target
-
-echo "-- building the web application -- "
-cd $currentDir
-./build-web.sh
-
-echo "Launch start-serving-files.sh to access the web sample application locally"
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/build-web.sh	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-#!/bin/bash
-
-set -e
-
-target=${1:-all}
-# this script currently assumes that the wasm code has been built on its side and is availabie in build-wasm/
-
-currentDir=$(pwd)
-samplesRootDir=$(pwd)
-
-tscOutput=$samplesRootDir/build-tsc-output/
-outputDir=$samplesRootDir/build-web/
-mkdir -p "$outputDir"
-
-# files used by all single files samples
-cp "$samplesRootDir/index.html" "$outputDir"
-cp "$samplesRootDir/samples-styles.css" "$outputDir"
-
-# build rt-viewer-demo
-cp $samplesRootDir/rt-viewer-demo.html $outputDir
-tsc --project $samplesRootDir/rt-viewer-demo.tsconfig.json --outDir "$tscOutput"
-browserify \
-    "$tscOutput/orthanc-stone/Platforms/Wasm/logger.js" \
-    "$tscOutput/orthanc-stone/Platforms/Wasm/stone-framework-loader.js" \
-    "$tscOutput/orthanc-stone/Platforms/Wasm/wasm-application-runner.js" \
-    "$tscOutput/orthanc-stone/Platforms/Wasm/wasm-viewport.js" \
-    "$tscOutput/rt-viewer-sample/rt-viewer-demo.js" \
-    -o "$outputDir/app-rt-viewer-demo.js"
-cp "$currentDir/build-wasm/RtViewerDemo.js"  $outputDir
-cp "$currentDir/build-wasm/RtViewerDemo.wasm"  $outputDir
-
-cd $currentDir
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/index.html	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-<!doctype html>
-
-<html lang="us">
-  <head>
-    <meta charset="utf-8" />
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-
-    <!-- Disable pinch zoom on mobile devices -->
-    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
-    <meta name="HandheldFriendly" content="true" />
-
-    <title>Wasm Samples</title>
-
-<body>
-    <ul>
-      <li><a href="rt-viewer-demo.html?ct-series=a04ecf01-79b2fc33-58239f7e-ad9db983-28e81afa&dose-instance=830a69ff-8e4b5ee3-b7f966c8-bccc20fb-d322dceb&struct-instance=54460695-ba3885ee-ddf61ac0-f028e31d-a6e474d9">RTSTRUCT + CT + RTDOSE viewer demo. Pplease replace the url arguments with suitable IDs (you can find those in the Orthanc Explorer, for instance)</a></li>
-    </ul>
-</body>
-
-</html>
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/main.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,893 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "Applications/IStoneApplication.h"
-#include "Framework/Widgets/WorldSceneWidget.h"
-#include "Framework/Widgets/LayoutWidget.h"
-
-#if ORTHANC_ENABLE_WASM==1
-  #include "Platforms/Wasm/WasmPlatformApplicationAdapter.h"
-  #include "Platforms/Wasm/Defaults.h"
-  #include "Platforms/Wasm/WasmViewport.h"
-#endif
-
-#if ORTHANC_ENABLE_QT==1
-  #include "Qt/SampleMainWindow.h"
-  #include "Qt/SampleMainWindowWithButtons.h"
-#endif
-
-#include "Framework/Layers/DicomSeriesVolumeSlicer.h"
-#include "Framework/Widgets/SliceViewerWidget.h"
-#include "Framework/Volumes/StructureSetLoader.h"
-
-#include <Core/Logging.h>
-#include <Core/OrthancException.h>
-#include <Core/Images/ImageTraits.h>
-
-#include <boost/math/constants/constants.hpp>
-#include "Framework/dev.h"
-#include "Framework/Widgets/LayoutWidget.h"
-#include "Framework/Layers/DicomStructureSetSlicer.h"
-
-namespace OrthancStone
-{
-  namespace Samples
-  {
-    class RtViewerDemoBaseApplication : public IStoneApplication
-    {
-    protected:
-      // ownership is transferred to the application context
-#ifndef RESTORE_NON_RTVIEWERDEMO_BEHAVIOR
-      LayoutWidget*          mainWidget_;
-#else
-      WorldSceneWidget*  mainWidget_;
-#endif
-
-    public:
-      virtual void Initialize(StoneApplicationContext* context,
-                              IStatusBar& statusBar,
-                              const boost::program_options::variables_map& parameters) ORTHANC_OVERRIDE
-      {
-      }
-
-      virtual std::string GetTitle() const ORTHANC_OVERRIDE
-      {
-        return "Stone of Orthanc - Sample";
-      }
-
-      /**
-       * In the basic samples, the commands are handled by the platform adapter and NOT
-       * by the application handler
-      */
-      virtual void HandleSerializedMessage(const char* data) ORTHANC_OVERRIDE {};
-
-
-      virtual void Finalize() ORTHANC_OVERRIDE {}
-      virtual IWidget* GetCentralWidget() ORTHANC_OVERRIDE {return mainWidget_;}
-
-#if ORTHANC_ENABLE_WASM==1
-      // default implementations for a single canvas named "canvas" in the HTML and an empty WasmApplicationAdapter
-
-      virtual void InitializeWasm() ORTHANC_OVERRIDE
-      {
-        AttachWidgetToWasmViewport("canvas", mainWidget_);
-      }
-
-      virtual WasmPlatformApplicationAdapter* CreateWasmApplicationAdapter(MessageBroker& broker)
-      {
-        return new WasmPlatformApplicationAdapter(broker, *this);
-      }
-#endif
-
-    };
-
-    // this application actually works in Qt and WASM
-    class RtViewerDemoBaseSingleCanvasWithButtonsApplication : public RtViewerDemoBaseApplication
-    {
-public:
-      virtual void OnPushButton1Clicked() {}
-      virtual void OnPushButton2Clicked() {}
-      virtual void OnTool1Clicked() {}
-      virtual void OnTool2Clicked() {}
-
-      virtual void GetButtonNames(std::string& pushButton1,
-                                  std::string& pushButton2,
-                                  std::string& tool1,
-                                  std::string& tool2
-                                  ) {
-        pushButton1 = "action1";
-        pushButton2 = "action2";
-        tool1 = "tool1";
-        tool2 = "tool2";
-      }
-
-#if ORTHANC_ENABLE_QT==1
-      virtual QStoneMainWindow* CreateQtMainWindow() {
-        return new SampleMainWindowWithButtons(dynamic_cast<OrthancStone::NativeStoneApplicationContext&>(*context_), *this);
-      }
-#endif
-
-    };
-
-    // this application actually works in SDL and WASM
-    class RtViewerDemoBaseApplicationSingleCanvas : public RtViewerDemoBaseApplication
-    {
-public:
-
-#if ORTHANC_ENABLE_QT==1
-      virtual QStoneMainWindow* CreateQtMainWindow() {
-        return new SampleMainWindow(dynamic_cast<OrthancStone::NativeStoneApplicationContext&>(*context_), *this);
-      }
-#endif
-    };
-  }
-}
-
-
-
-namespace OrthancStone
-{
-  namespace Samples
-  {
-    template <Orthanc::PixelFormat T>
-    void ReadDistributionInternal(std::vector<float>& distribution,
-                                  const Orthanc::ImageAccessor& image)
-    {
-      const unsigned int width = image.GetWidth();
-      const unsigned int height = image.GetHeight();
-      
-      distribution.resize(width * height);
-      size_t pos = 0;
-
-      for (unsigned int y = 0; y < height; y++)
-      {
-        for (unsigned int x = 0; x < width; x++, pos++)
-        {
-          distribution[pos] = Orthanc::ImageTraits<T>::GetFloatPixel(image, x, y);
-        }
-      }
-    }
-
-    void ReadDistribution(std::vector<float>& distribution,
-                          const Orthanc::ImageAccessor& image)
-    {
-      switch (image.GetFormat())
-      {
-        case Orthanc::PixelFormat_Grayscale8:
-          ReadDistributionInternal<Orthanc::PixelFormat_Grayscale8>(distribution, image);
-          break;
-
-        case Orthanc::PixelFormat_Grayscale16:
-          ReadDistributionInternal<Orthanc::PixelFormat_Grayscale16>(distribution, image);
-          break;
-
-        case Orthanc::PixelFormat_SignedGrayscale16:
-          ReadDistributionInternal<Orthanc::PixelFormat_SignedGrayscale16>(distribution, image);
-          break;
-
-        case Orthanc::PixelFormat_Grayscale32:
-          ReadDistributionInternal<Orthanc::PixelFormat_Grayscale32>(distribution, image);
-          break;
-
-        case Orthanc::PixelFormat_Grayscale64:
-          ReadDistributionInternal<Orthanc::PixelFormat_Grayscale64>(distribution, image);
-          break;
-
-        default:
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
-      }
-    }
-
-
-    class DoseInteractor : public VolumeImageInteractor
-    {
-    private:
-      SliceViewerWidget&         widget_;
-      size_t               layer_;
-      DicomFrameConverter  converter_;
-
-
-      
-    protected:
-      virtual void NotifySliceChange(const ISlicedVolume& slicedVolume,
-                                    const size_t& sliceIndex,
-                                    const Slice& slice)
-      {
-        converter_ = slice.GetConverter();
-        
-  #if 0
-        const OrthancVolumeImage& volume = dynamic_cast<const OrthancVolumeImage&>(slicedVolume);
-
-        RenderStyle s = widget_.GetLayerStyle(layer_);
-
-        if (volume.FitWindowingToRange(s, slice.GetConverter()))
-        {
-          printf("Windowing: %f => %f\n", s.customWindowCenter_, s.customWindowWidth_);
-          widget_.SetLayerStyle(layer_, s);
-        }
-  #endif
-      }
-
-      virtual void NotifyVolumeReady(const ISlicedVolume& slicedVolume)
-      {
-        const float percentile = 0.01f;
-        const OrthancVolumeImage& volume = dynamic_cast<const OrthancVolumeImage&>(slicedVolume);
-
-        std::vector<float> distribution;
-        ReadDistribution(distribution, volume.GetImage().GetInternalImage());
-        std::sort(distribution.begin(), distribution.end());
-
-        int start = static_cast<int>(std::ceil(distribution.size() * percentile));
-        int end = static_cast<int>(std::floor(distribution.size() * (1.0f - percentile)));
-
-        float a = 0;
-        float b = 0;
-        
-        if (start < end &&
-            start >= 0 &&
-            end < static_cast<int>(distribution.size()))
-        {
-          a = distribution[start];
-          b = distribution[end];
-        }
-        else if (!distribution.empty())
-        {
-          // Too small distribution: Use full range
-          a = distribution.front();
-          b = distribution.back();
-        }
-
-        //printf("%f %f\n", a, b);
-
-        RenderStyle s = widget_.GetLayerStyle(layer_);
-        s.windowing_ = ImageWindowing_Custom;
-        s.customWindowCenter_ = static_cast<float>(converter_.Apply((a + b) / 2.0f));
-        s.customWindowWidth_ = static_cast<float>(converter_.Apply(b - a));
-        
-        // 96.210556 => 192.421112
-        widget_.SetLayerStyle(layer_, s);
-        printf("Windowing: %f => %f\n", s.customWindowCenter_, s.customWindowWidth_);      
-      }
-
-    public:
-      DoseInteractor(MessageBroker& broker, OrthancVolumeImage& volume,
-                    SliceViewerWidget& widget,
-                    VolumeProjection projection,
-                    size_t layer) :
-        VolumeImageInteractor(broker, volume, widget, projection),
-        widget_(widget),
-        layer_(layer)
-      {
-      }
-    };
-
-    class RtViewerDemoApplication :
-      public RtViewerDemoBaseApplicationSingleCanvas,
-      public IObserver
-    {
-    public:
-      std::vector<std::pair<SliceViewerWidget*, size_t> > doseCtWidgetLayerPairs_;
-      std::list<OrthancStone::IWorldSceneInteractor*>    interactors_;
-
-      class Interactor : public IWorldSceneInteractor
-      {
-      private:
-        RtViewerDemoApplication&  application_;
-
-      public:
-        Interactor(RtViewerDemoApplication&  application) :
-          application_(application)
-        {
-        }
-
-        virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget,
-          const ViewportGeometry& view,
-          MouseButton button,
-          KeyboardModifiers modifiers,
-          int viewportX,
-          int viewportY,
-          double x,
-          double y,
-          IStatusBar* statusBar,
-          const std::vector<Touch>& displayTouches)
-        {
-          return NULL;
-        }
-
-        virtual void MouseOver(CairoContext& context,
-          WorldSceneWidget& widget,
-          const ViewportGeometry& view,
-          double x,
-          double y,
-          IStatusBar* statusBar)
-        {
-          if (statusBar != NULL)
-          {
-            Vector p = dynamic_cast<SliceViewerWidget&>(widget).GetSlice().MapSliceToWorldCoordinates(x, y);
-
-            char buf[64];
-            sprintf(buf, "X = %.02f Y = %.02f Z = %.02f (in cm)",
-              p[0] / 10.0, p[1] / 10.0, p[2] / 10.0);
-            statusBar->SetMessage(buf);
-          }
-        }
-
-        virtual void MouseWheel(WorldSceneWidget& widget,
-          MouseWheelDirection direction,
-          KeyboardModifiers modifiers,
-          IStatusBar* statusBar)
-        {
-          int scale = (modifiers & KeyboardModifiers_Control ? 10 : 1);
-
-          switch (direction)
-          {
-          case MouseWheelDirection_Up:
-            application_.OffsetSlice(-scale);
-            break;
-
-          case MouseWheelDirection_Down:
-            application_.OffsetSlice(scale);
-            break;
-
-          default:
-            break;
-          }
-        }
-
-        virtual void KeyPressed(WorldSceneWidget& widget,
-          KeyboardKeys key,
-          char keyChar,
-          KeyboardModifiers modifiers,
-          IStatusBar* statusBar)
-        {
-          switch (keyChar)
-          {
-          case 's':
-            // TODO: recursively traverse children
-            widget.FitContent();
-            break;
-
-          default:
-            break;
-          }
-        }
-      };
-
-      void OffsetSlice(int offset)
-      {
-        if (source_ != NULL)
-        {
-          int slice = static_cast<int>(slice_) + offset;
-
-          if (slice < 0)
-          {
-            slice = 0;
-          }
-
-          if (slice >= static_cast<int>(source_->GetSliceCount()))
-          {
-            slice = static_cast<int>(source_->GetSliceCount()) - 1;
-          }
-
-          if (slice != static_cast<int>(slice_))
-          {
-            SetSlice(slice);
-          }
-        }
-      }
-
-
-      SliceViewerWidget& GetMainWidget()
-      {
-        return *dynamic_cast<SliceViewerWidget*>(mainWidget_);
-      }
-
-
-      void SetSlice(size_t index)
-      {
-        if (source_ != NULL &&
-          index < source_->GetSliceCount())
-        {
-          slice_ = static_cast<unsigned int>(index);
-
-#if 1
-          GetMainWidget().SetSlice(source_->GetSlice(slice_).GetGeometry());
-#else
-          // TEST for scene extents - Rotate the axes
-          double a = 15.0 / 180.0 * boost::math::constants::pi<double>();
-
-#if 1
-          Vector x; GeometryToolbox::AssignVector(x, cos(a), sin(a), 0);
-          Vector y; GeometryToolbox::AssignVector(y, -sin(a), cos(a), 0);
-#else
-          // Flip the normal
-          Vector x; GeometryToolbox::AssignVector(x, cos(a), sin(a), 0);
-          Vector y; GeometryToolbox::AssignVector(y, sin(a), -cos(a), 0);
-#endif
-
-          SliceGeometry s(source_->GetSlice(slice_).GetGeometry().GetOrigin(), x, y);
-          widget_->SetSlice(s);
-#endif
-        }
-      }
-
-
-      void OnMainWidgetGeometryReady(const IVolumeSlicer::GeometryReadyMessage& message)
-      {
-        // Once the geometry of the series is downloaded from Orthanc,
-        // display its middle slice, and adapt the viewport to fit this
-        // slice
-        if (source_ == &message.GetOrigin())
-        {
-          SetSlice(source_->GetSliceCount() / 2);
-        }
-
-        GetMainWidget().FitContent();
-      }
-
-    DicomFrameConverter                                converter_;
-
-    void OnSliceContentChangedMessage(const ISlicedVolume::SliceContentChangedMessage&   message)
-    {
-      converter_ = message.GetSlice().GetConverter();
-    }
-
-    void OnVolumeReadyMessage(const ISlicedVolume::VolumeReadyMessage& message)
-    {
-      const float percentile = 0.01f;
-
-      auto& slicedVolume = message.GetOrigin();
-      const OrthancVolumeImage& volume = dynamic_cast<const OrthancVolumeImage&>(slicedVolume);
-
-      std::vector<float> distribution;
-      ReadDistribution(distribution, volume.GetImage().GetInternalImage());
-      std::sort(distribution.begin(), distribution.end());
-
-      int start = static_cast<int>(std::ceil(distribution.size() * percentile));
-      int end = static_cast<int>(std::floor(distribution.size() * (1.0f - percentile)));
-
-      float a = 0;
-      float b = 0;
-
-      if (start < end &&
-        start >= 0 &&
-        end < static_cast<int>(distribution.size()))
-      {
-        a = distribution[start];
-        b = distribution[end];
-      }
-      else if (!distribution.empty())
-      {
-        // Too small distribution: Use full range
-        a = distribution.front();
-        b = distribution.back();
-      }
-
-      //printf("WINDOWING %f %f\n", a, b);
-
-      for (const auto& pair : doseCtWidgetLayerPairs_)
-      {
-        auto widget = pair.first;
-        auto layer = pair.second;
-        RenderStyle s = widget->GetLayerStyle(layer);
-        s.windowing_ = ImageWindowing_Custom;
-        s.customWindowCenter_ = static_cast<float>(converter_.Apply((a + b) / 2.0f));
-        s.customWindowWidth_ = static_cast<float>(converter_.Apply(b - a));
-
-        // 96.210556 => 192.421112
-        widget->SetLayerStyle(layer, s);
-        printf("Windowing: %f => %f\n", s.customWindowCenter_, s.customWindowWidth_);
-      }
-    }
-      
-
-
-      size_t AddDoseLayer(SliceViewerWidget& widget,
-        OrthancVolumeImage& volume, VolumeProjection projection);
-
-      void AddStructLayer(
-        SliceViewerWidget& widget, StructureSetLoader& loader);
-
-      SliceViewerWidget* CreateDoseCtWidget(
-        std::unique_ptr<OrthancVolumeImage>& ct,
-        std::unique_ptr<OrthancVolumeImage>& dose,
-        std::unique_ptr<StructureSetLoader>& structLoader,
-        VolumeProjection projection);
-
-      void AddCtLayer(SliceViewerWidget& widget, OrthancVolumeImage& volume);
-
-      std::unique_ptr<Interactor>         mainWidgetInteractor_;
-      const DicomSeriesVolumeSlicer*    source_;
-      unsigned int                      slice_;
-
-      std::string                                        ctSeries_;
-      std::string                                        doseInstance_;
-      std::string                                        doseSeries_;
-      std::string                                        structInstance_;
-      std::unique_ptr<OrthancStone::OrthancVolumeImage>    dose_;
-      std::unique_ptr<OrthancStone::OrthancVolumeImage>    ct_;
-      std::unique_ptr<OrthancStone::StructureSetLoader>    struct_;
-
-    public:
-      RtViewerDemoApplication(MessageBroker& broker) :
-        IObserver(broker),
-        source_(NULL),
-        slice_(0)
-      {
-      }
-
-      /*
-      dev options on bgo xps15
-
-      COMMAND LINE
-      --ct-series=a04ecf01-79b2fc33-58239f7e-ad9db983-28e81afa --dose-instance=830a69ff-8e4b5ee3-b7f966c8-bccc20fb-d322dceb --struct-instance=54460695-ba3885ee-ddf61ac0-f028e31d-a6e474d9
-
-      URL PARAMETERS
-      ?ct-series=a04ecf01-79b2fc33-58239f7e-ad9db983-28e81afa&dose-instance=830a69ff-8e4b5ee3-b7f966c8-bccc20fb-d322dceb&struct-instance=54460695-ba3885ee-ddf61ac0-f028e31d-a6e474d9
-
-      */
-
-      void ParseParameters(const boost::program_options::variables_map&  parameters)
-      {
-        // Generic
-        {
-          if (parameters.count("verbose"))
-          {
-            Orthanc::Logging::EnableInfoLevel(true);
-            LOG(INFO) << "Verbose logs (info) are enabled";
-          }
-        }
-
-        {
-          if (parameters.count("trace"))
-          {
-            LOG(INFO) << "parameters.count(\"trace\") != 0";
-            Orthanc::Logging::EnableTraceLevel(true);
-            VLOG(1) << "Trace logs (debug) are enabled";
-          }
-        }
-
-        // CT series
-        {
-
-          if (parameters.count("ct-series") != 1)
-          {
-            LOG(ERROR) << "There must be exactly one CT series specified";
-            throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-          }
-          ctSeries_ = parameters["ct-series"].as<std::string>();
-        }
-
-        // RTDOSE 
-        {
-          if (parameters.count("dose-instance") == 1)
-          {
-            doseInstance_ = parameters["dose-instance"].as<std::string>();
-          }
-          else
-          {
-#ifdef BGO_NOT_IMPLEMENTED_YET
-            // Dose series
-            if (parameters.count("dose-series") != 1)
-            {
-              LOG(ERROR) << "the RTDOSE series is missing";
-              throw Orthanc::OrthancException(
-                Orthanc::ErrorCode_ParameterOutOfRange);
-            }
-            doseSeries_ = parameters["ct"].as<std::string>();
-#endif
-            LOG(ERROR) << "the RTSTRUCT instance is missing";
-            throw Orthanc::OrthancException(
-              Orthanc::ErrorCode_ParameterOutOfRange);
-          }
-        }
-        
-        // RTSTRUCT 
-        {
-          if (parameters.count("struct-instance") == 1)
-          {
-            structInstance_ = parameters["struct-instance"].as<std::string>();
-          }
-          else
-          {
-#ifdef BGO_NOT_IMPLEMENTED_YET
-            // Struct series
-            if (parameters.count("struct-series") != 1)
-            {
-              LOG(ERROR) << "the RTSTRUCT series is missing";
-              throw Orthanc::OrthancException(
-                Orthanc::ErrorCode_ParameterOutOfRange);
-            }
-            structSeries_ = parameters["struct-series"].as<std::string>();
-#endif
-            LOG(ERROR) << "the RTSTRUCT instance is missing";
-            throw Orthanc::OrthancException(
-              Orthanc::ErrorCode_ParameterOutOfRange);
-          }
-        }
-      }
-
-      virtual void DeclareStartupOptions(
-        boost::program_options::options_description& options)
-      {
-        boost::program_options::options_description generic(
-          "RtViewerDemo options. Please note that some of these options "
-          "are mutually exclusive");
-        generic.add_options()
-          ("ct-series", boost::program_options::value<std::string>(),
-            "Orthanc ID of the CT series")
-          ("dose-instance", boost::program_options::value<std::string>(), 
-            "Orthanc ID of the RTDOSE instance (incompatible with dose-series)")
-          ("dose-series", boost::program_options::value<std::string>(), 
-            "NOT IMPLEMENTED YET. Orthanc ID of the RTDOSE series (incompatible"
-            " with dose-instance)")
-          ("struct-instance", boost::program_options::value<std::string>(), 
-            "Orthanc ID of the RTSTRUCT instance (incompatible with struct-"
-            "series)")
-          ("struct-series", boost::program_options::value<std::string>(), 
-            "NOT IMPLEMENTED YET. Orthanc ID of the RTSTRUCT (incompatible with"
-            " struct-instance)")
-          ("smooth", boost::program_options::value<bool>()->default_value(true),
-            "Enable bilinear image smoothing")
-          ;
-
-        options.add(generic);
-      }
-
-      virtual void Initialize(
-        StoneApplicationContext*                      context,
-        IStatusBar&                                   statusBar,
-        const boost::program_options::variables_map&  parameters)
-      {
-        using namespace OrthancStone;
-
-        ParseParameters(parameters);
-
-        context_ = context;
-
-        statusBar.SetMessage("Use the key \"s\" to reinitialize the layout");
-
-        if (!ctSeries_.empty())
-        {
-          printf("CT = [%s]\n", ctSeries_.c_str());
-
-          ct_.reset(new OrthancStone::OrthancVolumeImage(
-            IObserver::GetBroker(), context->GetOrthancApiClient(), false));
-          ct_->ScheduleLoadSeries(ctSeries_);
-          //ct_->ScheduleLoadSeries(
-          //  "a04ecf01-79b2fc33-58239f7e-ad9db983-28e81afa");
-          //ct_->ScheduleLoadSeries(
-          //  "03677739-1d8bca40-db1daf59-d74ff548-7f6fc9c0");
-        }
-
-        if (!doseSeries_.empty() ||
-          !doseInstance_.empty())
-        {
-          dose_.reset(new OrthancStone::OrthancVolumeImage(
-            IObserver::GetBroker(), context->GetOrthancApiClient(), true));
-
-
-          dose_->RegisterObserverCallback(
-            new Callable<RtViewerDemoApplication, ISlicedVolume::VolumeReadyMessage>
-            (*this, &RtViewerDemoApplication::OnVolumeReadyMessage));
-
-          dose_->RegisterObserverCallback(
-            new Callable<RtViewerDemoApplication, ISlicedVolume::SliceContentChangedMessage>
-            (*this, &RtViewerDemoApplication::OnSliceContentChangedMessage));
-
-          if (doseInstance_.empty())
-          {
-            dose_->ScheduleLoadSeries(doseSeries_);
-          }
-          else
-          {
-            dose_->ScheduleLoadInstance(doseInstance_);
-          }
-
-          //dose_->ScheduleLoadInstance(
-            //"830a69ff-8e4b5ee3-b7f966c8-bccc20fb-d322dceb");  // 1
-          //dose_->ScheduleLoadInstance(
-            //"269f26f4-0c83eeeb-2e67abbd-5467a40f-f1bec90c"); //0522c0001 TCIA
-        }
-
-        if (!structInstance_.empty())
-        {
-          struct_.reset(new OrthancStone::StructureSetLoader(
-            IObserver::GetBroker(), context->GetOrthancApiClient()));
-
-          struct_->ScheduleLoadInstance(structInstance_);
-
-          //struct_->ScheduleLoadInstance(
-            //"54460695-ba3885ee-ddf61ac0-f028e31d-a6e474d9");
-          //struct_->ScheduleLoadInstance(
-            //"17cd032b-ad92a438-ca05f06a-f9e96668-7e3e9e20"); // 0522c0001 TCIA
-        }
-
-        mainWidget_ = new LayoutWidget("main-layout");
-        mainWidget_->SetBackgroundColor(0, 0, 0);
-        mainWidget_->SetBackgroundCleared(true);
-        mainWidget_->SetPadding(0);
-
-        auto axialWidget = CreateDoseCtWidget
-        (ct_, dose_, struct_, OrthancStone::VolumeProjection_Axial);
-        mainWidget_->AddWidget(axialWidget);
-               
-        std::unique_ptr<OrthancStone::LayoutWidget> subLayout(
-          new OrthancStone::LayoutWidget("main-layout"));
-        subLayout->SetVertical();
-        subLayout->SetPadding(5);
-
-        auto coronalWidget = CreateDoseCtWidget
-        (ct_, dose_, struct_, OrthancStone::VolumeProjection_Coronal);
-        subLayout->AddWidget(coronalWidget);
-
-        auto sagittalWidget = CreateDoseCtWidget
-        (ct_, dose_, struct_, OrthancStone::VolumeProjection_Sagittal);
-        subLayout->AddWidget(sagittalWidget);
-        
-        mainWidget_->AddWidget(subLayout.release());
-      }
-    };
-
-
-    size_t RtViewerDemoApplication::AddDoseLayer(
-      SliceViewerWidget& widget,
-      OrthancVolumeImage& volume, VolumeProjection projection)
-    {
-      size_t layer = widget.AddLayer(
-        new VolumeImageMPRSlicer(IObserver::GetBroker(), volume));
-
-      RenderStyle s;
-      //s.drawGrid_ = true;
-      s.SetColor(255, 0, 0);  // Draw missing PET layer in red
-      s.alpha_ = 0.3f;
-      s.applyLut_ = true;
-      s.lut_ = Orthanc::EmbeddedResources::COLORMAP_JET;
-      s.interpolation_ = ImageInterpolation_Bilinear;
-      widget.SetLayerStyle(layer, s);
-
-      return layer;
-    }
-
-    void RtViewerDemoApplication::AddStructLayer(
-      SliceViewerWidget& widget, StructureSetLoader& loader)
-    {
-      widget.AddLayer(new DicomStructureSetSlicer(
-        IObserver::GetBroker(), loader));
-    }
-
-    SliceViewerWidget* RtViewerDemoApplication::CreateDoseCtWidget(
-      std::unique_ptr<OrthancVolumeImage>& ct,
-      std::unique_ptr<OrthancVolumeImage>& dose,
-      std::unique_ptr<StructureSetLoader>& structLoader,
-      VolumeProjection projection)
-    {
-      std::unique_ptr<OrthancStone::SliceViewerWidget> widget(
-        new OrthancStone::SliceViewerWidget(IObserver::GetBroker(),
-          "ct-dose-widget"));
-
-      if (ct.get() != NULL)
-      {
-        AddCtLayer(*widget, *ct);
-      }
-
-      if (dose.get() != NULL)
-      {
-        size_t layer = AddDoseLayer(*widget, *dose, projection);
-
-        // we need to store the dose rendering widget because we'll update them
-        // according to various asynchronous events
-        doseCtWidgetLayerPairs_.push_back(std::make_pair(widget.get(), layer));
-#if 0
-        interactors_.push_back(new VolumeImageInteractor(
-          IObserver::GetBroker(), *dose, *widget, projection));
-#else
-        interactors_.push_back(new DoseInteractor(
-          IObserver::GetBroker(), *dose, *widget, projection, layer));
-#endif
-      }
-      else if (ct.get() != NULL)
-      {
-        interactors_.push_back(
-          new VolumeImageInteractor(
-            IObserver::GetBroker(), *ct, *widget, projection));
-      }
-
-      if (structLoader.get() != NULL)
-      {
-        AddStructLayer(*widget, *structLoader);
-      }
-
-      return widget.release();
-    }
-
-    void RtViewerDemoApplication::AddCtLayer(
-      SliceViewerWidget& widget,
-      OrthancVolumeImage& volume)
-    {
-      size_t layer = widget.AddLayer(
-        new VolumeImageMPRSlicer(IObserver::GetBroker(), volume));
-
-      RenderStyle s;
-      //s.drawGrid_ = true;
-      s.alpha_ = 1;
-      s.windowing_ = ImageWindowing_Bone;
-      widget.SetLayerStyle(layer, s);
-    }
-  }
-}
-
-
-
-#if ORTHANC_ENABLE_WASM==1
-
-#include "Platforms/Wasm/WasmWebService.h"
-#include "Platforms/Wasm/WasmViewport.h"
-
-#include <emscripten/emscripten.h>
-
-//#include "SampleList.h"
-
-
-OrthancStone::IStoneApplication* CreateUserApplication(OrthancStone::MessageBroker& broker)
-{
-  return new OrthancStone::Samples::RtViewerDemoApplication(broker);
-}
-
-OrthancStone::WasmPlatformApplicationAdapter* CreateWasmApplicationAdapter(OrthancStone::MessageBroker& broker, OrthancStone::IStoneApplication* application)
-{
-  return dynamic_cast<OrthancStone::Samples::RtViewerDemoApplication*>(application)->CreateWasmApplicationAdapter(broker);
-}
-
-#else
-
-//#include "SampleList.h"
-#if ORTHANC_ENABLE_SDL==1
-#include "Applications/Sdl/SdlStoneApplicationRunner.h"
-#endif
-#if ORTHANC_ENABLE_QT==1
-#include "Applications/Qt/SampleQtApplicationRunner.h"
-#endif
-#include "Framework/Messages/MessageBroker.h"
-
-int main(int argc, char* argv[])
-{
-  OrthancStone::MessageBroker broker;
-  OrthancStone::Samples::RtViewerDemoApplication sampleStoneApplication(broker);
-
-#if ORTHANC_ENABLE_SDL==1
-  OrthancStone::SdlStoneApplicationRunner sdlApplicationRunner(broker, sampleStoneApplication);
-  return sdlApplicationRunner.Execute(argc, argv);
-#endif
-#if ORTHANC_ENABLE_QT==1
-  OrthancStone::Samples::SampleQtApplicationRunner qtAppRunner(broker, sampleStoneApplication);
-  return qtAppRunner.Execute(argc, argv);
-#endif
-}
-
-
-#endif
-
-
-
-
-
-
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/nginx.local.conf	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-# Local config to serve the WASM samples static files and reverse proxy Orthanc.
-# Uses port 9977 instead of 80.
-
-# `events` section is mandatory
-events {
-  worker_connections 1024; # Default: 1024
-}
-
-http {
-
-  # prevent nginx sync issues on OSX
-  proxy_buffering off;
-
-  server {
-    listen 9977 default_server;
-    client_max_body_size 4G;
-
-    # location may have to be adjusted depending on your OS and nginx install
-    include /etc/nginx/mime.types;
-    # if not in your system mime.types, add this line to support WASM:
-    # types {
-    #    application/wasm                      wasm; 
-    # }
-
-    # serve WASM static files
-    root build-web/;
-    location / {
-	}
-
-    # reverse proxy orthanc
-	location /orthanc/ {
-		rewrite /orthanc(.*) $1 break;
-		proxy_pass http://127.0.0.1:8042;
-		proxy_set_header Host $http_host;
-		proxy_set_header my-auth-header good-token;
-		proxy_request_buffering off;
-		proxy_max_temp_file_size 0;
-		client_max_body_size 0;
-	}
-
-
-  }
-  
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/rt-viewer-demo.html	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-<!doctype html>
-
-<html lang="us">
-  <head>
-    <meta charset="utf-8" />
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-
-    <!-- Disable pinch zoom on mobile devices -->
-    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
-    <meta name="HandheldFriendly" content="true" />
-
-    <title>Simple Viewer</title>
-    <link href="samples-styles.css" rel="stylesheet" />
-
-<body>
-  <div style="width: 100%; height: 5%">
-    <p>RTSTRUCT viewer demonstration</p>
-  </div>
-  <div style="width: 100%; height: 95%">
-    <canvas id="canvas"></canvas>
-  </div>
-  <script type="text/javascript" src="app-rt-viewer-demo.js"></script>
-</body>
-
-</html>
\ No newline at end of file
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/rt-viewer-demo.ts	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-import { InitializeWasmApplication } from '../../../Platforms/Wasm/wasm-application-runner';
-
-
-InitializeWasmApplication("RtViewerDemo", "/orthanc");
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/rt-viewer-demo.tsconfig.json	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-{
-    "extends" : "./tsconfig-samples",
-    "compilerOptions": {
-    },
-    "include" : [
-        "rt-viewer-demo.ts"
-    ]
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/samples-styles.css	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-html, body {
-  width: 100%;
-  height: 100%;
-  margin: 0px;
-  border: 0;
-  overflow: hidden; /*  Disable scrollbars */
-  display: block;  /* No floating content on sides */
-  background-color: black;
-  color: white;
-  font-family: Arial, Helvetica, sans-serif;
-}
-
-canvas {
-  left:0px;
-  top:0px;
-}
\ No newline at end of file
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/start-serving-files.sh	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,9 +0,0 @@
-#!/bin/bash
-
-sudo nginx -p $(pwd) -c nginx.local.conf
-
-echo "Please browse to :"
-
-echo "http://localhost:9977/rt-viewer-demo.html?ct-series=a04ecf01-79b2fc33-58239f7e-ad9db983-28e81afa&dose-instance=830a69ff-8e4b5ee3-b7f966c8-bccc20fb-d322dceb&struct-instance=54460695-ba3885ee-ddf61ac0-f028e31d-a6e474d9"
-
-echo "(This requires you have uploaded the correct files to your local Orthanc instance)"
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/stop-serving-files.sh	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-#!/bin/bash
-
-sudo nginx -s stop
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/rt-viewer-demo/tsconfig-samples.json	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-{
-    "extends" : "../../../Platforms/Wasm/tsconfig-stone.json",
-    "compilerOptions": {
-        "sourceMap": false,
-        "lib" : [
-            "es2017",
-            "dom",
-            "dom.iterable"
-        ]
-    }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Samples/Deprecated/tsconfig-stone.json	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-{
-    "include" : [
-        "../../Platforms/Wasm/stone-framework-loader.ts",
-        "../../Platforms/Wasm/wasm-application-runner.ts",
-        "../../Platforms/Wasm/wasm-viewport.ts"
-    ]
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Sdl/SdlCairoSurface.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "SdlCairoSurface.h"
-
-#if ORTHANC_ENABLE_SDL == 1
-
-#include <Core/Logging.h>
-#include <Core/OrthancException.h>
-
-namespace OrthancStone
-{
-  SdlCairoSurface::SdlCairoSurface(SdlWindow& window) :
-    window_(window),
-    sdlSurface_(NULL)
-  {
-  }
-
-
-  SdlCairoSurface::~SdlCairoSurface()
-  {
-    if (sdlSurface_)
-    {
-      SDL_FreeSurface(sdlSurface_);
-    }
-  }
-
-
-  void SdlCairoSurface::SetSize(unsigned int width,
-                                unsigned int height)
-  {
-    if (cairoSurface_.get() == NULL ||
-        cairoSurface_->GetWidth() != width ||
-        cairoSurface_->GetHeight() != height)
-    {
-      cairoSurface_.reset(new CairoSurface(width, height, false /* no alpha */));
-
-      // TODO Big endian?
-      static const uint32_t rmask = 0x00ff0000;
-      static const uint32_t gmask = 0x0000ff00;
-      static const uint32_t bmask = 0x000000ff;
-
-      if (sdlSurface_)
-      {
-        SDL_FreeSurface(sdlSurface_);
-      }
-
-      sdlSurface_ = SDL_CreateRGBSurfaceFrom(cairoSurface_->GetBuffer(), width, height, 32,
-                                             cairoSurface_->GetPitch(), rmask, gmask, bmask, 0);
-      if (!sdlSurface_)
-      {
-        LOG(ERROR) << "Cannot create a SDL surface from a Cairo surface";
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-      }
-    }
-  }
-
-
-  void SdlCairoSurface::Render(Deprecated::IViewport& viewport)
-  {
-    if (cairoSurface_.get() == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-
-    Orthanc::ImageAccessor target;
-    cairoSurface_->GetWriteableAccessor(target);
-
-    if (viewport.Render(target))
-    {
-      window_.Render(sdlSurface_);
-    }
-  }
-}
-
-#endif
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Sdl/SdlCairoSurface.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#if ORTHANC_ENABLE_SDL == 1
-
-#include "../../Framework/Viewport/SdlWindow.h"
-#include "../../Framework/Wrappers/CairoSurface.h"
-#include "../../Framework/Deprecated/Viewport/IViewport.h"
-
-#include <Core/Compatibility.h>
-
-#include <SDL_render.h>
-#include <boost/thread/mutex.hpp>
-
-namespace OrthancStone
-{
-  class SdlCairoSurface : public boost::noncopyable
-  {
-  private:
-    std::unique_ptr<CairoSurface>  cairoSurface_;
-    SdlWindow&                   window_;
-    SDL_Surface*                 sdlSurface_;
-
-  public:
-    SdlCairoSurface(SdlWindow& window);
-
-    ~SdlCairoSurface();
-
-    void SetSize(unsigned int width,
-                 unsigned int height);
-
-    void Render(Deprecated::IViewport& viewport);
-  };
-}
-
-#endif
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Sdl/SdlEngine.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,282 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "SdlEngine.h"
-
-#if ORTHANC_ENABLE_SDL == 1
-
-#include <Core/Logging.h>
-
-#include <SDL.h>
-
-namespace OrthancStone
-{
-  void SdlEngine::SetSize(unsigned int width,
-                          unsigned int height)
-  {
-    NativeStoneApplicationContext::GlobalMutexLocker locker(context_);
-    locker.GetCentralViewport().SetSize(width, height);
-    surface_.SetSize(width, height);
-  }
-
-
-  void SdlEngine::RenderFrame()
-  {
-    if (viewportChanged_)
-    {
-      NativeStoneApplicationContext::GlobalMutexLocker locker(context_);
-      surface_.Render(locker.GetCentralViewport());
-
-      viewportChanged_ = false;
-    }
-  }
-
-
-  KeyboardModifiers SdlEngine::GetKeyboardModifiers(const uint8_t* keyboardState,
-                                                    const int scancodeCount)
-  {
-    int result = KeyboardModifiers_None;
-
-    if (keyboardState != NULL)
-    {
-      if (SDL_SCANCODE_LSHIFT < scancodeCount &&
-          keyboardState[SDL_SCANCODE_LSHIFT])
-      {
-        result |= KeyboardModifiers_Shift;
-      }
-
-      if (SDL_SCANCODE_RSHIFT < scancodeCount &&
-          keyboardState[SDL_SCANCODE_RSHIFT])
-      {
-        result |= KeyboardModifiers_Shift;
-      }
-
-      if (SDL_SCANCODE_LCTRL < scancodeCount &&
-          keyboardState[SDL_SCANCODE_LCTRL])
-      {
-        result |= KeyboardModifiers_Control;
-      }
-
-      if (SDL_SCANCODE_RCTRL < scancodeCount &&
-          keyboardState[SDL_SCANCODE_RCTRL])
-      {
-        result |= KeyboardModifiers_Control;
-      }
-
-      if (SDL_SCANCODE_LALT < scancodeCount &&
-          keyboardState[SDL_SCANCODE_LALT])
-      {
-        result |= KeyboardModifiers_Alt;
-      }
-
-      if (SDL_SCANCODE_RALT < scancodeCount &&
-          keyboardState[SDL_SCANCODE_RALT])
-      {
-        result |= KeyboardModifiers_Alt;
-      }
-    }
-
-    return static_cast<KeyboardModifiers>(result);
-  }
-
-
-  SdlEngine::SdlEngine(SdlWindow& window,
-                       NativeStoneApplicationContext& context) :
-    window_(window),
-    context_(context),
-    surface_(window),
-    viewportChanged_(true)
-  {
-  }
-  
-
-  void SdlEngine::Run()
-  {
-    int scancodeCount = 0;
-    const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount);
-
-    SetSize(window_.GetWidth(), window_.GetHeight());
-    
-    {
-      NativeStoneApplicationContext::GlobalMutexLocker locker(context_);
-      locker.GetCentralViewport().FitContent();
-    }
-    
-    bool stop = false;
-    while (!stop)
-    {
-      RenderFrame();
-
-      SDL_Event event;
-
-      while (!stop &&
-             SDL_PollEvent(&event))
-      {
-        NativeStoneApplicationContext::GlobalMutexLocker locker(context_);
-
-        if (event.type == SDL_QUIT)
-        {
-          stop = true;
-          break;
-        }
-        else if (event.type == SDL_MOUSEBUTTONDOWN)
-        {
-          KeyboardModifiers modifiers = GetKeyboardModifiers(keyboardState, scancodeCount);
-
-          switch (event.button.button)
-          {
-          case SDL_BUTTON_LEFT:
-            locker.GetCentralViewport().MouseDown(MouseButton_Left, event.button.x, event.button.y, modifiers, std::vector<Deprecated::Touch>());
-            break;
-            
-          case SDL_BUTTON_RIGHT:
-            locker.GetCentralViewport().MouseDown(MouseButton_Right, event.button.x, event.button.y, modifiers, std::vector<Deprecated::Touch>());
-            break;
-            
-          case SDL_BUTTON_MIDDLE:
-            locker.GetCentralViewport().MouseDown(MouseButton_Middle, event.button.x, event.button.y, modifiers, std::vector<Deprecated::Touch>());
-            break;
-
-          default:
-            break;
-          }
-        }
-        else if (event.type == SDL_MOUSEMOTION)
-        {
-          locker.GetCentralViewport().MouseMove(event.button.x, event.button.y, std::vector<Deprecated::Touch>());
-        }
-        else if (event.type == SDL_MOUSEBUTTONUP)
-        {
-          locker.GetCentralViewport().MouseUp();
-        }
-        else if (event.type == SDL_WINDOWEVENT)
-        {
-          switch (event.window.event)
-          {
-          case SDL_WINDOWEVENT_LEAVE:
-            locker.GetCentralViewport().MouseLeave();
-            break;
-
-          case SDL_WINDOWEVENT_ENTER:
-            locker.GetCentralViewport().MouseEnter();
-            break;
-
-          case SDL_WINDOWEVENT_SIZE_CHANGED:
-            SetSize(event.window.data1, event.window.data2);
-            break;
-
-          default:
-            break;
-          }
-        }
-        else if (event.type == SDL_MOUSEWHEEL)
-        {
-          KeyboardModifiers modifiers = GetKeyboardModifiers(keyboardState, scancodeCount);
-
-          int x, y;
-          SDL_GetMouseState(&x, &y);
-
-          if (event.wheel.y > 0)
-          {
-            locker.GetCentralViewport().MouseWheel(MouseWheelDirection_Up, x, y, modifiers);
-          }
-          else if (event.wheel.y < 0)
-          {
-            locker.GetCentralViewport().MouseWheel(MouseWheelDirection_Down, x, y, modifiers);
-          }
-        }
-        else if (event.type == SDL_KEYDOWN &&
-                 event.key.repeat == 0 /* Ignore key bounce */)
-        {
-          KeyboardModifiers modifiers = GetKeyboardModifiers(keyboardState, scancodeCount);
-
-          switch (event.key.keysym.sym)
-          {
-          case SDLK_a:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 'a', modifiers);  break;
-          case SDLK_b:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 'b', modifiers);  break;
-          case SDLK_c:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 'c', modifiers);  break;
-          case SDLK_d:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 'd', modifiers);  break;
-          case SDLK_e:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 'e', modifiers);  break;
-          case SDLK_f:    window_.ToggleMaximize();                         break;
-          case SDLK_g:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 'g', modifiers);  break;
-          case SDLK_h:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 'h', modifiers);  break;
-          case SDLK_i:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 'i', modifiers);  break;
-          case SDLK_j:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 'j', modifiers);  break;
-          case SDLK_k:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 'k', modifiers);  break;
-          case SDLK_l:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 'l', modifiers);  break;
-          case SDLK_m:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 'm', modifiers);  break;
-          case SDLK_n:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 'n', modifiers);  break;
-          case SDLK_o:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 'o', modifiers);  break;
-          case SDLK_p:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 'p', modifiers);  break;
-          case SDLK_q:    stop = true;                                      break;
-          case SDLK_r:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 'r', modifiers);  break;
-          case SDLK_s:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 's', modifiers);  break;
-          case SDLK_t:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 't', modifiers);  break;
-          case SDLK_u:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 'u', modifiers);  break;
-          case SDLK_v:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 'v', modifiers);  break;
-          case SDLK_w:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 'w', modifiers);  break;
-          case SDLK_x:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 'x', modifiers);  break;
-          case SDLK_y:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 'y', modifiers);  break;
-          case SDLK_z:    locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, 'z', modifiers);  break;
-          case SDLK_KP_0: locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, '0', modifiers);  break;
-          case SDLK_KP_1: locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, '1', modifiers);  break;
-          case SDLK_KP_2: locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, '2', modifiers);  break;
-          case SDLK_KP_3: locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, '3', modifiers);  break;
-          case SDLK_KP_4: locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, '4', modifiers);  break;
-          case SDLK_KP_5: locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, '5', modifiers);  break;
-          case SDLK_KP_6: locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, '6', modifiers);  break;
-          case SDLK_KP_7: locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, '7', modifiers);  break;
-          case SDLK_KP_8: locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, '8', modifiers);  break;
-          case SDLK_KP_9: locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, '9', modifiers);  break;
-
-          case SDLK_PLUS:
-          case SDLK_KP_PLUS:
-            locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, '+', modifiers);  break;
-
-          case SDLK_MINUS:
-          case SDLK_KP_MINUS:
-            locker.GetCentralViewport().KeyPressed(KeyboardKeys_Generic, '-', modifiers);  break;
-
-          case SDLK_DELETE:
-            locker.GetCentralViewport().KeyPressed(KeyboardKeys_Delete, 0, modifiers);  break;
-          case SDLK_BACKSPACE:
-            locker.GetCentralViewport().KeyPressed(KeyboardKeys_Backspace, 0, modifiers);  break;
-          case SDLK_RIGHT:
-            locker.GetCentralViewport().KeyPressed(KeyboardKeys_Right, 0, modifiers);  break;
-          case SDLK_LEFT:
-            locker.GetCentralViewport().KeyPressed(KeyboardKeys_Left, 0, modifiers);  break;
-          case SDLK_UP:
-            locker.GetCentralViewport().KeyPressed(KeyboardKeys_Up, 0, modifiers);  break;
-          case SDLK_DOWN:
-            locker.GetCentralViewport().KeyPressed(KeyboardKeys_Down, 0, modifiers);  break;
-          default:
-            break;
-          }
-        }
-      }
-
-      // Small delay to avoid using 100% of CPU
-      SDL_Delay(1);
-    }
-  }
-}
-
-#endif
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Sdl/SdlEngine.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#if ORTHANC_ENABLE_SDL == 1
-
-#include "../../Framework/Messages/ObserverBase.h"
-#include "../Generic/NativeStoneApplicationContext.h"
-#include "SdlCairoSurface.h"
-
-namespace OrthancStone
-{
-  class SdlEngine : public ObserverBase<SdlEngine>
-  {
-  private:
-    SdlWindow&                window_;
-    NativeStoneApplicationContext&  context_;
-    SdlCairoSurface           surface_;
-    bool                      viewportChanged_;
-
-    void SetSize(unsigned int width,
-                 unsigned int height);
-    
-    void RenderFrame();
-
-    static KeyboardModifiers GetKeyboardModifiers(const uint8_t* keyboardState,
-                                                  const int scancodeCount);
-
-  public:
-    SdlEngine(SdlWindow& window,
-              NativeStoneApplicationContext& context);
-  
-    void OnViewportChanged(const Deprecated::IViewport::ViewportChangedMessage& message)
-    {
-      viewportChanged_ = true;
-    }
-
-    void Run();
-  };
-}
-
-#endif
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Sdl/SdlOrthancSurface.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "SdlOrthancSurface.h"
-
-#if ORTHANC_ENABLE_SDL == 1
-
-#include <Core/Logging.h>
-#include <Core/OrthancException.h>
-#include <Core/Images/Image.h>
-
-#include <SDL_render.h>
-
-namespace OrthancStone
-{
-  SdlOrthancSurface::SdlOrthancSurface(SdlWindow& window) :
-    window_(window),
-    sdlSurface_(NULL)
-  {
-  }
-
-
-  SdlOrthancSurface::~SdlOrthancSurface()
-  {
-    if (sdlSurface_)
-    {
-      SDL_FreeSurface(sdlSurface_);
-    }
-  }
-
-
-  void SdlOrthancSurface::SetSize(unsigned int width,
-                                  unsigned int height)
-  {
-    if (image_.get() == NULL ||
-        image_->GetWidth() != width ||
-        image_->GetHeight() != height)
-    {
-      image_.reset(new Orthanc::Image(Orthanc::PixelFormat_BGRA32, width, height, true));  // (*)
-
-      if (image_->GetPitch() != image_->GetWidth() * 4)
-      {
-        // This should have been ensured by setting "forceMinimalPitch" to "true" (*)
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-      }
-
-      // TODO Big endian?
-      static const uint32_t rmask = 0x00ff0000;
-      static const uint32_t gmask = 0x0000ff00;
-      static const uint32_t bmask = 0x000000ff;
-
-      if (sdlSurface_)
-      {
-        SDL_FreeSurface(sdlSurface_);
-      }
-
-      sdlSurface_ = SDL_CreateRGBSurfaceFrom(image_->GetBuffer(), width, height, 32,
-                                             image_->GetPitch(), rmask, gmask, bmask, 0);
-      if (!sdlSurface_)
-      {
-        LOG(ERROR) << "Cannot create a SDL surface from a Orthanc surface";
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-      }
-    }
-  }
-
-
-  Orthanc::ImageAccessor& SdlOrthancSurface::GetImage()
-  {
-    if (image_.get() == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-
-    return *image_;
-  }
-
-
-  void SdlOrthancSurface::Render()
-  {
-    if (image_.get() == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-
-    window_.Render(sdlSurface_);
-  }
-}
-
-#endif
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Sdl/SdlOrthancSurface.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#if ORTHANC_ENABLE_SDL == 1
-
-#include "../../Framework/Viewport/SdlWindow.h"
-
-#include <Core/Compatibility.h>
-#include <Core/Images/ImageAccessor.h>
-
-#include <boost/thread/mutex.hpp>
-
-namespace OrthancStone
-{
-  class SdlOrthancSurface : public boost::noncopyable
-  {
-  private:
-    std::unique_ptr<Orthanc::ImageAccessor>  image_;
-    SdlWindow&                             window_;
-    SDL_Surface*                           sdlSurface_;
-
-  public:
-    SdlOrthancSurface(SdlWindow& window);
-
-    ~SdlOrthancSurface();
-
-    void SetSize(unsigned int width,
-                 unsigned int height);
-
-    Orthanc::ImageAccessor& GetImage();
-
-    void Render();
-  };
-}
-
-#endif
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Sdl/SdlStoneApplicationRunner.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,138 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#if ORTHANC_ENABLE_SDL != 1
-#error this file shall be included only with the ORTHANC_ENABLE_SDL set to 1
-#endif
-
-#include "SdlStoneApplicationRunner.h"
-
-#include "../../Platforms/Generic/OracleWebService.h"
-#include "SdlEngine.h"
-
-#include <Core/Logging.h>
-#include <Core/HttpClient.h>
-#include <Core/Toolbox.h>
-#include <Core/OrthancException.h>
-#include <Plugins/Samples/Common/OrthancHttpConnection.h>
-
-#include <boost/program_options.hpp>
-
-namespace OrthancStone
-{
-  void SdlStoneApplicationRunner::Initialize()
-  {
-    SdlWindow::GlobalInitialize();
-  }
-
-  
-  void SdlStoneApplicationRunner::DeclareCommandLineOptions(boost::program_options::options_description& options)
-  {
-    boost::program_options::options_description sdl("SDL options");
-    sdl.add_options()
-        ("width", boost::program_options::value<int>()->default_value(1024), "Initial width of the SDL window")
-        ("height", boost::program_options::value<int>()->default_value(768), "Initial height of the SDL window")
-        ("opengl", boost::program_options::value<bool>()->default_value(true), "Enable OpenGL in SDL")
-        ;
-
-    options.add(sdl);
-  }
-
-  
-  void SdlStoneApplicationRunner::ParseCommandLineOptions(const boost::program_options::variables_map& parameters)
-  {
-    if (!parameters.count("width") ||
-        !parameters.count("height") ||
-        !parameters.count("opengl"))
-    {
-      LOG(ERROR) << "Parameter \"width\", \"height\" or \"opengl\" is missing";
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    int w = parameters["width"].as<int>();
-    int h = parameters["height"].as<int>();
-    if (w <= 0 || h <= 0)
-    {
-      LOG(ERROR) << "Parameters \"width\" and \"height\" must be positive";
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    width_ = static_cast<unsigned int>(w);
-    height_ = static_cast<unsigned int>(h);
-    LOG(WARNING) << "Initial display size: " << width_ << "x" << height_;
-
-    enableOpenGl_ = parameters["opengl"].as<bool>();
-    if (enableOpenGl_)
-    {
-      LOG(WARNING) << "OpenGL is enabled, disable it with option \"--opengl=off\" if the application crashes";
-    }
-    else
-    {
-      LOG(WARNING) << "OpenGL is disabled, enable it with option \"--opengl=on\" for best performance";
-    }
-  }
-
-  
-  void SdlStoneApplicationRunner::Run(NativeStoneApplicationContext& context,
-                                      const std::string& title,
-                                      int argc,
-                                      char* argv[])
-  {
-    /**************************************************************
-     * Run the application inside a SDL window
-     **************************************************************/
-
-    LOG(WARNING) << "Starting the application";
-
-    SdlWindow window(title.c_str(), width_, height_, enableOpenGl_);
-    boost::shared_ptr<SdlEngine> sdl(new SdlEngine(window, context));
-
-    {
-      NativeStoneApplicationContext::GlobalMutexLocker locker(context);
-
-      sdl->Register<Deprecated::IViewport::ViewportChangedMessage>
-        (locker.GetCentralViewport(), &SdlEngine::OnViewportChanged);
-
-      //context.GetCentralViewport().Register(sdl);  // (*)
-    }
-
-    context.Start();
-    sdl->Run();
-
-    LOG(WARNING) << "Stopping the application";
-
-    // Don't move the "Stop()" command below out of the block,
-    // otherwise the application might crash, because the
-    // "SdlEngine" is an observer of the viewport (*) and the
-    // update thread started by "context.Start()" would call a
-    // destructed object (the "SdlEngine" is deleted with the
-    // lexical scope).
-
-    // TODO Is this still true with message broker?
-    context.Stop();
-  }
-
-  
-  void SdlStoneApplicationRunner::Finalize()
-  {
-    SdlWindow::GlobalFinalize();
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Sdl/SdlStoneApplicationRunner.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../Generic/NativeStoneApplicationRunner.h"
-
-#if ORTHANC_ENABLE_SDL != 1
-#error this file shall be included only with the ORTHANC_ENABLE_SDL set to 1
-#endif
-
-#include <SDL.h>   // Necessary to avoid undefined reference to `SDL_main'
-
-namespace OrthancStone
-{
-  class SdlStoneApplicationRunner : public NativeStoneApplicationRunner
-  {
-  private:
-    unsigned int  width_;
-    unsigned int  height_;
-    bool          enableOpenGl_;
-    
-  public:
-    SdlStoneApplicationRunner(boost::shared_ptr<IStoneApplication> application) :
-      NativeStoneApplicationRunner(application)
-    {
-    }
-
-    virtual void Initialize();
-    
-    virtual void DeclareCommandLineOptions(boost::program_options::options_description& options);
-    
-    virtual void Run(NativeStoneApplicationContext& context,
-                     const std::string& title,
-                     int argc,
-                     char* argv[]);
-    
-    virtual void ParseCommandLineOptions(const boost::program_options::variables_map& parameters);
-    
-    virtual void Finalize();
-  };
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/StoneApplicationContext.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "StoneApplicationContext.h"
-
-#include <Core/OrthancException.h>
-
-namespace OrthancStone
-{
-  void StoneApplicationContext::InitializeOrthanc()
-  {
-    if (webService_ == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-
-    orthanc_.reset(new Deprecated::OrthancApiClient(*webService_, orthancBaseUrl_));
-  }
-
-
-  boost::shared_ptr<Deprecated::IWebService> StoneApplicationContext::GetWebService()
-  {
-    if (webService_ == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-    
-    return webService_;
-  }
-
-  
-  boost::shared_ptr<Deprecated::OrthancApiClient> StoneApplicationContext::GetOrthancApiClient()
-  {
-    if (orthanc_.get() == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-    
-    return orthanc_;
-  }
-
-  
-  void StoneApplicationContext::SetWebService(boost::shared_ptr<Deprecated::IWebService> webService)
-  {
-    webService_ = webService;
-    InitializeOrthanc();
-  }
-
-
-  void StoneApplicationContext::SetOrthancBaseUrl(const std::string& baseUrl)
-  {
-    // Make sure the base url ends with "/"
-    if (baseUrl.empty() ||
-        baseUrl[baseUrl.size() - 1] != '/')
-    {
-      orthancBaseUrl_ = baseUrl + "/";
-    }
-    else
-    {
-      orthancBaseUrl_ = baseUrl;
-    }
-
-    if (webService_ != NULL)
-    {
-      InitializeOrthanc();
-    }
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/StoneApplicationContext.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../Framework/Deprecated/Toolbox/IWebService.h"
-#include "../Framework/Deprecated/Toolbox/IDelayedCallExecutor.h"
-#include "../Framework/Deprecated/Toolbox/OrthancApiClient.h"
-#include "../Framework/Deprecated/Viewport/WidgetViewport.h"
-
-
-#ifdef _MSC_VER
-  #if _MSC_VER > 1910
-    #define orthanc_override override
-  #else
-    #define orthanc_override
-  #endif
-#elif defined __GNUC__
-  #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
-/* Test for GCC > 3.2.0 */
-  #if GCC_VERSION > 40900
-    #define orthanc_override override
-  #else
-    #define orthanc_override
-  #endif
-#else
-    #define orthanc_override
-#endif
-
-#include <list>
-
-namespace OrthancStone
-{
-  // a StoneApplicationContext contains the services that a StoneApplication
-  // uses and that depends on the environment in which the Application executes.
-  // I.e, the StoneApplicationContext provides a WebService interface such that
-  // the StoneApplication can perform HTTP requests.  In a WASM environment,
-  // the WebService is provided by the browser while, in a native environment,
-  // the WebService is provided by the OracleWebService (a C++ Http client)
-
-  class StoneApplicationContext : public boost::noncopyable
-  {
-  private:
-    boost::shared_ptr<Deprecated::IWebService>     webService_;
-    Deprecated::IDelayedCallExecutor*  delayedCallExecutor_;   // TODO => shared_ptr ??
-    boost::shared_ptr<Deprecated::OrthancApiClient>  orthanc_;
-    std::string                      orthancBaseUrl_;
-
-    void InitializeOrthanc();
-
-  public:
-    StoneApplicationContext() :
-      delayedCallExecutor_(NULL)
-    {
-    }
-
-    virtual ~StoneApplicationContext()
-    {
-    }
-
-    boost::shared_ptr<Deprecated::IWebService> GetWebService();
-
-    boost::shared_ptr<Deprecated::OrthancApiClient> GetOrthancApiClient();
-
-    void SetWebService(boost::shared_ptr<Deprecated::IWebService> webService);
-
-    void SetOrthancBaseUrl(const std::string& baseUrl);
-
-    void SetDelayedCallExecutor(Deprecated::IDelayedCallExecutor& delayedCallExecutor)
-    {
-      delayedCallExecutor_ = &delayedCallExecutor;
-    }
-
-    Deprecated::IDelayedCallExecutor& GetDelayedCallExecutor()
-    {
-      return *delayedCallExecutor_;
-    }
-  };
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Wasm/StartupParametersBuilder.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "StartupParametersBuilder.h"
-#include <iostream>
-#include <cstdio>
-#include "emscripten/html5.h"
-
-namespace OrthancStone
-{
-  void StartupParametersBuilder::Clear()
-  {
-    startupParameters_.clear();
-  }
-
-  void StartupParametersBuilder::SetStartupParameter(
-    const char* name,
-    const char* value)
-  {
-    startupParameters_.push_back(std::make_tuple(name, value));
-  }
-
-  void StartupParametersBuilder::GetStartupParameters(
-    boost::program_options::variables_map& parameters,
-    const boost::program_options::options_description& options) 
-  {
-    std::vector<std::string> argvStrings(startupParameters_.size() + 1);
-    // argv mirrors pointers to the internal argvStrings buffers.
-    // ******************************************************
-    // THIS IS HIGHLY DANGEROUS SO BEWARE!!!!!!!!!!!!!!
-    // ******************************************************
-    std::vector<const char*> argv(startupParameters_.size() + 1);
-    
-    int argCounter = 0;
-    argvStrings[argCounter] = "dummy.exe";
-    argv[argCounter] = argvStrings[argCounter].c_str();
-    
-    argCounter++;
-    
-    std::string cmdLine = "";
-    for ( StartupParameters::const_iterator it = startupParameters_.begin(); 
-          it != startupParameters_.end(); 
-          it++)
-    {
-      std::stringstream argSs;
-
-      argSs << "--" << std::get<0>(*it);
-      if(std::get<1>(*it).length() > 0)
-        argSs << "=" << std::get<1>(*it);
-      
-      argvStrings[argCounter] = argSs.str();
-      cmdLine = cmdLine + " " + argvStrings[argCounter];
-      std::cout << cmdLine << std::endl;
-      argv[argCounter] = argvStrings[argCounter].c_str();
-      argCounter++;
-    }
-
-
-    std::cout << "simulated cmdLine = \"" << cmdLine.c_str() << "\"\n";
-
-    try
-    {
-      boost::program_options::store(
-        boost::program_options::command_line_parser(argCounter, argv.data()).
-          options(options).allow_unregistered().run(), parameters);
-      boost::program_options::notify(parameters);
-    }
-    catch (boost::program_options::error& e)
-    {
-      std::cerr << "Error while parsing the command-line arguments: " <<
-        e.what() << std::endl;    
-    }
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Applications/Wasm/StartupParametersBuilder.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include <boost/program_options.hpp>
-#include <tuple>
-
-#if ORTHANC_ENABLE_SDL == 1
-#error this file shall be included only with the ORTHANC_ENABLE_SDL set to 0
-#endif
-
-namespace OrthancStone
-{
-  // This class is used to generate boost program options from a dico.
-  // In a Wasm context, startup options are passed as URI arguments that
-  // are then passed to this class as a dico.
-  // This class regenerates a fake command-line and parses it to produce
-  // the same output as if the app was started at command-line.
-  class StartupParametersBuilder
-  {
-    typedef std::list<std::tuple<std::string, std::string>> StartupParameters;
-    StartupParameters startupParameters_;
-
-  public:
-
-    void Clear();
-    // Please note that if a parameter is a flag-style one, the value that 
-    // is passed should be an empty string
-    void SetStartupParameter(const char* name, const char* value);
-    void GetStartupParameters(
-      boost::program_options::variables_map& parameters_, 
-      const boost::program_options::options_description& options);
-  };
-
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/DelayedCallCommand.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "DelayedCallCommand.h"
-#include "boost/thread/thread.hpp"
-
-#include <iostream>
-
-namespace Deprecated
-{
-  DelayedCallCommand::DelayedCallCommand(MessageHandler<IDelayedCallExecutor::TimeoutMessage>* callback,  // takes ownership
-                                         unsigned int timeoutInMs,
-                                         Orthanc::IDynamicObject* payload /* takes ownership */,
-                                         OrthancStone::NativeStoneApplicationContext& context
-                                         ) :
-    callback_(callback),
-    payload_(payload),
-    context_(context),
-    expirationTimePoint_(boost::posix_time::microsec_clock::local_time() + boost::posix_time::milliseconds(timeoutInMs)),
-    timeoutInMs_(timeoutInMs)
-  {
-  }
-
-
-  void DelayedCallCommand::Execute()
-  {
-    while (boost::posix_time::microsec_clock::local_time() < expirationTimePoint_)
-    {
-      boost::this_thread::sleep(boost::posix_time::milliseconds(1));
-    }
-  }
-
-  void DelayedCallCommand::Commit()
-  {
-    // We want to make sure that, i.e, the UpdateThread is not
-    // triggered while we are updating the "model" with the result of
-    // an OracleCommand
-    OrthancStone::NativeStoneApplicationContext::GlobalMutexLocker lock(context_);
-
-    if (callback_.get() != NULL)
-    {
-      IDelayedCallExecutor::TimeoutMessage message; // TODO: add payload
-      callback_->Apply(message);
-    }
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/DelayedCallCommand.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "IOracleCommand.h"
-
-#include "../../Framework/Deprecated/Toolbox/IDelayedCallExecutor.h"
-#include "../../Framework/Messages/IObservable.h"
-#include "../../Framework/Messages/ICallable.h"
-#include "../../Applications/Generic/NativeStoneApplicationContext.h"
-
-#include <boost/date_time/posix_time/posix_time.hpp>
-
-namespace Deprecated
-{
-  class DelayedCallCommand : public IOracleCommand, OrthancStone::IObservable
-  {
-  protected:
-    std::unique_ptr<MessageHandler<IDelayedCallExecutor::TimeoutMessage> >  callback_;
-    std::unique_ptr<Orthanc::IDynamicObject>  payload_;
-    OrthancStone::NativeStoneApplicationContext&          context_;
-    boost::posix_time::ptime                expirationTimePoint_;
-    unsigned int                            timeoutInMs_;
-
-  public:
-    DelayedCallCommand(MessageHandler<IDelayedCallExecutor::TimeoutMessage>* callback,  // takes ownership
-                       unsigned int timeoutInMs,
-                       Orthanc::IDynamicObject* payload /* takes ownership */,
-                       OrthancStone::NativeStoneApplicationContext& context
-                       );
-
-    virtual void Execute();
-
-    virtual void Commit();
-  };
-
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/IOracleCommand.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include <Core/IDynamicObject.h>
-
-namespace Deprecated
-{
-  class IOracleCommand : public Orthanc::IDynamicObject
-  {
-  public:
-    virtual ~IOracleCommand()
-    {
-    }
-
-    // This part of the command can be invoked simultaneously, and
-    // must not modify the Stone context
-    virtual void Execute() = 0;
-
-    // This part of the command must be invoked in mutual exclusion
-    virtual void Commit() = 0;
-  };
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/Oracle.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,212 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "Oracle.h"
-
-#include <Core/Logging.h>
-#include <Core/MultiThreading/SharedMessageQueue.h>
-#include <Core/OrthancException.h>
-
-#include <vector>
-#include <stdio.h>
-#include <boost/thread/mutex.hpp>
-
-namespace Deprecated
-{
-  class Oracle::PImpl
-  {
-  private:
-    enum State
-    {
-      State_Init,
-      State_Started,
-      State_Stopped
-    };
-
-    boost::mutex                   oracleMutex_;
-    State                          state_;
-    std::vector<boost::thread*>    threads_;
-    Orthanc::SharedMessageQueue    queue_;
-
-    static void Worker(PImpl* that)
-    {
-      for (;;)
-      {
-        State state;
-        
-        {
-          boost::mutex::scoped_lock lock(that->oracleMutex_);
-          state = that->state_;
-        }
-
-        if (state == State_Stopped)
-        {
-          break;
-        }
-
-        std::unique_ptr<Orthanc::IDynamicObject> item(that->queue_.Dequeue(100));
-        if (item.get() != NULL)
-        {
-          IOracleCommand& command = dynamic_cast<IOracleCommand&>(*item);
-          try
-          {
-            command.Execute();
-          }
-          catch (Orthanc::OrthancException& /*ex*/)
-          {
-            // this is probably a curl error that has been triggered.  We may just ignore it.
-            // The command.success_ will stay at false and this will be handled in the command.Commit
-          }
-
-          // Random sleeping to test
-          //boost::this_thread::sleep(boost::posix_time::milliseconds(50 * (1 + rand() % 10)));
-
-          command.Commit();
-        }
-      }
-    }
-    
-  public:
-    PImpl(unsigned int threadCount) :
-      state_(State_Init),
-      threads_(threadCount)
-    {
-    }
-
-    ~PImpl()
-    {
-      if (state_ == State_Started)
-      {
-        LOG(ERROR) << "You should have manually called Oracle::Stop()";
-        Stop();
-      }
-    }
-
-    Orthanc::SharedMessageQueue& GetQueue()
-    {
-      return queue_;
-    }
-
-    void Submit(IOracleCommand* command)
-    {
-      std::unique_ptr<IOracleCommand> protection(command);
-
-      if (command == NULL)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
-      }
-      
-      boost::mutex::scoped_lock lock(oracleMutex_);
-
-      switch (state_)
-      {
-        case State_Init:
-        case State_Started:
-          queue_.Enqueue(protection.release());
-          break;
-
-        case State_Stopped:
-          LOG(ERROR) << "Cannot schedule a request to the Oracle after having "
-                     << "called Oracle::Stop()";
-          break;
-
-        default:
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-      }
-      
-    }
-
-    void Start()
-    {
-      boost::mutex::scoped_lock lock(oracleMutex_);
-
-      if (state_ != State_Init)
-      {
-        LOG(ERROR) << "Oracle::PImpl::Start: (state_ != State_Init)";
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-      }
-      
-      for (size_t i = 0; i < threads_.size(); i++)
-      {
-        threads_[i] = new boost::thread(Worker, this);
-      }
-
-      state_ = State_Started;
-    }
-
-    void Stop()
-    {
-      {
-        boost::mutex::scoped_lock lock(oracleMutex_);
-
-        if (state_ != State_Started)
-        {
-          LOG(ERROR) << "Oracle::PImpl::Stop(): (state_ != State_Started)";
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-        }
-
-        state_ = State_Stopped;
-      }
-      
-      for (size_t i = 0; i < threads_.size(); i++)
-      {
-        if (threads_[i] != NULL)
-        {
-          if (threads_[i]->joinable())
-          {
-            threads_[i]->join();
-          }
-
-          delete threads_[i];
-        }
-      }
-    }
-  };
-  
-
-  Oracle::Oracle(unsigned int threadCount) :
-    pimpl_(new PImpl(threadCount))
-  {
-  }
-
-  void Oracle::Start()
-  {
-    pimpl_->Start();
-  }
-
-
-  void Oracle::Submit(IOracleCommand* command)
-  {
-    pimpl_->Submit(command);
-  }
-     
-   
-  void Oracle::Stop()
-  {
-    pimpl_->Stop();
-  }
-
-
-  void Oracle::WaitEmpty()
-  {
-    pimpl_->GetQueue().WaitEmpty(50);
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/Oracle.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "IOracleCommand.h"
-
-#include <boost/shared_ptr.hpp>
-
-namespace Deprecated
-{
-  class Oracle : public boost::noncopyable
-  {
-  private:
-    class PImpl;
-  
-    boost::shared_ptr<PImpl>  pimpl_;
-
-  public:
-    Oracle(unsigned int threadCount);
-
-    void Start();
-
-    void Submit(IOracleCommand* command);
-        
-    void WaitEmpty();  // For unit tests
-
-    void Stop();
-  };
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/OracleDelayedCallExecutor.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Framework/Deprecated/Toolbox/IDelayedCallExecutor.h"
-#include "Oracle.h"
-#include "../../Applications/Generic/NativeStoneApplicationContext.h"
-#include "DelayedCallCommand.h"
-
-namespace Deprecated
-{
-  // The OracleTimeout executes callbacks after a delay.
-  class OracleDelayedCallExecutor : public IDelayedCallExecutor
-  {
-  private:
-    Oracle&                        oracle_;
-    OrthancStone::NativeStoneApplicationContext& context_;
-
-  public:
-    OracleDelayedCallExecutor(Oracle& oracle,
-                              OrthancStone::NativeStoneApplicationContext& context) :
-      oracle_(oracle),
-      context_(context)
-    {
-    }
-
-    virtual void Schedule(MessageHandler<IDelayedCallExecutor::TimeoutMessage>* callback,
-                          unsigned int timeoutInMs = 1000)
-    {
-      oracle_.Submit(new DelayedCallCommand(callback, timeoutInMs, NULL, context_));
-    }
-  };
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/OracleWebService.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "OracleWebService.h"
-#include "../../Framework/Deprecated/Toolbox/IWebService.h"
-
-namespace Deprecated
-{
-
-
-  class OracleWebService::WebServiceCachedGetCommand : public IOracleCommand, OrthancStone::IObservable
-  {
-  protected:
-    std::unique_ptr<MessageHandler<IWebService::HttpRequestSuccessMessage> >  successCallback_;
-    std::unique_ptr<Orthanc::IDynamicObject>                                  payload_;
-    boost::shared_ptr<BaseWebService::CachedHttpRequestSuccessMessage>      cachedMessage_;
-    OrthancStone::NativeStoneApplicationContext&                                          context_;
-
-  public:
-    WebServiceCachedGetCommand(MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback,  // takes ownership
-                               boost::shared_ptr<BaseWebService::CachedHttpRequestSuccessMessage> cachedMessage,
-                               Orthanc::IDynamicObject* payload /* takes ownership */,
-                               OrthancStone::NativeStoneApplicationContext& context
-                               ) :
-      successCallback_(successCallback),
-      payload_(payload),
-      cachedMessage_(cachedMessage),
-      context_(context)
-    {
-    }
-
-    virtual void Execute()
-    {
-      // nothing to do, everything is in the commit
-    }
-
-    virtual void Commit()
-    {
-      // We want to make sure that, i.e, the UpdateThread is not
-      // triggered while we are updating the "model" with the result of
-      // a WebServiceCommand
-      OrthancStone::NativeStoneApplicationContext::GlobalMutexLocker lock(context_);
-
-      IWebService::HttpRequestSuccessMessage successMessage(cachedMessage_->GetUri(),
-                                                            cachedMessage_->GetAnswer(),
-                                                            cachedMessage_->GetAnswerSize(),
-                                                            cachedMessage_->GetAnswerHttpHeaders(),
-                                                            payload_.get());
-
-      successCallback_->Apply(successMessage);
-    }
-  };
-
-  void OracleWebService::NotifyHttpSuccessLater(boost::shared_ptr<BaseWebService::CachedHttpRequestSuccessMessage> cachedMessage,
-                                                Orthanc::IDynamicObject* payload, // takes ownership
-                                                MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback)
-  {
-    oracle_.Submit(new WebServiceCachedGetCommand(successCallback, cachedMessage, payload, context_));
-  }
-
-
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/OracleWebService.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Framework/Deprecated/Toolbox/BaseWebService.h"
-#include "Oracle.h"
-#include "WebServiceGetCommand.h"
-#include "WebServicePostCommand.h"
-#include "WebServiceDeleteCommand.h"
-#include "../../Applications/Generic/NativeStoneApplicationContext.h"
-
-namespace Deprecated
-{
-  // The OracleWebService performs HTTP requests in a native environment.
-  // It uses a thread pool to handle multiple HTTP requests in a same time.
-  // It works asynchronously to mimick the behaviour of the WebService running in a WASM environment.
-  class OracleWebService : public BaseWebService
-  {
-  private:
-    Oracle&                        oracle_;
-    OrthancStone::NativeStoneApplicationContext& context_;
-    Orthanc::WebServiceParameters  parameters_;
-
-    class WebServiceCachedGetCommand;
-
-  public:
-    OracleWebService(Oracle& oracle,
-                     const Orthanc::WebServiceParameters& parameters,
-                     OrthancStone::NativeStoneApplicationContext& context) :
-      oracle_(oracle),
-      context_(context),
-      parameters_(parameters)
-    {
-    }
-
-    virtual void PostAsync(const std::string& uri,
-                           const HttpHeaders& headers,
-                           const std::string& body,
-                           Orthanc::IDynamicObject* payload, // takes ownership
-                           MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback, // takes ownership
-                           MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback = NULL, // takes ownership
-                           unsigned int timeoutInSeconds = 60)
-    {
-      oracle_.Submit(new WebServicePostCommand(successCallback, failureCallback, parameters_, uri, headers, timeoutInSeconds, body, payload, context_));
-    }
-
-    virtual void DeleteAsync(const std::string& uri,
-                             const HttpHeaders& headers,
-                             Orthanc::IDynamicObject* payload,
-                             MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback,
-                             MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback = NULL,
-                             unsigned int timeoutInSeconds = 60)
-    {
-      oracle_.Submit(new WebServiceDeleteCommand(successCallback, failureCallback, parameters_, uri, headers, timeoutInSeconds, payload, context_));
-    }
-
-  protected:
-    virtual void GetAsyncInternal(const std::string& uri,
-                                  const HttpHeaders& headers,
-                                  Orthanc::IDynamicObject* payload, // takes ownership
-                                  MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback,   // takes ownership
-                                  MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback = NULL,// takes ownership
-                                  unsigned int timeoutInSeconds = 60)
-    {
-      oracle_.Submit(new WebServiceGetCommand(successCallback, failureCallback, parameters_, uri, headers, timeoutInSeconds, payload, context_));
-    }
-
-    virtual void NotifyHttpSuccessLater(boost::shared_ptr<BaseWebService::CachedHttpRequestSuccessMessage> cachedHttpMessage,
-                                        Orthanc::IDynamicObject* payload, // takes ownership
-                                        MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback);
-
-  };
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/WebServiceCommandBase.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "WebServiceCommandBase.h"
-
-#include <Core/HttpClient.h>
-
-namespace Deprecated
-{
-  WebServiceCommandBase::WebServiceCommandBase(MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback,
-                                               MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback,
-                                               const Orthanc::WebServiceParameters& parameters,
-                                               const std::string& url,
-                                               const IWebService::HttpHeaders& headers,
-                                               unsigned int timeoutInSeconds,
-                                               Orthanc::IDynamicObject* payload /* takes ownership */,
-                                               OrthancStone::NativeStoneApplicationContext& context) :
-    successCallback_(successCallback),
-    failureCallback_(failureCallback),
-    parameters_(parameters),
-    url_(url),
-    headers_(headers),
-    payload_(payload),
-    success_(false),
-    httpStatus_(Orthanc::HttpStatus_None),
-    context_(context),
-    timeoutInSeconds_(timeoutInSeconds)
-  {
-  }
-
-
-  void WebServiceCommandBase::Commit()
-  {
-    // We want to make sure that, i.e, the UpdateThread is not
-    // triggered while we are updating the "model" with the result of
-    // a WebServiceCommand
-    OrthancStone::NativeStoneApplicationContext::GlobalMutexLocker lock(context_); 
-
-    if (success_ && successCallback_.get() != NULL)
-    {
-      IWebService::HttpRequestSuccessMessage message
-        (url_, answer_.c_str(), answer_.size(), answerHeaders_, payload_.get());
-      successCallback_->Apply(message);
-    }
-    else if (!success_ && failureCallback_.get() != NULL)
-    {
-      IWebService::HttpRequestErrorMessage message(url_, httpStatus_, payload_.get());
-      failureCallback_->Apply(message);
-    }
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/WebServiceCommandBase.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "IOracleCommand.h"
-
-#include "../../Framework/Deprecated/Toolbox/IWebService.h"
-#include "../../Framework/Messages/IObservable.h"
-#include "../../Framework/Messages/ICallable.h"
-#include "../../Applications/Generic/NativeStoneApplicationContext.h"
-
-#include <Core/WebServiceParameters.h>
-
-#include <memory>
-
-namespace Deprecated
-{
-  class WebServiceCommandBase : public IOracleCommand, OrthancStone::IObservable
-  {
-  protected:
-    std::unique_ptr<MessageHandler<IWebService::HttpRequestSuccessMessage> >  successCallback_;
-    std::unique_ptr<MessageHandler<IWebService::HttpRequestErrorMessage> >    failureCallback_;
-    Orthanc::WebServiceParameters           parameters_;
-    std::string                             url_;
-    IWebService::HttpHeaders                headers_;
-    std::unique_ptr<Orthanc::IDynamicObject>  payload_;
-    bool                                    success_;
-    Orthanc::HttpStatus                     httpStatus_;
-    std::string                             answer_;
-    IWebService::HttpHeaders                answerHeaders_;
-    OrthancStone::NativeStoneApplicationContext&          context_;
-    unsigned int                            timeoutInSeconds_;
-
-  public:
-    WebServiceCommandBase(MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback,  // takes ownership
-                          MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback,  // takes ownership
-                          const Orthanc::WebServiceParameters& parameters,
-                          const std::string& url,
-                          const IWebService::HttpHeaders& headers,
-                          unsigned int timeoutInSeconds,
-                          Orthanc::IDynamicObject* payload /* takes ownership */,
-                          OrthancStone::NativeStoneApplicationContext& context
-                          );
-
-    virtual void Execute() = 0;
-
-    virtual void Commit();
-  };
-
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/WebServiceDeleteCommand.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "WebServiceDeleteCommand.h"
-
-#include <Core/HttpClient.h>
-
-namespace Deprecated
-{
-  WebServiceDeleteCommand::WebServiceDeleteCommand(MessageHandler<Deprecated::IWebService::HttpRequestSuccessMessage>* successCallback,  // takes ownership
-                                                   MessageHandler<Deprecated::IWebService::HttpRequestErrorMessage>* failureCallback,  // takes ownership
-                                                   const Orthanc::WebServiceParameters& parameters,
-                                                   const std::string& url,
-                                                   const Deprecated::IWebService::HttpHeaders& headers,
-                                                   unsigned int timeoutInSeconds,
-                                                   Orthanc::IDynamicObject* payload /* takes ownership */,
-                                                   OrthancStone::NativeStoneApplicationContext& context) :
-    WebServiceCommandBase(successCallback, failureCallback, parameters, url, headers, timeoutInSeconds, payload, context)
-  {
-  }
-
-  void WebServiceDeleteCommand::Execute()
-  {
-    Orthanc::HttpClient client(parameters_, "/");
-    client.SetUrl(url_);
-    client.SetTimeout(timeoutInSeconds_);
-    client.SetMethod(Orthanc::HttpMethod_Delete);
-
-    for (Deprecated::IWebService::HttpHeaders::const_iterator it = headers_.begin(); it != headers_.end(); it++ )
-    {
-      client.AddHeader(it->first, it->second);
-    }
-
-    success_ = client.Apply(answer_, answerHeaders_);
-    httpStatus_ = client.GetLastStatus();
-  }
-
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/WebServiceDeleteCommand.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "WebServiceCommandBase.h"
-
-namespace Deprecated
-{
-  class WebServiceDeleteCommand : public WebServiceCommandBase
-  {
-  public:
-    WebServiceDeleteCommand(MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback,  // takes ownership
-                            MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback,  // takes ownership
-                            const Orthanc::WebServiceParameters& parameters,
-                            const std::string& url,
-                            const IWebService::HttpHeaders& headers,
-                            unsigned int timeoutInSeconds,
-                            Orthanc::IDynamicObject* payload /* takes ownership */,
-                            OrthancStone::NativeStoneApplicationContext& context);
-
-    virtual void Execute();
-  };
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/WebServiceGetCommand.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "WebServiceGetCommand.h"
-
-#include <Core/HttpClient.h>
-
-namespace Deprecated
-{
-  WebServiceGetCommand::WebServiceGetCommand(MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback,  // takes ownership
-                                             MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback,  // takes ownership
-                                             const Orthanc::WebServiceParameters& parameters,
-                                             const std::string& url,
-                                             const IWebService::HttpHeaders& headers,
-                                             unsigned int timeoutInSeconds,
-                                             Orthanc::IDynamicObject* payload /* takes ownership */,
-                                             OrthancStone::NativeStoneApplicationContext& context) :
-    WebServiceCommandBase(successCallback, failureCallback, parameters, url, headers, timeoutInSeconds, payload, context)
-  {
-  }
-
-
-  void WebServiceGetCommand::Execute()
-  {
-    Orthanc::HttpClient client(parameters_, "/");
-    client.SetUrl(url_);
-    client.SetTimeout(timeoutInSeconds_);
-    client.SetMethod(Orthanc::HttpMethod_Get);
-
-    for (IWebService::HttpHeaders::const_iterator it = headers_.begin(); it != headers_.end(); it++ )
-    {
-      client.AddHeader(it->first, it->second);
-    }
-
-    success_ = client.Apply(answer_, answerHeaders_);
-    httpStatus_ = client.GetLastStatus();
-  }
-
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/WebServiceGetCommand.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "WebServiceCommandBase.h"
-
-namespace Deprecated
-{
-  class WebServiceGetCommand : public WebServiceCommandBase
-  {
-  public:
-    WebServiceGetCommand(MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback,  // takes ownership
-                         MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback,  // takes ownership
-                         const Orthanc::WebServiceParameters& parameters,
-                         const std::string& url,
-                         const IWebService::HttpHeaders& headers,
-                         unsigned int timeoutInSeconds,
-                         Orthanc::IDynamicObject* payload /* takes ownership */,
-                         OrthancStone::NativeStoneApplicationContext& context);
-
-    virtual void Execute();
-  };
-
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/WebServicePostCommand.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "WebServicePostCommand.h"
-
-#include <Core/HttpClient.h>
-
-namespace Deprecated
-{
-  WebServicePostCommand::WebServicePostCommand(MessageHandler<Deprecated::IWebService::HttpRequestSuccessMessage>* successCallback,  // takes ownership
-                                               MessageHandler<Deprecated::IWebService::HttpRequestErrorMessage>* failureCallback,  // takes ownership
-                                               const Orthanc::WebServiceParameters& parameters,
-                                               const std::string& url,
-                                               const Deprecated::IWebService::HttpHeaders& headers,
-                                               unsigned int timeoutInSeconds,
-                                               const std::string& body,
-                                               Orthanc::IDynamicObject* payload /* takes ownership */,
-                                               OrthancStone::NativeStoneApplicationContext& context) :
-    WebServiceCommandBase(successCallback, failureCallback, parameters, url, headers, timeoutInSeconds, payload, context),
-    body_(body)
-  {
-  }
-
-  void WebServicePostCommand::Execute()
-  {
-    Orthanc::HttpClient client(parameters_, "/");
-    client.SetUrl(url_);
-    client.SetTimeout(timeoutInSeconds_);
-    client.SetMethod(Orthanc::HttpMethod_Post);
-    client.GetBody().swap(body_);
-
-    for (Deprecated::IWebService::HttpHeaders::const_iterator it = headers_.begin(); it != headers_.end(); it++ )
-    {
-      client.AddHeader(it->first, it->second);
-    }
-
-    success_ = client.Apply(answer_, answerHeaders_);
-    httpStatus_ = client.GetLastStatus();
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Generic/WebServicePostCommand.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "WebServiceCommandBase.h"
-
-namespace Deprecated
-{
-  class WebServicePostCommand : public WebServiceCommandBase
-  {
-  protected:
-    std::string  body_;
-
-  public:
-    WebServicePostCommand(MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback,  // takes ownership
-                          MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback,  // takes ownership
-                          const Orthanc::WebServiceParameters& parameters,
-                          const std::string& url,
-                          const IWebService::HttpHeaders& headers,
-                          unsigned int timeoutInSeconds,
-                          const std::string& body,
-                          Orthanc::IDynamicObject* payload /* takes ownership */,
-                          OrthancStone::NativeStoneApplicationContext& context);
-
-    virtual void Execute();
-  };
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/Defaults.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,437 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "Defaults.h"
-
-#include "WasmWebService.h"
-#include "WasmDelayedCallExecutor.h"
-#include "../../../Framework/Deprecated/Widgets/TestCairoWidget.h"
-#include "../../../Framework/Deprecated/Viewport/WidgetViewport.h"
-#include <Applications/Wasm/StartupParametersBuilder.h>
-#include <Platforms/Wasm/WasmPlatformApplicationAdapter.h>
-#include <Framework/StoneInitialization.h>
-#include <Core/Logging.h>
-#include <sstream>
-
-#include <algorithm>
-
-
-static unsigned int width_ = 0;
-static unsigned int height_ = 0;
-
-/**********************************/
-
-static std::unique_ptr<OrthancStone::IStoneApplication> application;
-static std::unique_ptr<OrthancStone::WasmPlatformApplicationAdapter> applicationWasmAdapter = NULL;
-static std::unique_ptr<OrthancStone::StoneApplicationContext> context;
-static OrthancStone::StartupParametersBuilder startupParametersBuilder;
-static OrthancStone::MessageBroker broker;
-
-static OrthancStone::ViewportContentChangedObserver viewportContentChangedObserver_(broker);
-static OrthancStone::StatusBar statusBar_;
-
-static std::list<std::shared_ptr<Deprecated::WidgetViewport>> viewports_;
-
-std::shared_ptr<Deprecated::WidgetViewport> FindViewportSharedPtr(ViewportHandle viewport) {
-  for (const auto& v : viewports_) {
-    if (v.get() == viewport) {
-      return v;
-    }
-  }
-  assert(false);
-  return std::shared_ptr<Deprecated::WidgetViewport>();
-}
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if 0
-  // rewrite malloc/free in order to monitor allocations.  We actually only monitor large allocations (like images ...)
-
-  size_t bigChunksTotalSize = 0;
-  std::map<void*, size_t> allocatedBigChunks;
-
-  extern void* emscripten_builtin_malloc(size_t bytes);
-  extern void emscripten_builtin_free(void* mem);
-
-  void * __attribute__((noinline)) malloc(size_t size)
-  {
-    void *ptr = emscripten_builtin_malloc(size);
-    if (size > 100000)
-    {
-      bigChunksTotalSize += size;
-      printf("++ Allocated %zu bytes, got %p. (%zu MB consumed by big chunks)\n", size, ptr, bigChunksTotalSize/(1024*1024));
-      allocatedBigChunks[ptr] = size;
-    }
-    return ptr;
-  }
-
-  void __attribute__((noinline)) free(void *ptr)
-  {
-    emscripten_builtin_free(ptr);
-
-    std::map<void*, size_t>::iterator it = allocatedBigChunks.find(ptr);
-    if (it != allocatedBigChunks.end())
-    {
-      bigChunksTotalSize -= it->second;
-      printf("--     Freed %zu bytes at %p.   (%zu MB consumed by big chunks)\n", it->second, ptr, bigChunksTotalSize/(1024*1024));
-      allocatedBigChunks.erase(it);
-    }
-  }
-#endif // 0
-
-  using namespace OrthancStone;
-
-  // when WASM needs a C++ viewport
-  ViewportHandle EMSCRIPTEN_KEEPALIVE CreateCppViewport() {
-    
-    std::shared_ptr<Deprecated::WidgetViewport> viewport(new Deprecated::WidgetViewport(broker));
-    printf("viewport %x\n", (int)viewport.get());
-
-    viewports_.push_back(viewport);
-
-    printf("There are now %lu viewports in C++\n", viewports_.size());
-
-    viewport->SetStatusBar(statusBar_);
-
-    viewport->RegisterObserverCallback(
-      new Callable<ViewportContentChangedObserver, Deprecated::IViewport::ViewportChangedMessage>
-      (viewportContentChangedObserver_, &ViewportContentChangedObserver::OnViewportChanged));
-
-    return viewport.get();
-  }
-
-  // when WASM does not need a viewport anymore, it should release it 
-  void EMSCRIPTEN_KEEPALIVE ReleaseCppViewport(ViewportHandle viewport) {
-    viewports_.remove_if([viewport](const std::shared_ptr<Deprecated::WidgetViewport>& v) { return v.get() == viewport;});
-
-    printf("There are now %lu viewports in C++\n", viewports_.size());
-  }
-
-  void EMSCRIPTEN_KEEPALIVE CreateWasmApplication(ViewportHandle viewport) {
-    printf("Initializing Stone\n");
-    OrthancStone::StoneInitialize();
-    printf("CreateWasmApplication\n");
-
-    application.reset(CreateUserApplication(broker));
-    applicationWasmAdapter.reset(CreateWasmApplicationAdapter(broker, application.get())); 
-    Deprecated::WasmWebService::SetBroker(broker);
-    Deprecated::WasmDelayedCallExecutor::SetBroker(broker);
-
-    startupParametersBuilder.Clear();
-  }
-
-  void EMSCRIPTEN_KEEPALIVE SetStartupParameter(const char* keyc,
-                                                  const char* value) {
-    startupParametersBuilder.SetStartupParameter(keyc, value);
-  }
-
-  void EMSCRIPTEN_KEEPALIVE StartWasmApplication(const char* baseUri) {
-
-    printf("StartWasmApplication\n");
-
-    Orthanc::Logging::SetErrorWarnInfoTraceLoggingFunctions(
-      stone_console_error, stone_console_warning,
-      stone_console_info, stone_console_trace);
-
-    // recreate a command line from uri arguments and parse it
-    boost::program_options::variables_map parameters;
-    boost::program_options::options_description options;
-    application->DeclareStartupOptions(options);
-    startupParametersBuilder.GetStartupParameters(parameters, options);
-
-    context.reset(new OrthancStone::StoneApplicationContext(broker));
-    context->SetOrthancBaseUrl(baseUri);
-    printf("Base URL to Orthanc API: [%s]\n", baseUri);
-    context->SetWebService(Deprecated::WasmWebService::GetInstance());
-    context->SetDelayedCallExecutor(Deprecated::WasmDelayedCallExecutor::GetInstance());
-    application->Initialize(context.get(), statusBar_, parameters);
-    application->InitializeWasm();
-
-//    viewport->SetSize(width_, height_);
-    printf("StartWasmApplication - completed\n");
-  }
-  
-  bool EMSCRIPTEN_KEEPALIVE WasmIsTraceLevelEnabled()
-  {
-    return Orthanc::Logging::IsTraceLevelEnabled();
-  }
-
-  bool EMSCRIPTEN_KEEPALIVE WasmIsInfoLevelEnabled()
-  {
-    return Orthanc::Logging::IsInfoLevelEnabled();
-  }
-  
-  void EMSCRIPTEN_KEEPALIVE WasmDoAnimation()
-  {
-    for (auto viewport : viewports_) {
-      // TODO Only launch the JavaScript timer if "HasAnimation()"
-      if (viewport->HasAnimation())
-      {
-        viewport->DoAnimation();
-      }
-
-    }
-
-  }
-  
-
-  void EMSCRIPTEN_KEEPALIVE ViewportSetSize(ViewportHandle viewport, unsigned int width, unsigned int height)
-  {
-    width_ = width;
-    height_ = height;
-    
-    viewport->SetSize(width, height);
-  }
-
-  int EMSCRIPTEN_KEEPALIVE ViewportRender(ViewportHandle viewport,
-                                          unsigned int width,
-                                          unsigned int height,
-                                          uint8_t* data)
-  {
-    viewportContentChangedObserver_.Reset();
-
-    //printf("ViewportRender called %dx%d\n", width, height);
-    if (width == 0 ||
-        height == 0)
-    {
-      return 1;
-    }
-
-    Orthanc::ImageAccessor surface;
-    surface.AssignWritable(Orthanc::PixelFormat_BGRA32, width, height, 4 * width, data);
-
-    viewport->Render(surface);
-
-    // Convert from BGRA32 memory layout (only color mode supported by
-    // Cairo, which corresponds to CAIRO_FORMAT_ARGB32) to RGBA32 (as
-    // expected by HTML5 canvas). This simply amounts to swapping the
-    // B and R channels.
-    uint8_t* p = data;
-    for (unsigned int y = 0; y < height; y++) {
-      for (unsigned int x = 0; x < width; x++) {
-        uint8_t tmp = p[0];
-        p[0] = p[2];
-        p[2] = tmp;
-        
-        p += 4;
-      }
-    }
-
-    return 1;
-  }
-
-
-  void EMSCRIPTEN_KEEPALIVE ViewportMouseDown(ViewportHandle viewport,
-                                              unsigned int rawButton,
-                                              int x,
-                                              int y,
-                                              unsigned int rawModifiers)
-  {
-    OrthancStone::MouseButton button;
-    switch (rawButton)
-    {
-      case 0:
-        button = OrthancStone::MouseButton_Left;
-        break;
-
-      case 1:
-        button = OrthancStone::MouseButton_Middle;
-        break;
-
-      case 2:
-        button = OrthancStone::MouseButton_Right;
-        break;
-
-      default:
-        return;  // Unknown button
-    }
-
-    viewport->MouseDown(button, x, y, OrthancStone::KeyboardModifiers_None, std::vector<Deprecated::Touch>());
-  }
-  
-
-  void EMSCRIPTEN_KEEPALIVE ViewportMouseWheel(ViewportHandle viewport,
-                                               int deltaY,
-                                               int x,
-                                               int y,
-                                               int isControl)
-  {
-    if (deltaY != 0)
-    {
-      OrthancStone::MouseWheelDirection direction = (deltaY < 0 ?
-                                                     OrthancStone::MouseWheelDirection_Up :
-                                                     OrthancStone::MouseWheelDirection_Down);
-      OrthancStone::KeyboardModifiers modifiers = OrthancStone::KeyboardModifiers_None;
-
-      if (isControl != 0)
-      {
-        modifiers = OrthancStone::KeyboardModifiers_Control;
-      }
-
-      viewport->MouseWheel(direction, x, y, modifiers);
-    }
-  }
-  
-
-  void EMSCRIPTEN_KEEPALIVE ViewportMouseMove(ViewportHandle viewport,
-                                              int x,
-                                              int y)
-  {
-    viewport->MouseMove(x, y, std::vector<Deprecated::Touch>());
-  }
-
-  void GetTouchVector(std::vector<Deprecated::Touch>& output,
-                      int touchCount,
-                      float x0,
-                      float y0,
-                      float x1,
-                      float y1,
-                      float x2,
-                      float y2)
-  {
-    // TODO: it might be nice to try to pass all the x0,y0 coordinates as arrays but that's not so easy to pass array between JS and C++
-    if (touchCount > 0)
-    {
-      output.push_back(Deprecated::Touch(x0, y0));
-    }
-    if (touchCount > 1)
-    {
-      output.push_back(Deprecated::Touch(x1, y1));
-    }
-    if (touchCount > 2)
-    {
-      output.push_back(Deprecated::Touch(x2, y2));
-    }
-
-  }
-
-  void EMSCRIPTEN_KEEPALIVE ViewportTouchStart(ViewportHandle viewport,
-                                              int touchCount,
-                                              float x0,
-                                              float y0,
-                                              float x1,
-                                              float y1,
-                                              float x2,
-                                              float y2)
-  {
-    // printf("touch start with %d touches\n", touchCount);
-
-    std::vector<Deprecated::Touch> touches;
-    GetTouchVector(touches, touchCount, x0, y0, x1, y1, x2, y2);
-    viewport->TouchStart(touches);
-  }
-
-  void EMSCRIPTEN_KEEPALIVE ViewportTouchMove(ViewportHandle viewport,
-                                              int touchCount,
-                                              float x0,
-                                              float y0,
-                                              float x1,
-                                              float y1,
-                                              float x2,
-                                              float y2)
-  {
-    // printf("touch move with %d touches\n", touchCount);
-
-    std::vector<Deprecated::Touch> touches;
-    GetTouchVector(touches, touchCount, x0, y0, x1, y1, x2, y2);
-    viewport->TouchMove(touches);
-  }
-
-  void EMSCRIPTEN_KEEPALIVE ViewportTouchEnd(ViewportHandle viewport,
-                                              int touchCount,
-                                              float x0,
-                                              float y0,
-                                              float x1,
-                                              float y1,
-                                              float x2,
-                                              float y2)
-  {
-    // printf("touch end with %d touches remaining\n", touchCount);
-
-    std::vector<Deprecated::Touch> touches;
-    GetTouchVector(touches, touchCount, x0, y0, x1, y1, x2, y2);
-    viewport->TouchEnd(touches);
-  }
-
-  void EMSCRIPTEN_KEEPALIVE ViewportKeyPressed(ViewportHandle viewport,
-                                               int key,
-                                               const char* keyChar, 
-                                               bool isShiftPressed, 
-                                               bool isControlPressed,
-                                               bool isAltPressed)
-                                               
-  {
-    OrthancStone::KeyboardModifiers modifiers = OrthancStone::KeyboardModifiers_None;
-    if (isShiftPressed) {
-      modifiers = static_cast<OrthancStone::KeyboardModifiers>(modifiers + OrthancStone::KeyboardModifiers_Shift);
-    }
-    if (isControlPressed) {
-      modifiers = static_cast<OrthancStone::KeyboardModifiers>(modifiers + OrthancStone::KeyboardModifiers_Control);
-    }
-    if (isAltPressed) {
-      modifiers = static_cast<OrthancStone::KeyboardModifiers>(modifiers + OrthancStone::KeyboardModifiers_Alt);
-    }
-
-    char c = 0;
-    if (keyChar != NULL && key == OrthancStone::KeyboardKeys_Generic) {
-      c = keyChar[0];
-    }
-    viewport->KeyPressed(static_cast<OrthancStone::KeyboardKeys>(key), c, modifiers);
-  }
-  
-
-  void EMSCRIPTEN_KEEPALIVE ViewportMouseUp(ViewportHandle viewport)
-  {
-    viewport->MouseUp();
-  }
-  
-
-  void EMSCRIPTEN_KEEPALIVE ViewportMouseEnter(ViewportHandle viewport)
-  {
-    viewport->MouseEnter();
-  }
-  
-
-  void EMSCRIPTEN_KEEPALIVE ViewportMouseLeave(ViewportHandle viewport)
-  {
-    viewport->MouseLeave();
-  }
-
-  const char* EMSCRIPTEN_KEEPALIVE SendSerializedMessageToStoneApplication(const char* message) 
-  {
-    static std::string output; // we don't want the string to be deallocated when we return to JS code so we always use the same string (this is fine since JS is single-thread)
-
-    //printf("SendSerializedMessageToStoneApplication\n");
-    //printf("%s", message);
-
-    if (applicationWasmAdapter.get() != NULL) {
-      applicationWasmAdapter->HandleSerializedMessageFromWeb(output, std::string(message));
-      return output.c_str();
-    }
-    printf("This Stone application does not have a Web Adapter, unable to send messages");
-    return NULL;
-  }
-
-#ifdef __cplusplus
-}
-#endif
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/Defaults.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include <emscripten/emscripten.h>
-
-#include "../../Framework/Deprecated/Viewport/WidgetViewport.h"
-#include "../../Framework/Deprecated/Widgets/LayoutWidget.h"
-#include <Applications/IStoneApplication.h>
-#include <Platforms/Wasm/WasmPlatformApplicationAdapter.h>
-
-typedef Deprecated::WidgetViewport* ViewportHandle; // the objects exchanged between JS and C++
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-  
-  // JS methods accessible from C++
-  extern void ScheduleWebViewportRedrawFromCpp(ViewportHandle cppViewportHandle);
-  extern void UpdateStoneApplicationStatusFromCppWithString(const char* statusUpdateMessage);
-  extern void UpdateStoneApplicationStatusFromCppWithSerializedMessage(const char* statusUpdateMessage);
-  extern void stone_console_error(const char*);
-  extern void stone_console_warning(const char*);
-  extern void stone_console_info(const char*);
-  extern void stone_console_trace(const char*);
-
-  // C++ methods accessible from JS
-  extern void EMSCRIPTEN_KEEPALIVE CreateWasmApplication(ViewportHandle cppViewportHandle);
-  extern void EMSCRIPTEN_KEEPALIVE SetStartupParameter(const char* keyc, const char* value);
-  
-
-#ifdef __cplusplus
-}
-#endif
-
-// these methods must be implemented in the custom app "mainWasm.cpp"
-extern OrthancStone::IStoneApplication* CreateUserApplication(OrthancStone::MessageBroker& broker);
-extern OrthancStone::WasmPlatformApplicationAdapter* CreateWasmApplicationAdapter(OrthancStone::MessageBroker& broker, OrthancStone::IStoneApplication* application);
-
-namespace OrthancStone {
-
-  // default Observer to trigger Viewport redraw when something changes in the Viewport
-  class ViewportContentChangedObserver : public IObserver
-  {
-  private:
-    // Flag to avoid flooding JavaScript with redundant Redraw requests
-    bool isScheduled_; 
-
-  public:
-    ViewportContentChangedObserver(MessageBroker& broker) :
-      IObserver(broker),
-      isScheduled_(false)
-    {
-    }
-
-    void Reset()
-    {
-      isScheduled_ = false;
-    }
-
-    void OnViewportChanged(const Deprecated::IViewport::ViewportChangedMessage& message)
-    {
-      if (!isScheduled_)
-      {
-        ScheduleWebViewportRedrawFromCpp((ViewportHandle)&message.GetOrigin());  // loosing constness when transmitted to Web
-        isScheduled_ = true;
-      }
-    }
-  };
-
-  // default status bar to log messages on the console/stdout
-  class StatusBar : public Deprecated::IStatusBar
-  {
-  public:
-    virtual void ClearMessage()
-    {
-    }
-
-    virtual void SetMessage(const std::string& message)
-    {
-      printf("%s\n", message.c_str());
-    }
-  };
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/WasmDelayedCallExecutor.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "WasmDelayedCallExecutor.h"
-#include "json/value.h"
-#include "json/writer.h"
-#include <emscripten/emscripten.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-  extern void WasmDelayedCallExecutor_Schedule(void* callable,
-                                      unsigned int timeoutInMs
-                                      /*void* payload*/);
-
-  void EMSCRIPTEN_KEEPALIVE WasmDelayedCallExecutor_ExecuteCallback(void* callable
-                                                       //void* payload
-                                                       )
-  {
-    if (callable == NULL)
-    {
-      throw;
-    }
-    else
-    {
-      reinterpret_cast<OrthancStone::MessageHandler<Deprecated::IDelayedCallExecutor::TimeoutMessage>*>(callable)->
-        Apply(Deprecated::IDelayedCallExecutor::TimeoutMessage()); // uri, reinterpret_cast<Orthanc::IDynamicObject*>(payload)));
-    }
-  }
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-
-namespace Deprecated
-{
-  OrthancStone::MessageBroker* WasmDelayedCallExecutor::broker_ = NULL;
-
-
-  void WasmDelayedCallExecutor::Schedule(OrthancStone::MessageHandler<IDelayedCallExecutor::TimeoutMessage>* callback,
-                         unsigned int timeoutInMs)
-  {
-    WasmDelayedCallExecutor_Schedule(callback, timeoutInMs);
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/WasmDelayedCallExecutor.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Framework/Deprecated/Toolbox/IDelayedCallExecutor.h"
-#include <Core/OrthancException.h>
-
-namespace Deprecated
-{
-  class WasmDelayedCallExecutor : public IDelayedCallExecutor
-  {
-  private:
-    static OrthancStone::MessageBroker* broker_;
-
-    // Private constructor => Singleton design pattern
-    WasmDelayedCallExecutor(OrthancStone::MessageBroker& broker) :
-      IDelayedCallExecutor(broker)
-    {
-    }
-
-  public:
-    static WasmDelayedCallExecutor& GetInstance()
-    {
-      if (broker_ == NULL)
-      {
-        printf("WasmDelayedCallExecutor::GetInstance(): broker not initialized\n");
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-      }
-      static WasmDelayedCallExecutor instance(*broker_);
-      return instance;
-    }
-
-    static void SetBroker(OrthancStone::MessageBroker& broker)
-    {
-      broker_ = &broker;
-    }
-
-    virtual void Schedule(OrthancStone::MessageHandler<IDelayedCallExecutor::TimeoutMessage>* callback,
-                         unsigned int timeoutInMs = 1000);
-
-  };
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/WasmDelayedCallExecutor.js	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-mergeInto(LibraryManager.library, {
-  WasmDelayedCallExecutor_Schedule: function(callable, timeoutInMs/*, payload*/) {
-    setTimeout(function() {
-      window.WasmDelayedCallExecutor_ExecuteCallback(callable/*, payload*/);
-    }, timeoutInMs);
-  }
-});
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/WasmPlatformApplicationAdapter.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "WasmPlatformApplicationAdapter.h"
-
-#include "Framework/StoneException.h"
-#include <stdio.h>
-#include "Platforms/Wasm/Defaults.h"
-
-namespace OrthancStone
-{
-  WasmPlatformApplicationAdapter::WasmPlatformApplicationAdapter(MessageBroker& broker, IStoneApplication& application)
-  : IObserver(broker),
-    application_(application)
-  {
-  }
-
-  void WasmPlatformApplicationAdapter::HandleSerializedMessageFromWeb(std::string& output, const std::string& input)
-  {
-    try
-    {
-      application_.HandleSerializedMessage(input.c_str());
-    }
-    catch (StoneException& exc)
-    {
-      printf("Error while handling message from web (error code = %d):\n", exc.GetErrorCode());
-      printf("While interpreting input: '%s'\n", input.c_str());
-      output = std::string("ERROR : ");
-    }
-    catch (std::exception& exc)
-    {
-      printf("Error while handling message from web (error text = %s):\n", exc.what());
-      printf("While interpreting input: '%s'\n", input.c_str());
-      output = std::string("ERROR : ");
-    }
-  }
-
-  void WasmPlatformApplicationAdapter::NotifyStatusUpdateFromCppToWebWithString(const std::string& statusUpdateMessage)
-  {
-    try
-    {
-      UpdateStoneApplicationStatusFromCppWithString(statusUpdateMessage.c_str());
-    }
-    catch (...)
-    {
-      printf("Error while handling string message to web\n");
-    }
-  }
-
-  void WasmPlatformApplicationAdapter::NotifyStatusUpdateFromCppToWebWithSerializedMessage(const std::string& statusUpdateMessage)
-  {
-    try
-    {
-      UpdateStoneApplicationStatusFromCppWithSerializedMessage(statusUpdateMessage.c_str());
-    }
-    catch (...)
-    {
-      printf("Error while handling serialized message to web\n");
-    }
-  }
-
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/WasmPlatformApplicationAdapter.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include <string>
-#include "../../../Framework/Messages/IObserver.h"
-#include <Applications/IStoneApplication.h>
-
-namespace OrthancStone
-{
-  class WasmPlatformApplicationAdapter : public IObserver
-  {
-      IStoneApplication&  application_;
-    public:
-      WasmPlatformApplicationAdapter(MessageBroker& broker, IStoneApplication& application);
-
-      virtual void HandleSerializedMessageFromWeb(std::string& output, const std::string& input);
-      virtual void NotifyStatusUpdateFromCppToWebWithString(const std::string& statusUpdateMessage);
-      virtual void NotifyStatusUpdateFromCppToWebWithSerializedMessage(const std::string& statusUpdateMessage);
-  };
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/WasmViewport.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "WasmViewport.h"
-
-#include <vector>
-#include <memory>
-
-std::vector<std::shared_ptr<Deprecated::WidgetViewport>> wasmViewports;
-
-void AttachWidgetToWasmViewport(const char* htmlCanvasId, Deprecated::IWidget* centralWidget) {
-    std::shared_ptr<Deprecated::WidgetViewport> viewport(CreateWasmViewportFromCpp(htmlCanvasId));
-    viewport->SetCentralWidget(centralWidget);
-
-    wasmViewports.push_back(viewport);
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/WasmViewport.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Framework/Deprecated/Viewport/WidgetViewport.h"
-
-#include <emscripten/emscripten.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-  // JS methods accessible from C++
-  extern Deprecated::WidgetViewport* CreateWasmViewportFromCpp(const char* htmlCanvasId);
-
-#ifdef __cplusplus
-}
-#endif
-
-extern void AttachWidgetToWasmViewport(const char* htmlCanvasId, Deprecated::IWidget* centralWidget);
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/WasmWebService.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "WasmWebService.h"
-#include "json/value.h"
-#include "json/writer.h"
-#include <emscripten/emscripten.h>
-#include <boost/shared_ptr.hpp>
-
-struct CachedSuccessNotification
-{
-  boost::shared_ptr<Deprecated::BaseWebService::CachedHttpRequestSuccessMessage>    cachedMessage;
-  std::unique_ptr<Orthanc::IDynamicObject>                                              payload;
-  OrthancStone::MessageHandler<Deprecated::IWebService::HttpRequestSuccessMessage>* successCallback;
-};
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-  extern void WasmWebService_GetAsync(void* callableSuccess,
-                                      void* callableFailure,
-                                      const char* uri,
-                                      const char* headersInJsonString,
-                                      void* payload,
-                                      unsigned int timeoutInSeconds);
-
-  extern void WasmWebService_ScheduleLaterCachedSuccessNotification(void* brol);
-
-  extern void WasmWebService_PostAsync(void* callableSuccess,
-                                       void* callableFailure,
-                                       const char* uri,
-                                       const char* headersInJsonString,
-                                       const void* body,
-                                       size_t bodySize,
-                                       void* payload,
-                                       unsigned int timeoutInSeconds);
-
-  extern void WasmWebService_DeleteAsync(void* callableSuccess,
-                                         void* callableFailure,
-                                         const char* uri,
-                                         const char* headersInJsonString,
-                                         void* payload,
-                                         unsigned int timeoutInSeconds);
-
-  void EMSCRIPTEN_KEEPALIVE WasmWebService_NotifyError(void* failureCallable,
-                                                       const char* uri,
-                                                       unsigned int httpStatus,
-                                                       void* payload)
-  {
-    if (failureCallable != NULL)
-    {
-      reinterpret_cast<OrthancStone::MessageHandler<Deprecated::IWebService::HttpRequestErrorMessage>*>(failureCallable)->
-        Apply(Deprecated::IWebService::HttpRequestErrorMessage(uri, static_cast<Orthanc::HttpStatus>(httpStatus), reinterpret_cast<Orthanc::IDynamicObject*>(payload)));
-    }
-  }
-
-  void EMSCRIPTEN_KEEPALIVE WasmWebService_NotifyCachedSuccess(void* notification_)
-  {
-    // notification has been allocated in C++ and passed to JS.  It must be deleted by this method
-    std::unique_ptr<CachedSuccessNotification> notification(reinterpret_cast<CachedSuccessNotification*>(notification_));
-
-    notification->successCallback->Apply(Deprecated::IWebService::HttpRequestSuccessMessage(
-      notification->cachedMessage->GetUri(), 
-      notification->cachedMessage->GetAnswer(),
-      notification->cachedMessage->GetAnswerSize(),
-      notification->cachedMessage->GetAnswerHttpHeaders(),
-      notification->payload.get()
-      ));
-  }
-
-  void EMSCRIPTEN_KEEPALIVE WasmWebService_NotifySuccess(void* successCallable,
-                                                         const char* uri,
-                                                         const void* body,
-                                                         size_t bodySize,
-                                                         const char* answerHeaders,
-                                                         void* payload)
-  {
-    if (successCallable != NULL)
-    {
-      Deprecated::IWebService::HttpHeaders headers;
-
-      // TODO - Parse "answerHeaders"
-      //printf("TODO: parse headers [%s]\n", answerHeaders);
-      
-      reinterpret_cast<OrthancStone::MessageHandler<Deprecated::IWebService::HttpRequestSuccessMessage>*>(successCallable)->
-        Apply(Deprecated::IWebService::HttpRequestSuccessMessage(uri, body, bodySize, headers,
-                                                                   reinterpret_cast<Orthanc::IDynamicObject*>(payload)));
-    }
-  }
-
-#ifdef __cplusplus
-}
-#endif
-
-
-
-namespace Deprecated
-{
-  OrthancStone::MessageBroker* WasmWebService::broker_ = NULL;
-
-  void ToJsonString(std::string& output, const IWebService::HttpHeaders& headers)
-  {
-    Json::Value jsonHeaders;
-    for (IWebService::HttpHeaders::const_iterator it = headers.begin(); it != headers.end(); it++ )
-    {
-      jsonHeaders[it->first] = it->second;
-    }
-
-    Json::StreamWriterBuilder builder;
-    std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
-    std::ostringstream outputStr;
-
-    writer->write(jsonHeaders, &outputStr);
-    output = outputStr.str();
-  }
-
-  void WasmWebService::PostAsync(const std::string& relativeUri,
-                                 const HttpHeaders& headers,
-                                 const std::string& body,
-                                 Orthanc::IDynamicObject* payload,
-                                 OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallable,
-                                 OrthancStone::MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallable,
-                                 unsigned int timeoutInSeconds)
-  {
-    std::string headersInJsonString;
-    ToJsonString(headersInJsonString, headers);
-    WasmWebService_PostAsync(successCallable, failureCallable, relativeUri.c_str(), headersInJsonString.c_str(),
-                             body.c_str(), body.size(), payload, timeoutInSeconds);
-  }
-
-  void WasmWebService::DeleteAsync(const std::string& relativeUri,
-                                   const HttpHeaders& headers,
-                                   Orthanc::IDynamicObject* payload,
-                                   OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallable,
-                                   OrthancStone::MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallable,
-                                   unsigned int timeoutInSeconds)
-  {
-    std::string headersInJsonString;
-    ToJsonString(headersInJsonString, headers);
-    WasmWebService_DeleteAsync(successCallable, failureCallable, relativeUri.c_str(), headersInJsonString.c_str(),
-                               payload, timeoutInSeconds);
-  }
-
-  void WasmWebService::GetAsyncInternal(const std::string &relativeUri,
-                                        const HttpHeaders &headers,
-                                        Orthanc::IDynamicObject *payload,
-                                        OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage> *successCallable,
-                                        OrthancStone::MessageHandler<IWebService::HttpRequestErrorMessage> *failureCallable,
-                                        unsigned int timeoutInSeconds)
-  {
-    std::string headersInJsonString;
-    ToJsonString(headersInJsonString, headers);
-    WasmWebService_GetAsync(successCallable, failureCallable, relativeUri.c_str(),
-                            headersInJsonString.c_str(), payload, timeoutInSeconds);
-  }
-
-  void WasmWebService::NotifyHttpSuccessLater(boost::shared_ptr<BaseWebService::CachedHttpRequestSuccessMessage> cachedMessage,
-                                              Orthanc::IDynamicObject* payload, // takes ownership
-                                              OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback)
-  {
-    CachedSuccessNotification* notification = new CachedSuccessNotification();  // allocated on the heap, it will be passed to JS and deleted when coming back to C++
-    notification->cachedMessage = cachedMessage;
-    notification->payload.reset(payload);
-    notification->successCallback = successCallback;
-
-    WasmWebService_ScheduleLaterCachedSuccessNotification(notification);
-  }
-
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/WasmWebService.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Framework/Deprecated/Toolbox/BaseWebService.h"
-#include <Core/OrthancException.h>
-
-namespace Deprecated
-{
-class WasmWebService : public BaseWebService
-{
-private:
-  static OrthancStone::MessageBroker *broker_;
-
-  // Private constructor => Singleton design pattern
-  WasmWebService(OrthancStone::MessageBroker &broker) : BaseWebService(broker)
-  {
-  }
-
-public:
-  static WasmWebService &GetInstance()
-  {
-    if (broker_ == NULL)
-    {
-      printf("WasmWebService::GetInstance(): broker not initialized\n");
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-    static WasmWebService instance(*broker_);
-    return instance;
-  }
-
-  static void SetBroker(OrthancStone::MessageBroker &broker)
-  {
-    broker_ = &broker;
-  }
-
-  virtual void PostAsync(const std::string &uri,
-                         const HttpHeaders &headers,
-                         const std::string &body,
-                         Orthanc::IDynamicObject *payload,
-                         OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage> *successCallable,
-                         OrthancStone::MessageHandler<IWebService::HttpRequestErrorMessage> *failureCallable = NULL,
-                         unsigned int timeoutInSeconds = 60);
-
-  virtual void DeleteAsync(const std::string &uri,
-                           const HttpHeaders &headers,
-                           Orthanc::IDynamicObject *payload,
-                           OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage> *successCallable,
-                           OrthancStone::MessageHandler<IWebService::HttpRequestErrorMessage> *failureCallable = NULL,
-                           unsigned int timeoutInSeconds = 60);
-
-protected:
-  virtual void GetAsyncInternal(const std::string &uri,
-                                const HttpHeaders &headers,
-                                Orthanc::IDynamicObject *payload,
-                                OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage> *successCallable,
-                                OrthancStone::MessageHandler<IWebService::HttpRequestErrorMessage> *failureCallable = NULL,
-                                unsigned int timeoutInSeconds = 60);
-
-  virtual void NotifyHttpSuccessLater(boost::shared_ptr<BaseWebService::CachedHttpRequestSuccessMessage> cachedHttpMessage,
-                                      Orthanc::IDynamicObject *payload, // takes ownership
-                                      OrthancStone::MessageHandler<IWebService::HttpRequestSuccessMessage> *successCallback);
-};
-} // namespace Deprecated
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/WasmWebService.js	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-mergeInto(LibraryManager.library, {
-  WasmWebService_GetAsync: function(callableSuccess, callableFailure, url, headersInJsonString, payload, timeoutInSeconds) {
-    // Directly use XMLHttpRequest (no jQuery) to retrieve the raw binary data
-    // http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/
-    var xhr = new XMLHttpRequest();
-    var url_ = UTF8ToString(url);
-    var headersInJsonString_ = UTF8ToString(headersInJsonString);
-
-    xhr.open('GET', url_, true);
-    xhr.responseType = 'arraybuffer';
-    xhr.timeout = timeoutInSeconds * 1000;
-    var headers = JSON.parse(headersInJsonString_);
-    for (var key in headers) {
-      xhr.setRequestHeader(key, headers[key]);
-    }
-    //console.log(xhr); 
-    xhr.onreadystatechange = function() {
-      if (this.readyState == XMLHttpRequest.DONE) {
-        if (xhr.status === 200) {
-          var s = xhr.getAllResponseHeaders();
-          var headers = _malloc(s.length + 1);
-          stringToUTF8(s, headers, s.length + 1);
-          
-          // TODO - Is "new Uint8Array()" necessary? This copies the
-          // answer to the WebAssembly stack, hence necessitating
-          // increasing the TOTAL_STACK parameter of Emscripten
-          window.WasmWebService_NotifySuccess(callableSuccess, url_, new Uint8Array(this.response),
-                                       this.response.byteLength, headers, payload);
-        } else {
-          window.WasmWebService_NotifyError(callableFailure, url_, xhr.status, payload);
-        }
-      }
-    }
-    
-    xhr.send();
-  },
-
-  WasmWebService_ScheduleLaterCachedSuccessNotification: function (brol) {
-    setTimeout(function() {
-      window.WasmWebService_NotifyCachedSuccess(brol);
-    }, 0);
-  },
-
-  WasmWebService_PostAsync: function(callableSuccess, callableFailure, url, headersInJsonString, body, bodySize, payload, timeoutInSeconds) {
-    var xhr = new XMLHttpRequest();
-    var url_ = UTF8ToString(url);
-    var headersInJsonString_ = UTF8ToString(headersInJsonString);
-    xhr.open('POST', url_, true);
-    xhr.timeout = timeoutInSeconds * 1000;
-    xhr.responseType = 'arraybuffer';
-    xhr.setRequestHeader('Content-type', 'application/octet-stream');
-
-    var headers = JSON.parse(headersInJsonString_);
-    for (var key in headers) {
-      xhr.setRequestHeader(key, headers[key]);
-    }
-    
-    xhr.onreadystatechange = function() {
-      if (this.readyState == XMLHttpRequest.DONE) {
-        if (xhr.status === 200) {
-          var s = xhr.getAllResponseHeaders();
-          var headers = _malloc(s.length + 1);
-          stringToUTF8(s, headers, s.length + 1);
-
-          window.WasmWebService_NotifySuccess(callableSuccess, url_, new Uint8Array(this.response),
-                                       this.response.byteLength, headers, payload);
-        } else {
-          window.WasmWebService_NotifyError(callableFailure, url_, xhr.status, payload);
-        }
-      }
-    }
-
-    xhr.send(new Uint8ClampedArray(HEAPU8.buffer, body, bodySize));
-  },
-
-  WasmWebService_DeleteAsync: function(callableSuccess, callableFailure, url, headersInJsonString, payload, timeoutInSeconds) {
-    var xhr = new XMLHttpRequest();
-    var url_ = UTF8ToString(url);
-    var headersInJsonString_ = UTF8ToString(headersInJsonString);
-    xhr.open('DELETE', url_, true);
-    xhr.timeout = timeoutInSeconds * 1000;
-    xhr.responseType = 'arraybuffer';
-    xhr.setRequestHeader('Content-type', 'application/octet-stream');
-  
-    var headers = JSON.parse(headersInJsonString_);
-    for (var key in headers) {
-      xhr.setRequestHeader(key, headers[key]);
-    }
-    
-    xhr.onreadystatechange = function() {
-      if (this.readyState == XMLHttpRequest.DONE) {
-        if (xhr.status === 200) {
-          var s = xhr.getAllResponseHeaders();
-          var headers = _malloc(s.length + 1);
-          stringToUTF8(s, headers, s.length + 1);
-
-          window.WasmWebService_NotifySuccess(callableSuccess, url_, new Uint8Array(this.response),
-                                       this.response.byteLength, headers, payload);
-        } else {
-          window.WasmWebService_NotifyError(callableFailure, url_, xhr.status, payload);
-        }
-      }
-    }
-  
-    xhr.send();
-  }
-  
-});
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/default-library.js	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-// this file contains the JS method you want to expose to C++ code
-
-mergeInto(LibraryManager.library, {
-
-  ScheduleWebViewportRedrawFromCpp: function(cppViewportHandle) {
-    window.ScheduleWebViewportRedraw(cppViewportHandle);
-  },
-
-  CreateWasmViewportFromCpp: function(htmlCanvasId) {
-    return window.CreateWasmViewport(htmlCanvasId);
-  },
-
-  // each time the StoneApplication updates its status, it may signal it 
-  // through this method. i.e, to change the status of a button in the web interface
-  UpdateStoneApplicationStatusFromCppWithString: function(statusUpdateMessage) {
-    var statusUpdateMessage_ = UTF8ToString(statusUpdateMessage);
-    window.UpdateWebApplicationWithString(statusUpdateMessage_);
-  },
-
-  // same, but with a serialized message
-  UpdateStoneApplicationStatusFromCppWithSerializedMessage: function(statusUpdateMessage) {
-    var statusUpdateMessage_ = UTF8ToString(statusUpdateMessage);
-    window.UpdateWebApplicationWithSerializedMessage(statusUpdateMessage_);
-  },
-
-  // These functions are called from C++ (through an extern declaration) 
-  // and call the standard logger that, here, routes to the console.
-
-  stone_console_error : function(message) {
-    var text = UTF8ToString(message);
-    window.errorFromCpp(text);
-  },
-
-  stone_console_warning : function(message) {
-    var text = UTF8ToString(message);
-    window.warningFromCpp(text);
-  },
-
-  stone_console_info: function(message) {
-    var text = UTF8ToString(message);
-    window.infoFromCpp(text);
-  },
-  
-  stone_console_trace : function(message) {
-    var text = UTF8ToString(message);
-    window.debugFromCpp(text);
-  }
-
-});
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/logger.ts	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-export enum LogSource {
-  Cpp,
-  Typescript
-}
-
-export class StandardConsoleLogger {
-  public showSource: boolean = true;
-
-  public debug(...args: any[]): void {
-    this._debug(LogSource.Typescript, ...args);
-  }
-
-  public debugFromCpp(...args: any[]): void {
-    this._debug(LogSource.Cpp, ...args);
-  }
-
-  public info(...args: any[]): void {
-    this._info(LogSource.Typescript, ...args);
-  }
-
-  public infoFromCpp(message: string): void {
-    this._info(LogSource.Cpp, message);
-  }
-
-  public warning(...args: any[]): void {
-    this._warning(LogSource.Typescript, ...args);
-  }
-
-  public warningFromCpp(message: string): void {
-    this._warning(LogSource.Cpp, message);
-  }
-
-  public error(...args: any[]): void {
-    this._error(LogSource.Typescript, ...args);
-  }
-
-  public errorFromCpp(message: string): void {
-    this._error(LogSource.Cpp, message);
-  }
-
-  public _debug(source: LogSource, ...args: any[]): void {
-    if ((<any> window).IsTraceLevelEnabled)
-    {
-      if ((<any> window).IsTraceLevelEnabled())
-      {
-        var output = this.getOutput(source, args);
-        console.debug(...output);
-      }
-    }
-  }
-
-  private _info(source: LogSource, ...args: any[]): void {
-    if ((<any> window).IsInfoLevelEnabled)
-    {
-      if ((<any> window).IsInfoLevelEnabled())
-      {
-        var output = this.getOutput(source, args);
-        console.info(...output);
-      }
-    }
-  }
-
-  public _warning(source: LogSource, ...args: any[]): void {
-    var output = this.getOutput(source, args);
-    console.warn(...output);
-  }
-
-  public _error(source: LogSource, ...args: any[]): void {
-    var output = this.getOutput(source, args);
-    console.error(...output);
-  }
-
-
-  private getOutput(source: LogSource, args: any[]): any[] {
-    var prefix = this.getPrefix();
-    var prefixAndSource = Array<string>();
-
-    if (prefix != null) {
-      prefixAndSource = [prefix];
-    } 
-
-    if (this.showSource) {
-      if (source == LogSource.Typescript) {
-        prefixAndSource = [...prefixAndSource, "TS "];
-      } else if (source == LogSource.Cpp) {
-        prefixAndSource = [...prefixAndSource, "C++"];
-      }
-    }
-
-    if (prefixAndSource.length > 0) {
-      prefixAndSource = [...prefixAndSource, "|"];
-    }
-
-    return [...prefixAndSource, ...args];
-  }
-
-  protected getPrefix(): string | null {
-    return null;
-  }
-}
-
-export class TimeConsoleLogger extends StandardConsoleLogger {
-  protected getPrefix(): string {
-    let now = new Date();
-    let timeString = now.getHours().toString().padStart(2, "0") + ":" + now.getMinutes().toString().padStart(2, "0") + ":" + now.getSeconds().toString().padStart(2, "0") + "." + now.getMilliseconds().toString().padStart(3, "0");
-    return timeString;
-  }
-}
-
-export var defaultLogger: StandardConsoleLogger = new TimeConsoleLogger();
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/stone-framework-loader.ts	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/**
- * This file contains primitives to interface with WebAssembly and
- * with the Stone framework.
- **/
-import * as Logger from './logger'
-
-export declare type InitializationCallback = () => void;
-
-//export declare var StoneFrameworkModule : any;
-export var StoneFrameworkModule : any;
-
-//const ASSETS_FOLDER : string = "assets/lib";
-//const WASM_FILENAME : string = "orthanc-framework";
-
-export class Framework
-{
-  private static singleton_ : Framework = null;
-  private static wasmModuleName_ : string = null;
-
-  public static Configure(wasmModuleName: string) {
-    this.wasmModuleName_ = wasmModuleName;
-  }
-
-  private constructor(verbose : boolean) 
-  {
-    //this.ccall('Initialize', null, [ 'number' ], [ verbose ]);
-  }
-
-  
-  public ccall( name: string,
-                returnType: string,
-                argTypes: Array<string>,
-                argValues: Array<any>) : any
-  {
-    return (<any> window).StoneFrameworkModule.ccall(name, returnType, argTypes, argValues);
-  }
-
-  
-  public cwrap( name: string,
-                returnType: string,
-                argTypes: Array<string>) : any
-  {
-    return (<any> window).StoneFrameworkModule.cwrap(name, returnType, argTypes);
-  }
-
-  
-  public static GetInstance() : Framework
-  {
-    if (Framework.singleton_ == null) {
-      throw new Error('The WebAssembly module is not loaded yet');
-    } else {
-      return Framework.singleton_;
-    }
-  }
-
-
-  public static Initialize( verbose: boolean,
-                            callback: InitializationCallback)
-  {
-    Logger.defaultLogger.debug('Initializing WebAssembly Module');
-
-    (<any> window).errorFromCpp = function(text:any) { Logger.defaultLogger.errorFromCpp(text); };
-    (<any> window).warningFromCpp = function(text:any) { Logger.defaultLogger.warningFromCpp(text); };
-    (<any> window).infoFromCpp = function(text:any) { Logger.defaultLogger.infoFromCpp(text); };
-    (<any> window).debugFromCpp = function(text:any) { Logger.defaultLogger.debugFromCpp(text); };
-
-    // (<any> window).
-    (<any> window).StoneFrameworkModule = {
-      preRun: [ 
-        function() {
-          Logger.defaultLogger.debug('Loading the Stone Framework using WebAssembly');
-        }
-      ],
-      postRun: [ 
-        function()  {
-          // This function is called by ".js" wrapper once the ".wasm"
-          // WebAssembly module has been loaded and compiled by the
-          // browser
-          Logger.defaultLogger.debug('WebAssembly is ready');
-          Framework.singleton_ = new Framework(verbose);
-          callback();
-        }
-      ],
-      totalDependencies: 0
-    };
-
-    // Dynamic loading of the JavaScript wrapper around WebAssembly
-    var script = document.createElement('script');
-    script.type = 'application/javascript';
-    //script.src = "orthanc-stone.js"; // ASSETS_FOLDER + '/' + WASM_FILENAME + '.js';
-    script.src = this.wasmModuleName_ + ".js";//  "OrthancStoneSimpleViewer.js"; // ASSETS_FOLDER + '/' + WASM_FILENAME + '.js';
-    script.async = true;
-    document.head.appendChild(script);
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/tsconfig-stone.json	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-{
-    "include" : [
-        "stone-framework-loader.ts",
-        "logger.ts",
-        "wasm-application-runner.ts",
-        "wasm-viewport.ts"
-    ]
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/wasm-application-runner.ts	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,141 +0,0 @@
-import * as Stone from './stone-framework-loader'
-import * as StoneViewport from './wasm-viewport'
-import * as Logger from './logger'
-
-if (!('WebAssembly' in window)) {
-  alert('Sorry, your browser does not support WebAssembly :(');
-}
-
-//var StoneFrameworkModule : Stone.Framework = (<any>window).StoneFrameworkModule;
-//export declare var StoneFrameworkModule : Stone.Framework;
-
-// global functions
-var WasmWebService_NotifyError: Function = null;
-var WasmWebService_NotifySuccess: Function = null;
-var WasmWebService_NotifyCachedSuccess: Function = null;
-var WasmDelayedCallExecutor_ExecuteCallback: Function = null;
-var WasmDoAnimation: Function = null;
-var SetStartupParameter: Function = null;
-var CreateWasmApplication: Function = null;
-export var CreateCppViewport: Function = null;
-var ReleaseCppViewport: Function = null;
-var StartWasmApplication: Function = null;
-export var SendSerializedMessageToStoneApplication: Function = null;
-
-var auxiliaryParameters : Map<string,string>  = null;
-
-export function SetApplicationParameters(params : Map<string,string>) {
-  if (auxiliaryParameters != null) {
-    console.warn("wasm-application-runner.SetApplicationParameters: about to overwrite the existing application parameters!")
-  }
-  auxiliaryParameters = params;
-}
-
-function DoAnimationThread() {
-  if (WasmDoAnimation != null) {
-    WasmDoAnimation();
-  }
-
-  // Update the viewport content every 100ms if need be
-  setTimeout(DoAnimationThread, 100);  
-}
-
-
-function GetUriParameters(): Map<string, string> {
-  var parameters = window.location.search.substr(1);
-
-  if (parameters != null &&
-    parameters != '') {
-    var result = new Map<string, string>();
-    var tokens = parameters.split('&');
-
-    for (var i = 0; i < tokens.length; i++) {
-      var tmp = tokens[i].split('=');
-      if (tmp.length == 2) {
-        result[tmp[0]] = decodeURIComponent(tmp[1]);
-      } else if(tmp.length == 1) {
-        // if there is no '=', we treat ot afterwards as a flag-style param
-        result[tmp[0]] = "";
-      }
-    }
-  return result;
-  }
-  else {
-    return new Map<string, string>();
-  }
-}
-
-// function UpdateWebApplication(statusUpdateMessage: string) {
-//   console.log(statusUpdateMessage);
-// }
-
-function _InitializeWasmApplication(orthancBaseUrl: string): void {
-
-  CreateWasmApplication();
-
-  // transmit the API-specified parameters to the app before initializing it
-  for (let key in auxiliaryParameters) {
-    if (auxiliaryParameters.hasOwnProperty(key)) {
-      Logger.defaultLogger.debug(
-        `About to call SetStartupParameter("${key}","${auxiliaryParameters[key]}")`);
-      SetStartupParameter(key, auxiliaryParameters[key]);
-    }
-  }
-
-  // parse uri and transmit the URI parameters to the app before initializing it
-  let parameters = GetUriParameters();
-
-  for (let key in parameters) {
-    if (parameters.hasOwnProperty(key)) {
-      Logger.defaultLogger.debug(
-        `About to call SetStartupParameter("${key}","${parameters[key]}")`);
-      SetStartupParameter(key, parameters[key]);
-    }
-  }
-
-  StartWasmApplication(orthancBaseUrl);
-
-  // trigger a first resize of the canvas that has just been initialized
-  StoneViewport.WasmViewport.ResizeAll();
-
-  DoAnimationThread();
-}
-
-export function InitializeWasmApplication(wasmModuleName: string, orthancBaseUrl: string) {
-  
-  Stone.Framework.Configure(wasmModuleName);
-
-  // Wait for the Orthanc Framework to be initialized (this initializes
-  // the WebAssembly environment) and then, create and initialize the Wasm application
-  Stone.Framework.Initialize(true, function () {
-
-    Logger.defaultLogger.debug("Connecting C++ methods to JS methods");
-    
-    SetStartupParameter = (<any> window).StoneFrameworkModule.cwrap('SetStartupParameter', null, ['string', 'string']);
-    CreateWasmApplication = (<any> window).StoneFrameworkModule.cwrap('CreateWasmApplication', null, ['number']);
-    CreateCppViewport = (<any> window).StoneFrameworkModule.cwrap('CreateCppViewport', 'number', []);
-    ReleaseCppViewport = (<any> window).StoneFrameworkModule.cwrap('ReleaseCppViewport', null, ['number']);
-    StartWasmApplication = (<any> window).StoneFrameworkModule.cwrap('StartWasmApplication', null, ['string']);
-    (<any> window).IsTraceLevelEnabled = (<any> window).StoneFrameworkModule.cwrap('WasmIsTraceLevelEnabled', 'boolean', null);
-    (<any> window).IsInfoLevelEnabled = (<any> window).StoneFrameworkModule.cwrap('WasmIsInfoLevelEnabled', 'boolean', null);
-
-    (<any> window).WasmWebService_NotifyCachedSuccess = (<any> window).StoneFrameworkModule.cwrap('WasmWebService_NotifyCachedSuccess', null, ['number']);
-    (<any> window).WasmWebService_NotifySuccess = (<any> window).StoneFrameworkModule.cwrap('WasmWebService_NotifySuccess', null, ['number', 'string', 'array', 'number', 'number']);
-    (<any> window).WasmWebService_NotifyError = (<any> window).StoneFrameworkModule.cwrap('WasmWebService_NotifyError', null, ['number', 'string', 'number', 'number']);
-    (<any> window).WasmDelayedCallExecutor_ExecuteCallback = (<any> window).StoneFrameworkModule.cwrap('WasmDelayedCallExecutor_ExecuteCallback', null, ['number']);
-    // no need to put this into the globals for it's only used in this very module
-    WasmDoAnimation = (<any> window).StoneFrameworkModule.cwrap('WasmDoAnimation', null, []);
-
-    SendSerializedMessageToStoneApplication = (<any> window).StoneFrameworkModule.cwrap('SendSerializedMessageToStoneApplication', 'string', ['string']);
-
-    Logger.defaultLogger.debug("Connecting C++ methods to JS methods - done");
-
-    _InitializeWasmApplication(orthancBaseUrl);
-  });
-}
-
-
-// exports.InitializeWasmApplication = InitializeWasmApplication;
-
-
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Platforms/Wasm/wasm-viewport.ts	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,359 +0,0 @@
-import * as wasmApplicationRunner from './wasm-application-runner'
-import * as Logger from './logger'
-
-var isPendingRedraw = false;
-
-function ScheduleWebViewportRedraw(cppViewportHandle: any) : void
-{
-  if (!isPendingRedraw) {
-    isPendingRedraw = true;
-    Logger.defaultLogger.debug('Scheduling a refresh of the viewport, as its content changed');
-    window.requestAnimationFrame(function() {
-      isPendingRedraw = false;
-      let viewport = WasmViewport.GetFromCppViewport(cppViewportHandle);
-      if (viewport) {
-        viewport.Redraw();
-      }
-    });
-  }
-}
-
-(<any>window).ScheduleWebViewportRedraw = ScheduleWebViewportRedraw;
-
-declare function UTF8ToString(v: any): string;
-
-function CreateWasmViewport(htmlCanvasId: string) : any {
-  var cppViewportHandle = wasmApplicationRunner.CreateCppViewport();
-  var canvasId = UTF8ToString(htmlCanvasId);
-  var webViewport = new WasmViewport((<any> window).StoneFrameworkModule, canvasId, cppViewportHandle);  // viewports are stored in a static map in WasmViewport -> won't be deleted
-  webViewport.Initialize();
-
-  return cppViewportHandle;
-}
- 
-(<any>window).CreateWasmViewport = CreateWasmViewport;
-
-export class WasmViewport {
-
-    private static viewportsMapByCppHandle_ : Map<number, WasmViewport> = new Map<number, WasmViewport>(); // key = the C++ handle
-    private static viewportsMapByCanvasId_ : Map<string, WasmViewport> = new Map<string, WasmViewport>(); // key = the canvasId
-
-    private module_ : any;
-    private canvasId_ : string;
-    private htmlCanvas_ : HTMLCanvasElement;
-    private context_ : CanvasRenderingContext2D | null;
-    private imageData_ : any = null;
-    private renderingBuffer_ : any = null;
-    
-    private touchGestureInProgress_: boolean = false;
-    private touchCount_: number = 0;
-    private touchGestureLastCoordinates_: [number, number][] = []; // last x,y coordinates of each touch
-    
-    private touchZoom_ : any = false;
-    private touchTranslation_ : any = false;
-
-    private ViewportSetSize : Function;
-    private ViewportRender : Function;
-    private ViewportMouseDown : Function;
-    private ViewportMouseMove : Function;
-    private ViewportMouseUp : Function;
-    private ViewportMouseEnter : Function;
-    private ViewportMouseLeave : Function;
-    private ViewportMouseWheel : Function;
-    private ViewportKeyPressed : Function;
-    private ViewportTouchStart : Function;
-    private ViewportTouchMove : Function;
-    private ViewportTouchEnd : Function;
-
-    private pimpl_ : any; // Private pointer to the underlying WebAssembly C++ object
-
-    public constructor(module: any, canvasId: string, cppViewport: any) {
-      
-      this.pimpl_ = cppViewport;
-      WasmViewport.viewportsMapByCppHandle_[this.pimpl_] = this;
-      WasmViewport.viewportsMapByCanvasId_[canvasId] = this;
-
-      this.module_ = module;
-      this.canvasId_ = canvasId;
-      this.htmlCanvas_ = document.getElementById(this.canvasId_) as HTMLCanvasElement;
-      if (this.htmlCanvas_ == null) {
-        Logger.defaultLogger.error("Can not create WasmViewport, did not find the canvas whose id is '", this.canvasId_, "'");
-      }
-      this.context_ = this.htmlCanvas_.getContext('2d');
-
-      this.ViewportSetSize = this.module_.cwrap('ViewportSetSize', null, [ 'number', 'number', 'number' ]);
-      this.ViewportRender = this.module_.cwrap('ViewportRender', null, [ 'number', 'number', 'number', 'number' ]);
-      this.ViewportMouseDown = this.module_.cwrap('ViewportMouseDown', null, [ 'number', 'number', 'number', 'number', 'number' ]);
-      this.ViewportMouseMove = this.module_.cwrap('ViewportMouseMove', null, [ 'number', 'number', 'number' ]);
-      this.ViewportMouseUp = this.module_.cwrap('ViewportMouseUp', null, [ 'number' ]);
-      this.ViewportMouseEnter = this.module_.cwrap('ViewportMouseEnter', null, [ 'number' ]);
-      this.ViewportMouseLeave = this.module_.cwrap('ViewportMouseLeave', null, [ 'number' ]);
-      this.ViewportMouseWheel = this.module_.cwrap('ViewportMouseWheel', null, [ 'number', 'number', 'number', 'number', 'number' ]);
-      this.ViewportKeyPressed = this.module_.cwrap('ViewportKeyPressed', null, [ 'number', 'number', 'string', 'number', 'number' ]);
-      this.ViewportTouchStart = this.module_.cwrap('ViewportTouchStart', null, [ 'number', 'number', 'number', 'number', 'number', 'number', 'number' ]);
-      this.ViewportTouchMove = this.module_.cwrap('ViewportTouchMove', null, [ 'number', 'number', 'number', 'number', 'number', 'number', 'number' ]);
-      this.ViewportTouchEnd = this.module_.cwrap('ViewportTouchEnd', null, [ 'number', 'number', 'number', 'number', 'number', 'number', 'number' ]);
-    }
-
-    public GetCppViewport() : number {
-      return this.pimpl_;
-    }
-
-    public static GetFromCppViewport(cppViewportHandle: number) : WasmViewport | null {
-      if (WasmViewport.viewportsMapByCppHandle_[cppViewportHandle] !== undefined) {
-        return WasmViewport.viewportsMapByCppHandle_[cppViewportHandle];
-      }
-      Logger.defaultLogger.error("WasmViewport not found !");
-      return null;
-    }
-
-    public static GetFromCanvasId(canvasId: string) : WasmViewport | null {
-      if (WasmViewport.viewportsMapByCanvasId_[canvasId] !== undefined) {
-        return WasmViewport.viewportsMapByCanvasId_[canvasId];
-      }
-      Logger.defaultLogger.error("WasmViewport not found !");
-      return null;
-    }
-
-    public static ResizeAll() {
-      for (let canvasId in WasmViewport.viewportsMapByCanvasId_) {
-        WasmViewport.viewportsMapByCanvasId_[canvasId].Resize();
-      }
-    }
-
-    public Redraw() {
-      if (this.imageData_ === null ||
-          this.renderingBuffer_ === null ||
-          this.ViewportRender(this.pimpl_,
-                         this.imageData_.width,
-                         this.imageData_.height,
-                         this.renderingBuffer_) == 0) {
-        Logger.defaultLogger.error('The rendering has failed');
-      } else {
-        // Create an accessor to the rendering buffer (i.e. create a
-        // "window" above the heap of the WASM module), then copy it to
-        // the ImageData object
-        this.imageData_.data.set(new Uint8ClampedArray(
-          this.module_.HEAPU8.buffer,
-          this.renderingBuffer_,
-          this.imageData_.width * this.imageData_.height * 4));
-        
-        if (this.context_) {
-          this.context_.putImageData(this.imageData_, 0, 0);
-        }
-      }
-    }
-  
-    public Resize() {
-      if (this.imageData_ != null &&
-          (this.imageData_.width != window.innerWidth ||
-           this.imageData_.height != window.innerHeight)) {
-        this.imageData_ = null;
-      }
-      
-      // width/height is defined by the parent width/height
-      if (this.htmlCanvas_.parentElement) {
-        this.htmlCanvas_.width = this.htmlCanvas_.parentElement.offsetWidth;  
-        this.htmlCanvas_.height = this.htmlCanvas_.parentElement.offsetHeight;  
-
-        Logger.defaultLogger.debug("resizing WasmViewport: ", this.htmlCanvas_.width, "x", this.htmlCanvas_.height);
-
-        if (this.imageData_ === null && this.context_) {
-          this.imageData_ = this.context_.getImageData(0, 0, this.htmlCanvas_.width, this.htmlCanvas_.height);
-          this.ViewportSetSize(this.pimpl_, this.htmlCanvas_.width, this.htmlCanvas_.height);
-    
-          if (this.renderingBuffer_ != null) {
-            this.module_._free(this.renderingBuffer_);
-          }
-          
-          this.renderingBuffer_ = this.module_._malloc(this.imageData_.width * this.imageData_.height * 4);
-        } else {
-          this.ViewportSetSize(this.pimpl_, this.htmlCanvas_.width, this.htmlCanvas_.height);
-        }
-        
-        this.Redraw();
-      }
-    }
-
-    public Initialize() {
-      
-      // Force the rendering of the viewport for the first time
-      this.Resize();
-    
-      var that : WasmViewport = this;
-      // Register an event listener to call the Resize() function 
-      // each time the window is resized.
-      window.addEventListener('resize', function(event) {
-        that.Resize();
-      }, false);
-  
-      this.htmlCanvas_.addEventListener('contextmenu', function(event) {
-        // Prevent right click on the canvas
-        event.preventDefault();
-      }, false);
-      
-      this.htmlCanvas_.addEventListener('mouseleave', function(event) {
-        that.ViewportMouseLeave(that.pimpl_);
-      });
-      
-      this.htmlCanvas_.addEventListener('mouseenter', function(event) {
-        that.ViewportMouseEnter(that.pimpl_);
-      });
-    
-      this.htmlCanvas_.addEventListener('mousedown', function(event) {
-        var x = event.pageX - this.offsetLeft;
-        var y = event.pageY - this.offsetTop;
-
-       that.ViewportMouseDown(that.pimpl_, event.button, x, y, 0 /* TODO detect modifier keys*/);    
-      });
-    
-      this.htmlCanvas_.addEventListener('mousemove', function(event) {
-        var x = event.pageX - this.offsetLeft;
-        var y = event.pageY - this.offsetTop;
-        that.ViewportMouseMove(that.pimpl_, x, y);
-      });
-    
-      this.htmlCanvas_.addEventListener('mouseup', function(event) {
-        that.ViewportMouseUp(that.pimpl_);
-      });
-    
-      window.addEventListener('keydown', function(event) {
-        var keyChar: string | null = event.key;
-        var keyCode = event.keyCode
-        if (keyChar.length == 1) {
-          keyCode = 0; // maps to OrthancStone::KeyboardKeys_Generic
-        } else {
-          keyChar = null;
-        }
-//        console.log("key: ", keyCode, keyChar);
-        that.ViewportKeyPressed(that.pimpl_, keyCode, keyChar, event.shiftKey, event.ctrlKey, event.altKey);
-      });
-    
-      this.htmlCanvas_.addEventListener('wheel', function(event) {
-        var x = event.pageX - this.offsetLeft;
-        var y = event.pageY - this.offsetTop;
-        that.ViewportMouseWheel(that.pimpl_, event.deltaY, x, y, event.ctrlKey);
-        event.preventDefault();
-      }, {passive: false}); // must not be passive if calling event.preventDefault, ie to cancel scroll or zoom of the whole interface
-
-      this.htmlCanvas_.addEventListener('touchstart', function(event: TouchEvent) {
-        // don't propagate events to the whole body (this could zoom the entire page instead of zooming the viewport)
-        event.preventDefault();
-        event.stopPropagation();
-
-        // TODO: find a way to pass the coordinates as an array between JS and C++
-        var x0 = 0;
-        var y0 = 0;
-        var x1 = 0;
-        var y1 = 0;
-        var x2 = 0;
-        var y2 = 0;
-        if (event.targetTouches.length > 0) {
-          x0 = event.targetTouches[0].pageX;
-          y0 = event.targetTouches[0].pageY;
-        }
-        if (event.targetTouches.length > 1) {
-          x1 = event.targetTouches[1].pageX;
-          y1 = event.targetTouches[1].pageY;
-        }
-        if (event.targetTouches.length > 2) {
-          x2 = event.targetTouches[2].pageX;
-          y2 = event.targetTouches[2].pageY;
-        }
-
-        that.ViewportTouchStart(that.pimpl_, event.targetTouches.length, x0, y0, x1, y1, x2, y2);
-      }, {passive: false}); // must not be passive if calling event.preventDefault, ie to cancel scroll or zoom of the whole interface
-    
-      this.htmlCanvas_.addEventListener('touchend', function(event) {
-        // don't propagate events to the whole body (this could zoom the entire page instead of zooming the viewport)
-        event.preventDefault();
-        event.stopPropagation();
-
-        // TODO: find a way to pass the coordinates as an array between JS and C++
-        var x0 = 0;
-        var y0 = 0;
-        var x1 = 0;
-        var y1 = 0;
-        var x2 = 0;
-        var y2 = 0;
-        if (event.targetTouches.length > 0) {
-          x0 = event.targetTouches[0].pageX;
-          y0 = event.targetTouches[0].pageY;
-        }
-        if (event.targetTouches.length > 1) {
-          x1 = event.targetTouches[1].pageX;
-          y1 = event.targetTouches[1].pageY;
-        }
-        if (event.targetTouches.length > 2) {
-          x2 = event.targetTouches[2].pageX;
-          y2 = event.targetTouches[2].pageY;
-        }
-
-        that.ViewportTouchEnd(that.pimpl_, event.targetTouches.length, x0, y0, x1, y1, x2, y2);
-      });
-    
-      this.htmlCanvas_.addEventListener('touchmove', function(event: TouchEvent) {
-
-        // don't propagate events to the whole body (this could zoom the entire page instead of zooming the viewport)
-        event.preventDefault();
-        event.stopPropagation();
-
-
-        // TODO: find a way to pass the coordinates as an array between JS and C++
-        var x0 = 0;
-        var y0 = 0;
-        var x1 = 0;
-        var y1 = 0;
-        var x2 = 0;
-        var y2 = 0;
-        if (event.targetTouches.length > 0) {
-          x0 = event.targetTouches[0].pageX;
-          y0 = event.targetTouches[0].pageY;
-        }
-        if (event.targetTouches.length > 1) {
-          x1 = event.targetTouches[1].pageX;
-          y1 = event.targetTouches[1].pageY;
-        }
-        if (event.targetTouches.length > 2) {
-          x2 = event.targetTouches[2].pageX;
-          y2 = event.targetTouches[2].pageY;
-        }
-
-        that.ViewportTouchMove(that.pimpl_, event.targetTouches.length, x0, y0, x1, y1, x2, y2);
-        return;
-
-      }, {passive: false}); // must not be passive if calling event.preventDefault, ie to cancel scroll or zoom of the whole interface
-    }  
-
-  public ResetTouch() {
-    if (this.touchTranslation_ ||
-        this.touchZoom_) {
-      this.ViewportMouseUp(this.pimpl_);
-    }
-
-    this.touchTranslation_ = false;
-    this.touchZoom_ = false;
-  }
-  
-  public GetTouchTranslation(event: any) {
-    var touch = event.targetTouches[0];
-    return [
-      touch.pageX,
-      touch.pageY
-    ];
-  }
-    
-  public GetTouchZoom(event: any) {
-    var touch1 = event.targetTouches[0];
-    var touch2 = event.targetTouches[1];
-    var dx = (touch1.pageX - touch2.pageX);
-    var dy = (touch1.pageY - touch2.pageY);
-    var d = Math.sqrt(dx * dx + dy * dy);
-    return [
-      (touch1.pageX + touch2.pageX) / 2.0,
-      (touch1.pageY + touch2.pageY) / 2.0,
-      d
-    ];
-  }
-   
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/Graveyard/playground.ts	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,259 +0,0 @@
-/*
-         1         2         3         4         5         6         7
-12345678901234567890123456789012345678901234567890123456789012345678901234567890
-*/
-
-namespace VsolStuff
-{
-  enum EnumMonth0
-  {
-    January,
-    February,
-    March
-  };
-
-  // interface Serializer
-  // {
-  //   Serialize(value: number): string;
-  //   Serialize(value: string): string;
-  //   Serialize(value: EnumMonth0): string;
-  // };
-  function printf(value: any):void
-  {
-    console.log(value)
-  }
-
-  // function StoneSerialize(value: string) : string;
-  // function StoneSerialize(value: number) : string;
-  // function StoneSerialize(value: EnumMonth0) : string;
-  function StoneSerialize<T>(value: T[]) : string;
-
-  function StoneSerialize<T>(value: T[] | EnumMonth0) : string
-  {
-    let valueType = typeof value;
-    printf(`About to serialize value. Type is ${valueType}`)
-    printf(`About to serialize value. Type is ${typeof value}`)
-    return "Choucroute";
-  }
-
-  function main():number
-  {
-    enum Color {Red = 1, Green = 2, Blue = 4}
-    let color: Color = Color.Green;
-    printf("---------------------------");
-    printf(`typeof color: ${typeof color}`);
-    printf("---------------------------");
-    let colors: Color[] = []
-    colors.push(Color.Green);
-    colors.push(Color.Red);
-    printf(`typeof colors: ${typeof colors}`);
-    printf(`Array.isArray(colors): ${Array.isArray(colors)}`);
-    printf("---------------------------");
-    
-
-    let toto:EnumMonth0[] = [];
-
-    toto.push(EnumMonth0.February);
-    toto.push(EnumMonth0.March);
-
-    printf(JSON.stringify(toto));
-
-    return 0;
-
-  }
-
-  main()
-
-//   string StoneSerialize_number(int32_t value)
-//   {
-
-//     Json::Value result(value);
-//     return result;
-//   }
-
-//   Json::Value StoneSerialize(double value)
-//   {
-//     Json::Value result(value);
-//     return result;
-//   }
-
-//   Json::Value StoneSerialize(bool value)
-//   {
-//     Json::Value result(value);
-//     return result;
-//   }
-
-//   Json::Value StoneSerialize(const std::string& value)
-//   {
-//     // the following is better than 
-//     Json::Value result(value.data(),value.data()+value.size());
-//     return result;
-//   }
-
-//   template<typename T>
-//   Json::Value StoneSerialize(const std::map<std::string,T>& value)
-//   {
-//     Json::Value result(Json::objectValue);
-
-//     for (std::map<std::string, T>::const_iterator it = value.cbegin();
-//       it != value.cend(); ++it)
-//     {
-//       // it->first it->second
-//       result[it->first] = StoneSerialize(it->second);
-//     }
-//     return result;
-//   }
-
-//   template<typename T>
-//   Json::Value StoneSerialize(const std::vector<T>& value)
-//   {
-//     Json::Value result(Json::arrayValue);
-//     for (size_t i = 0; i < value.size(); ++i)
-//     {
-//       result.append(StoneSerialize(value[i]));
-//     }
-//     return result;
-//   }
-
-//   enum EnumMonth0
-//   {
-//     January,
-//     February,
-//     March
-//   };
-
-//   std::string ToString(EnumMonth0 value)
-//   {
-//     switch(value)
-//     {
-//       case January: 
-//         return "January";
-//       case February:
-//         return "February";
-//       case March:
-//         return "March";
-//       default:
-//         {
-//           std::stringstream ss;
-//           ss << "Unrecognized EnumMonth0 value (" << static_cast<int64_t>(value) << ")";
-//           throw std::runtime_error(ss.str());
-//         }
-//     }
-//   }
-
-//   void FromString(EnumMonth0& value, std::string strValue)
-//   {
-//     if (strValue == "January" || strValue == "EnumMonth0_January")
-//     {
-//       return January;
-//     }
-//     else if (strValue == "February" || strValue == "EnumMonth0_February")
-//     {
-//       return February;
-//     }
-// #error Not implemented yet
-//   }
-
-//   Json::Value StoneSerialize(const EnumMonth0& value)
-//   {
-//     return StoneSerialize(ToString(value));
-//   }
-//   struct Message1
-//   {
-//     int32_t a;
-//     std::string b;
-//     EnumMonth0 c;
-//     bool d;
-//   };
-
-//   struct Message2
-//   {
-//     std::string toto;
-//     std::vector<Message1> tata;
-//     std::vector<std::string> tutu;
-//     std::map<std::string, std::string> titi;
-//     std::map<std::string, Message1> lulu;
-//   };
-
-//   Json::Value StoneSerialize(const Message1& value)
-//   {
-//     Json::Value result(Json::objectValue);
-//     result["a"] = StoneSerialize(value.a);
-//     result["b"] = StoneSerialize(value.b);
-//     result["c"] = StoneSerialize(value.c);
-//     result["d"] = StoneSerialize(value.d);
-//     return result;
-//   }
-    
-//   Json::Value StoneSerialize(const Message2& value)
-//   {
-//     Json::Value result(Json::objectValue);
-//     result["toto"] = StoneSerialize(value.toto);
-//     result["tata"] = StoneSerialize(value.tata);
-//     result["tutu"] = StoneSerialize(value.tutu);
-//     result["titi"] = StoneSerialize(value.titi);
-//     result["lulu"] = StoneSerialize(value.lulu);
-//     return result;
-//   }
-// }
-
-// int main()
-// {
-//   VsolStuff::Message1 msg1_0;
-//   msg1_0.a = 42;
-//   msg1_0.b = "Benjamin";
-//   msg1_0.c = VsolStuff::January;
-//   msg1_0.d = true;
-
-//   VsolStuff::Message1 msg1_1;
-//   msg1_1.a = 43;
-//   msg1_1.b = "Sandrine";
-//   msg1_1.c = VsolStuff::March;
-//   msg1_0.d = false;
-
-//   // std::string toto;
-//   // std::vector<Message1> tata;
-//   // std::vector<std::string> tutu;
-//   // std::map<int32_t, std::string> titi;
-//   // std::map<int32_t, Message1> lulu;
-
-//   VsolStuff::Message2 msg2_0;
-//   msg2_0.toto = "Prout zizi";
-//   msg2_0.tata.push_back(msg1_0);
-//   msg2_0.tata.push_back(msg1_1);
-//   msg2_0.tutu.push_back("Mercadet");
-//   msg2_0.tutu.push_back("Poisson");
-//   msg2_0.titi["44"] = "key 44";
-//   msg2_0.titi["45"] = "key 45";
-//   msg2_0.lulu["54"] = msg1_1;
-//   msg2_0.lulu["55"] = msg1_0;
-//   auto result = VsolStuff::StoneSerialize(msg2_0);
-//   auto resultStr = result.toStyledString();
-
-//   Json::Value readValue;
-
-//   Json::CharReaderBuilder builder;
-//   Json::CharReader* reader = builder.newCharReader();
-//   std::string errors;
-
-//   bool ok = reader->parse(
-//     resultStr.c_str(),
-//     resultStr.c_str() + resultStr.size(),
-//     &readValue,
-//     &errors
-//   );
-//   delete reader;
-
-//   if (!ok)
-//   {
-//     std::stringstream ss;
-//     ss << "Json parsing error: " << errors;
-//     throw std::runtime_error(ss.str());
-//   }
-//   std::cout << readValue.get("toto", "Default Value").asString() << std::endl;
-//   return 0;
-// }
-
-
-}
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/Graveyard/playground2.ts	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-class Greeter {
-    greeting: string;
-    constructor(message: string) {
-        this.greeting = message;
-    }
-    greet() {
-        return "Hello, " + this.greeting;
-    }
-}
-enum Color {
-    Red,
-    Green,
-    Blue,
-};
-
-function ColorToString(value: Color)
-{
-    switch (value)
-    {
-        case Color.Red:
-            return "Red";
-        case Color.Green:
-            return "Green";
-        case Color.Blue:
-            return "Blue";
-        default:
-            throw new Error(`Unrecognized Color value(${value})`);
-    }
-}
-
-let color: Color = Color.Red;
-
-document.body.textContent = "<p>---------------------</p>"
-document.body.textContent += "<p>********************************</p>"
-
-class TestMessage {
-    s1: string;
-    s2: Array<string>;
-    s3: Array<Array<string>>;
-    s4: Map<string, number>;
-    s5: Map<number, Array<string>>;
-    s6: Color;
-    s7: boolean;
-}
-
-let tm = new TestMessage();
-tm.s2 = new Array<string>()
-tm.s2.push("toto");
-tm.s2.push("toto2");
-tm.s2.push("toto3");
-tm.s4 = new Map<string, number>();
-tm.s4["toto"] = 42;
-tm.s4["toto"] = 1999;
-tm.s4["tatata"] = 1999;
-tm.s6 = Color.Red;
-tm.s7 = true
-
-let txt = JSON.stringify(tm)
-let txtElem = document.createElement('textarea');
-txtElem.value = txt;
-
-document.body.appendChild(txtElem);
-
-let greeter = new Greeter("world");
-
-let button = document.createElement('button');
-button.textContent = "Say Hello";
-button.onclick = function() {
-    alert(greeter.greet());
-}
-
-document.body.appendChild(button);
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/Graveyard/playground3.ts	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,275 +0,0 @@
-/*
-         1         2         3         4         5         6         7
-12345678901234567890123456789012345678901234567890123456789012345678901234567890
-*/
-
-namespace VsolStuff222 {
-  export enum EnumMonth0 {
-    January,
-    February,
-    March
-  };
-
-  export class Message1 {
-    a: number;
-    b: string;
-    c: EnumMonth0;
-    d: boolean;
-    public StoneSerialize(): string {
-      let container: object = {};
-      container['type'] = 'VsolStuff.Message1';
-      container['value'] = this;
-      return JSON.stringify(container);
-    }
-  };
-
-  export class Message2 {
-    toto: string;
-    tata: Message1[];
-    tutu: string[];
-    titi: Map<string, string>;
-    lulu: Map<string, Message1>;
-
-    public StoneSerialize(): string {
-      let container: object = {};
-      container['type'] = 'VsolStuff.Message2';
-      container['value'] = this;
-      return JSON.stringify(container);
-    }
-  };
-}
-
-function printf(value: any): void {
-  console.log(value)
-}
-
-function main(): number {
-
-  let msg1_0 = new VsolStuff.Message1();
-  msg1_0.a = 42;
-  msg1_0.b = "Benjamin";
-  msg1_0.c = VsolStuff.EnumMonth0.January;
-  msg1_0.d = true;
-
-  let msg1_1 = new VsolStuff.Message1();
-  msg1_1.a = 43;
-  msg1_1.b = "Sandrine";
-  msg1_1.c = VsolStuff.EnumMonth0.March;
-  msg1_0.d = false;
-
-  // std::string toto;
-  // std::vector<Message1> tata;
-  // std::vector<std::string> tutu;
-  // std::map<int32_t, std::string> titi;
-  // std::map<int32_t, Message1> lulu;
-
-  let msg2_0 = new VsolStuff.Message2();
-  msg2_0.toto = "Prout zizi";
-  msg2_0.tata = new Array<VsolStuff.Message1>();
-  msg2_0.tata.push(msg1_0);
-  msg2_0.tata.push(msg1_1);
-  msg2_0.tutu.push("Mercadet");
-  msg2_0.tutu.push("Poisson");ing
-  msg2_0.titi["44"] = "key 44";
-  msg2_0.titi["45"] = "key 45";
-  msg2_0.lulu["54"] = msg1_1;
-  msg2_0.lulu["55"] = msg1_0;
-  let result:string = VsolStuff.StoneSerialize(msg2_0);
-  return 0;
-}
-
-main()
-
-//   string StoneSerialize_number(int32_t value)
-//   {
-
-//     Json::Value result(value);
-//     return result;
-//   }
-
-//   Json::Value StoneSerialize(double value)
-//   {
-//     Json::Value result(value);
-//     return result;
-//   }
-
-//   Json::Value StoneSerialize(bool value)
-//   {
-//     Json::Value result(value);
-//     return result;
-//   }
-
-//   Json::Value StoneSerialize(const std::string& value)
-//   {
-//     // the following is better than 
-//     Json::Value result(value.data(),value.data()+value.size());
-//     return result;
-//   }
-
-//   template<typename T>
-//   Json::Value StoneSerialize(const std::map<std::string,T>& value)
-//   {
-//     Json::Value result(Json::objectValue);
-
-//     for (std::map<std::string, T>::const_iterator it = value.cbegin();
-//       it != value.cend(); ++it)
-//     {
-//       // it->first it->second
-//       result[it->first] = StoneSerialize(it->second);
-//     }
-//     return result;
-//   }
-
-//   template<typename T>
-//   Json::Value StoneSerialize(const std::vector<T>& value)
-//   {
-//     Json::Value result(Json::arrayValue);
-//     for (size_t i = 0; i < value.size(); ++i)
-//     {
-//       result.append(StoneSerialize(value[i]));
-//     }
-//     return result;
-//   }
-
-//   enum EnumMonth0
-//   {
-//     January,
-//     February,
-//     March
-//   };
-
-//   std::string ToString(EnumMonth0 value)
-//   {
-//     switch(value)
-//     {
-//       case January: 
-//         return "January";
-//       case February:
-//         return "February";
-//       case March:
-//         return "March";
-//       default:
-//         {
-//           std::stringstream ss;
-//           ss << "Unrecognized EnumMonth0 value (" << static_cast<int64_t>(value) << ")";
-//           throw std::runtime_error(ss.str());
-//         }
-//     }
-//   }
-
-//   void FromString(EnumMonth0& value, std::string strValue)
-//   {
-//     if (strValue == "January" || strValue == "EnumMonth0_January")
-//     {
-//       return January;
-//     }
-//     else if (strValue == "February" || strValue == "EnumMonth0_February")
-//     {
-//       return February;
-//     }
-// #error Not implemented yet
-//   }
-
-//   Json::Value StoneSerialize(const EnumMonth0& value)
-//   {
-//     return StoneSerialize(ToString(value));
-//   }
-//   struct Message1
-//   {
-//     int32_t a;
-//     std::string b;
-//     EnumMonth0 c;
-//     bool d;
-//   };
-
-//   struct Message2
-//   {
-//     std::string toto;
-//     std::vector<Message1> tata;
-//     std::vector<std::string> tutu;
-//     std::map<std::string, std::string> titi;
-//     std::map<std::string, Message1> lulu;
-//   };
-
-//   Json::Value StoneSerialize(const Message1& value)
-//   {
-//     Json::Value result(Json::objectValue);
-//     result["a"] = StoneSerialize(value.a);
-//     result["b"] = StoneSerialize(value.b);
-//     result["c"] = StoneSerialize(value.c);
-//     result["d"] = StoneSerialize(value.d);
-//     return result;
-//   }
-
-//   Json::Value StoneSerialize(const Message2& value)
-//   {
-//     Json::Value result(Json::objectValue);
-//     result["toto"] = StoneSerialize(value.toto);
-//     result["tata"] = StoneSerialize(value.tata);
-//     result["tutu"] = StoneSerialize(value.tutu);
-//     result["titi"] = StoneSerialize(value.titi);
-//     result["lulu"] = StoneSerialize(value.lulu);
-//     return result;
-//   }
-// }
-
-// int main()
-// {
-//   VsolStuff::Message1 msg1_0;
-//   msg1_0.a = 42;
-//   msg1_0.b = "Benjamin";
-//   msg1_0.c = VsolStuff::January;
-//   msg1_0.d = true;
-
-//   VsolStuff::Message1 msg1_1;
-//   msg1_1.a = 43;
-//   msg1_1.b = "Sandrine";
-//   msg1_1.c = VsolStuff::March;
-//   msg1_0.d = false;
-
-//   // std::string toto;
-//   // std::vector<Message1> tata;
-//   // std::vector<std::string> tutu;
-//   // std::map<int32_t, std::string> titi;
-//   // std::map<int32_t, Message1> lulu;
-
-//   VsolStuff::Message2 msg2_0;
-//   msg2_0.toto = "Prout zizi";
-//   msg2_0.tata.push_back(msg1_0);
-//   msg2_0.tata.push_back(msg1_1);
-//   msg2_0.tutu.push_back("Mercadet");
-//   msg2_0.tutu.push_back("Poisson");
-//   msg2_0.titi["44"] = "key 44";
-//   msg2_0.titi["45"] = "key 45";
-//   msg2_0.lulu["54"] = msg1_1;
-//   msg2_0.lulu["55"] = msg1_0;
-//   auto result = VsolStuff::StoneSerialize(msg2_0);
-//   auto resultStr = result.toStyledString();
-
-//   Json::Value readValue;
-
-//   Json::CharReaderBuilder builder;
-//   Json::CharReader* reader = builder.newCharReader();
-//   std::string errors;
-
-//   bool ok = reader->parse(
-//     resultStr.c_str(),
-//     resultStr.c_str() + resultStr.size(),
-//     &readValue,
-//     &errors
-//   );
-//   delete reader;
-
-//   if (!ok)
-//   {
-//     std::stringstream ss;
-//     ss << "Json parsing error: " << errors;
-//     throw std::runtime_error(ss.str());
-//   }
-//   std::cout << readValue.get("toto", "Default Value").asString() << std::endl;
-//   return 0;
-// }
-
-
-}
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/Graveyard/playground4.py	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-testYaml = """
-enum SomeEnum:
- - january
- - feb
-
-struct Message0:
- a: string
-
-struct Message1:
- a: string
- b: int32
- c: vector<Message0>
- d: SomeEnum = january
- e: SomeEnum= january
- f: SomeEnum=january
- g: SomeEnum =january
-  
-
-# github.com/AlDanial/cloc
-header2 : 
-  cloc_version       : 1.67
-  elapsed_seconds    : int32_t
-
-header : 
-  cloc_version       : 1.67
-  elapsed_seconds    : int32_t
-  cloc_url           : vector<map<string,int32>>
-  n_files            : 1
-  n_lines            : 3
-  files_per_second   : 221.393718659277
-  lines_per_second   : 664.181155977831
-  report_file        : IDL.idl.yaml
-IDL :
-  nFiles: 1
-  blank: 0
-  comment: 2
-  code: 1
-EnumSUM: 
-  - aaa
-  - bbb
-
-SUM: 
-  blank: 0
-  comment: 2
-  code: 1
-  nFiles: 1
-"""
-
-import yaml
-
-b = yaml.load(testYaml)
-print(b)
-
-c = {
-  'enum SomeEnum': ['january', 'feb'], 
-  'struct Message0': {'a': 'string'}, 
-  'struct Message1': {
-    'a': 'string', 
-    'b': 'int32', 
-    'c': 'vector<Message0>', 
-    'd': 'vector<map<string,int32>>', 
-    'e': 'SomeEnum= january', 
-    'f': 'SomeEnum=january', 
-    'g': 'SomeEnum =january'
-  }, 
-}
-
-print(c)
\ No newline at end of file
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/Graveyard/runts.ps1	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-# echo "+----------------------+"
-# echo "|    playground.ts     |"
-# echo "+----------------------+"
-
-# tsc -t ES2015 .\playground.ts; node .\playground.js
-
-# echo "+----------------------+"
-# echo "|    playground3.ts     |"
-# echo "+----------------------+"
-
-# tsc -t ES2015 .\playground3.ts; node .\playground3.js
-
-echo "+----------------------+"
-echo "|      stonegen        |"
-echo "+----------------------+"
-
-if(-not (test-Path "build")) {
-  mkdir "build"
-}
-
-echo "Generate the TS and CPP wrapper... (to build/)"
-python stonegentool.py -o "." test_data/test1.yaml
-if($LASTEXITCODE -ne 0) {
-  Write-Error ("Code generation failed!")
-  exit $LASTEXITCODE
-}
-
-echo "Compile the TS wrapper to JS... (in build/)"
-tsc --module commonjs --sourceMap -t ES2015 --outDir "build/" VsolMessages_generated.ts
-if($LASTEXITCODE -ne 0) {
-  Write-Error ("Code compilation failed!")
-  exit $LASTEXITCODE
-}
-
-echo "Compile the test app..."
-tsc --module commonjs --sourceMap -t ES2015 --outDir "build/" test_stonegen.ts
-if($LASTEXITCODE -ne 0) {
-  Write-Error ("Code compilation failed!")
-  exit $LASTEXITCODE
-}
-
-browserify "build/test_stonegen.js" "build/VsolMessages_generated.js" -o "build_browser/test_stonegen_fused.js"
-
-cp .\test_stonegen.html .\build_browser\
-
-echo "Run the test app..."
-Push-Location
-cd build_browser
-node .\test_stonegen_fused.js
-Pop-Location
-if($LASTEXITCODE -ne 0) {
-  Write-Error ("Code execution failed!")
-  exit $LASTEXITCODE
-}
-
-
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/Graveyard/test_stonegen.html	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-<script type="text/javascript" src="test_stonegen_fused.js"></script>
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/Graveyard/test_stonegen.ts	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,206 +0,0 @@
-import * as VsolMessages from "./VsolMessages_generated";
-
-function TEST_StoneGen_SerializeComplex() {
-  let msg1_0 = new VsolMessages.Message1();
-  msg1_0.a = 42;
-  msg1_0.b = "Benjamin";
-  msg1_0.c = VsolMessages.EnumMonth0.January;
-  msg1_0.d = true;
-  let msg1_1 = new VsolMessages.Message1();
-  msg1_1.a = 43;
-  msg1_1.b = "Sandrine";
-  msg1_1.c = VsolMessages.EnumMonth0.March;
-  msg1_0.d = false;
-  let result1_0 = msg1_0.StoneSerialize();
-  let resultStr1_0 = JSON.stringify(result1_0);
-  let result1_1 = msg1_1.StoneSerialize();
-  let resultStr1_1 = JSON.stringify(result1_1);
-  // std::string toto;
-  // std::vector<Message1> tata;
-  // std::vector<std::string> tutu;
-  // std::map<int32_t, std::string> titi;
-  // std::map<int32_t, Message1> lulu;
-  let msg2_0 = new VsolMessages.Message2();
-  msg2_0.toto = "Prout zizi";
-  msg2_0.tata.push(msg1_0);
-  msg2_0.tata.push(msg1_1);
-  msg2_0.tutu.push("Mercadet");
-  msg2_0.tutu.push("Poisson");
-  msg2_0.titi["44"] = "key 44";
-  msg2_0.titi["45"] = "key 45";
-  msg2_0.lulu["54"] = msg1_1;
-  msg2_0.lulu["55"] = msg1_0;
-  let result2 = msg2_0.StoneSerialize();
-  let resultStr2 = JSON.stringify(result2);
-  let refResult2 = `{
-"type" : "VsolMessages.Message2",
-"value" : 
-{
-  "lulu" : 
-  {
-    "54" : 
-    {
-      "a" : 43,
-      "b" : "Sandrine",
-      "c" : 2,
-      "d" : true
-    },
-    "55" : 
-    {
-      "a" : 42,
-      "b" : "Benjamin",
-      "c" : 0,
-      "d" : false
-    }
-  },
-  "tata" : 
-  [
-    {
-      "a" : 42,
-      "b" : "Benjamin",
-      "c" : 0,
-      "d" : false
-    },
-    {
-      "a" : 43,
-      "b" : "Sandrine",
-      "c" : 2,
-      "d" : true
-    }
-  ],
-  "titi" : 
-  {
-    "44" : "key 44",
-    "45" : "key 45"
-  },
-  "toto" : "Prout zizi",
-  "tutu" : 
-  [
-    "Mercadet",
-    "Poisson"
-  ]
-}
-}
-`;
-  let refResult2Obj = JSON.parse(refResult2);
-  let resultStr2Obj = JSON.parse(resultStr2);
-  if (false) {
-    if (refResult2Obj !== resultStr2Obj) {
-      console.log("Results are different!");
-      console.log(`refResult2Obj['value']['lulu']['54'] = ${refResult2Obj['value']['lulu']['54']}`);
-      console.log(`refResult2Obj['value']['lulu']['54']['a'] = ${refResult2Obj['value']['lulu']['54']['a']}`);
-      console.log("************************************************************");
-      console.log("**                  REFERENCE OBJ                         **");
-      console.log("************************************************************");
-      console.log(refResult2Obj);
-      console.log("************************************************************");
-      console.log("**                  ACTUAL OBJ                            **");
-      console.log("************************************************************");
-      console.log(resultStr2Obj);
-      console.log("************************************************************");
-      console.log("**                  REFERENCE                             **");
-      console.log("************************************************************");
-      console.log(refResult2);
-      console.log("************************************************************");
-      console.log("**                  ACTUAL                                **");
-      console.log("************************************************************");
-      console.log(resultStr2);
-      throw new Error("Wrong serialization");
-    }
-  }
-  let refResultValue = JSON.parse(resultStr2);
-  console.log(refResultValue);
-}
-class MyDispatcher {
-  message1: VsolMessages.Message1;
-  message2: VsolMessages.Message2;
-
-  HandleMessage1(value: VsolMessages.Message1) {
-    this.message1 = value;
-    return true;
-  }
-  HandleMessage2(value: VsolMessages.Message2) {
-    this.message2 = value;
-    return true;
-  }
-  HandleA(value) {
-    return true;
-  }
-  HandleB(value) {
-    return true;
-  }
-  HandleC(value) {
-    return true;
-  }
-}
-;
-function TEST_StoneGen_DeserializeOkAndNok() {
-  let serializedMessage = `{
-"type" : "VsolMessages.Message2",
-"value" : 
-{
-  "lulu" : 
-  {
-    "54" : 
-    {
-      "a" : 43,
-      "b" : "Sandrine",
-      "c" : 2,
-      "d" : true
-    },
-    "55" : 
-    {
-      "a" : 42,
-      "b" : "Benjamin",
-      "c" : 0,
-      "d" : false
-    }
-  },
-  "tata" : 
-  [
-    {
-      "a" : 42,
-      "b" : "Benjamin",
-      "c" : 0,
-      "d" : false
-    },
-    {
-      "a" : 43,
-      "b" : "Sandrine",
-      "c" : 2,
-      "d" : true
-    }
-  ],
-  "titi" : 
-  {
-    "44" : "key 44",
-    "45" : "key 45"
-  },
-  "toto" : "Prout zizi",
-  "tutu" : 
-  [
-    "Mercadet",
-    "Poisson"
-  ]
-}
-}`;
-  let myDispatcher = new MyDispatcher();
-  let ok = VsolMessages.StoneDispatchToHandler(serializedMessage, myDispatcher);
-  if (!ok) {
-    throw Error("Error when dispatching message!");
-  }
-  if (myDispatcher.message1 != undefined) {
-    throw Error("(myDispatcher.Message1 != undefined)");
-  }
-  if (myDispatcher.message2 == undefined) {
-    throw Error("(myDispatcher.Message2 == undefined)");
-  }
-  console.log("TEST_StoneGen_DeserializeOkAndNok: OK!");
-}
-function main() {
-  console.log("Entering main()");
-  TEST_StoneGen_SerializeComplex();
-  TEST_StoneGen_DeserializeOkAndNok();
-  return 0;
-}
-console.log(`Exit code is: ${main()}`);
\ No newline at end of file
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/Graveyard/tsconfig.json	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-{
-  // "extends": "../../../../../orthanc-stone/Platforms/Wasm/tsconfig-stone",
-  "compilerOptions": {
-    // "outFile": "../../../WebApplication-build/to-embed/app.js",
-    // "module": "system",
-    // "sourceMap": false,
-    "lib": [
-      "es2017",
-      "es2017",
-      "dom",
-      "dom.iterable"
-    ]
-  },
-  "include": [
-    // "commands/*.ts",
-    // "logger.ts",
-    // "app.ts",
-    // "main.ts",
-    // "ui.ts",
-    // "popup.ts"
-  ]
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/README.md	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-Requirements
-----------------
-
-Install Node and npm.
-
-Then:
-- `npm install browserify`
-- `npm install typescript`
-- `npm install tsify`
-
-`testCppHandler` contains a C++ project that produces an executable 
-slurping a set of text files representing messages defined against 
-the `test_data/testTestStoneCodeGen.yaml' schema and dumping them to `cout`.
-
-'testWasmIntegrated` contains a small Web app demonstrating the 
-interaction between TypeScript and C++ in WASM.
-source ~/apps/emsdk/emsdk_env.sh
-
-
-Install Python and the following packages `pip install pyyaml yamlloader jinja2`
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/stonegentool.py	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,605 +0,0 @@
-import json
-import yaml
-import re
-import os
-import sys
-from jinja2 import Template
-from io import StringIO
-import time
-import datetime
-import yamlloader
-
-"""
-         1         2         3         4         5         6         7
-12345678901234567890123456789012345678901234567890123456789012345678901234567890
-"""
-
-# see https://stackoverflow.com/a/2504457/2927708
-def trim(docstring):
-    if not docstring:
-        return ''
-    # Convert tabs to spaces (following the normal Python rules)
-    # and split into a list of lines:
-    lines = docstring.expandtabs().splitlines()
-    # Determine minimum indentation (first line doesn't count):
-    indent = sys.maxsize
-    for line in lines[1:]:
-        stripped = line.lstrip()
-        if stripped:
-            indent = min(indent, len(line) - len(stripped))
-    # Remove indentation (first line is special):
-    trimmed = [lines[0].strip()]
-    if indent < sys.maxsize:
-        for line in lines[1:]:
-            trimmed.append(line[indent:].rstrip())
-    # Strip off trailing and leading blank lines:
-    while trimmed and not trimmed[-1]:
-        trimmed.pop()
-    while trimmed and not trimmed[0]:
-        trimmed.pop(0)
-    # Return a single string:
-    return '\n'.join(trimmed)
-
-class JsonHelpers:
-    """A set of utilities to perform JSON operations"""
-
-    @staticmethod
-    def removeCommentsFromJsonContent(string):
-        """
-      Remove comments from a JSON file
-
-      Comments are not allowed in JSON but, i.e., Orthanc configuration files
-      contains C++ like comments that we need to remove before python can
-      parse the file
-      """
-        # remove all occurrence streamed comments (/*COMMENT */) from string
-        string = re.sub(re.compile("/\*.*?\*/", re.DOTALL), "", string)
-
-        # remove all occurrence singleline comments (//COMMENT\n ) from string
-        string = re.sub(re.compile("//.*?\n"), "", string)
-
-        return string
-
-    @staticmethod
-    def loadJsonWithComments(path):
-        """
-      Reads a JSON file that may contain C++ like comments
-      """
-        with open(path, "r") as fp:
-            fileContent = fp.read()
-        fileContent = JsonHelpers.removeCommentsFromJsonContent(fileContent)
-        return json.loads(fileContent)
-
-class FieldDefinition:
-
-    def __init__(self, name: str, type: str, defaultValue: str):
-        self.name = name
-        self.type = type
-        self.defaultValue = defaultValue
-
-    @staticmethod
-    def fromKeyValue(key: str, value: str):
-
-        if "=" in value:
-            splitValue = value.split(sep="=")
-            type = splitValue[0].strip(" ")
-            defaultValue = splitValue[1].strip(" ")
-        else:
-            type = value
-            defaultValue = None
-
-        return FieldDefinition(name = key, type = type, defaultValue = defaultValue)
-
-
-def LoadSchemaFromJson(filePath):
-    return JsonHelpers.loadJsonWithComments(filePath)
-
-def CanonToCpp(canonicalTypename):
-  # C++: prefix map vector and string with std::map, std::vector and
-  # std::string
-  # replace int32... by int32_t...
-  # replace float32 by float
-  # replace float64 by double
-  retVal = canonicalTypename
-  retVal = retVal.replace("map", "std::map")
-  retVal = retVal.replace("vector", "std::vector")
-  retVal = retVal.replace("set", "std::set")
-  retVal = retVal.replace("string", "std::string")
-  #uint32 and uint64 are handled by int32 and uint32 (because search and replace are done as partial words)
-  retVal = retVal.replace("int32", "int32_t")
-  retVal = retVal.replace("int64", "int64_t")
-  retVal = retVal.replace("float32", "float")
-  retVal = retVal.replace("float64", "double")
-  retVal = retVal.replace("json", "Json::Value")
-  return retVal
-
-def CanonToTs(canonicalTypename):
-  # TS: replace vector with Array and map with Map
-  # string remains string
-  # replace int32... by number
-  # replace float32... by number
-  retVal = canonicalTypename
-  retVal = retVal.replace("map", "Map")
-  retVal = retVal.replace("vector", "Array")
-  retVal = retVal.replace("set", "Set")
-  retVal = retVal.replace("uint32", "number")
-  retVal = retVal.replace("uint64", "number")
-  retVal = retVal.replace("int32", "number")
-  retVal = retVal.replace("int64", "number")
-  retVal = retVal.replace("float32", "number")
-  retVal = retVal.replace("float64", "number")
-  retVal = retVal.replace("bool", "boolean")
-  retVal = retVal.replace("json", "Object")
-  return retVal
-
-def NeedsTsConstruction(enums, tsType):
-  if tsType == 'boolean':
-    return False
-  elif tsType == 'number':
-    return False
-  elif tsType == 'string':
-    return False
-  else:
-    enumNames = []
-    for enum in enums:
-      enumNames.append(enum['name'])
-    if tsType in enumNames:
-      return False
-  return True
-
-def NeedsCppConstruction(canonTypename):
-  return False
-
-def DefaultValueToTs(enums, field:FieldDefinition):
-    tsType = CanonToTs(field.type)
-
-    enumNames = []
-    for enum in enums:
-        enumNames.append(enum['name'])
-
-    if tsType in enumNames:
-        return tsType + "." + field.defaultValue
-    else:
-        return field.defaultValue
-
-def DefaultValueToCpp(root, enums, field:FieldDefinition):
-    cppType = CanonToCpp(field.type)
-
-    enumNames = []
-    for enum in enums:
-        enumNames.append(enum['name'])
-
-    if cppType in enumNames:
-        return root + "::" + cppType + "_" + field.defaultValue
-    else:
-        return field.defaultValue
-
-def RegisterTemplateFunction(template,func):
-  """Makes a function callable by a jinja2 template"""
-  template.globals[func.__name__] = func
-  return func
-
-def MakeTemplate(templateStr):
-  template = Template(templateStr)
-  RegisterTemplateFunction(template,CanonToCpp)
-  RegisterTemplateFunction(template,CanonToTs)
-  RegisterTemplateFunction(template,NeedsTsConstruction)
-  RegisterTemplateFunction(template,NeedsCppConstruction)
-  RegisterTemplateFunction(template, DefaultValueToTs)
-  RegisterTemplateFunction(template, DefaultValueToCpp)
-  return template
-
-def MakeTemplateFromFile(templateFileName):
-
-  with open(templateFileName, "r") as templateFile:
-    templateFileContents = templateFile.read()
-    return MakeTemplate(templateFileContents)
-
-
-def EatToken(sentence):
-    """splits "A,B,C" into "A" and "B,C" where A, B and C are type names
-  (including templates) like "int32", "TotoTutu", or 
-  "map<map<int32,vector<string>>,map<string,int32>>" """
-
-    if sentence.count("<") != sentence.count(">"):
-        raise Exception(
-            "Error in the partial template type list " + str(sentence) + "."
-            + " The number of < and > do not match!"
-        )
-
-    # the template level we're currently in
-    templateLevel = 0
-    for i in range(len(sentence)):
-        if (sentence[i] == ",") and (templateLevel == 0):
-            return (sentence[0:i], sentence[i + 1 :])
-        elif sentence[i] == "<":
-            templateLevel += 1
-        elif sentence[i] == ">":
-            templateLevel -= 1
-    return (sentence, "")
-
-
-def SplitListOfTypes(typename):
-    """Splits something like
-  vector<string>,int32,map<string,map<string,int32>> 
-  in:
-  - vector<string>
-  - int32
-    map<string,map<string,int32>>
-  
-  This is not possible with a regex so 
-  """
-    stillStuffToEat = True
-    tokenList = []
-    restOfString = typename
-    while stillStuffToEat:
-        firstToken, restOfString = EatToken(restOfString)
-        tokenList.append(firstToken)
-        if restOfString == "":
-            stillStuffToEat = False
-    return tokenList
-
-
-templateRegex = \
-  re.compile(r"([a-zA-Z0-9_]*[a-zA-Z0-9_]*)<([a-zA-Z0-9_,:<>]+)>")
-
-
-def ParseTemplateType(typename):
-    """ If the type is a template like "SOMETHING<SOME<THING,EL<SE>>>", 
-    then it returns (true,"SOMETHING","SOME<THING,EL<SE>>")
-  otherwise it returns (false,"","")"""
-
-    # let's remove all whitespace from the type
-    # split without argument uses any whitespace string as separator
-    # (space, tab, newline, return or formfeed)
-    typename = "".join(typename.split())
-    matches = templateRegex.match(typename)
-    if matches == None:
-        return (False, "", [])
-    else:
-        m = matches
-        assert len(m.groups()) == 2
-        # we need to split with the commas that are outside of the
-        # defined types. Simply splitting at commas won't work
-        listOfDependentTypes = SplitListOfTypes(m.group(2))
-        return (True, m.group(1), listOfDependentTypes)
-
-def GetStructFields(struct):
-  """This filters out the special metadata key from the struct fields"""
-  return [k for k in struct.keys() if k != '__handler']
-
-def ComputeOrderFromTypeTree(
-  ancestors, 
-  genOrder, 
-  shortTypename, schema):
-
-  if shortTypename in ancestors:
-    raise Exception(
-      "Cyclic dependency chain found: the last of " + str(ancestors) +
-      + " depends on " + str(shortTypename) + " that is already in the list."
-    )
-
-  if not (shortTypename in genOrder):
-    (isTemplate, _, dependentTypenames) = ParseTemplateType(shortTypename)
-    if isTemplate:
-      # if it is a template, it HAS dependent types... They can be 
-      # anything (primitive, collection, enum, structs..). 
-      # Let's process them!
-      for dependentTypename in dependentTypenames:
-        # childAncestors = ancestors.copy()  NO TEMPLATE ANCESTOR!!!
-        # childAncestors.append(typename)
-        ComputeOrderFromTypeTree(
-            ancestors, genOrder, dependentTypename, schema
-        )
-    else:
-      # If it is not template, we are only interested if it is a 
-      # dependency that we must take into account in the dep graph,
-      # i.e., a struct.
-      if IsShortStructType(shortTypename, schema):
-        struct = schema[GetLongTypename(shortTypename, schema)]
-        # The keys in the struct dict are the member names
-        # The values in the struct dict are the member types
-        if struct:
-          # we reach this if struct is not None AND not empty
-          for field in GetStructFields(struct):
-            # we fill the chain of dependent types (starting here)
-            ancestors.append(shortTypename)
-            ComputeOrderFromTypeTree(
-              ancestors, genOrder, struct[field], schema)
-            # don't forget to restore it!
-            ancestors.pop()
-        
-        # now we're pretty sure our dependencies have been processed,
-        # we can start marking our code for generation (it might 
-        # already have been done if someone referenced us earlier)
-        if not shortTypename in genOrder:
-          genOrder.append(shortTypename)
-
-# +-----------------------+
-# |   Utility functions   |
-# +-----------------------+
-
-def IsShortStructType(typename, schema):
-  fullStructName = "struct " + typename
-  return (fullStructName in schema)
-
-def GetLongTypename(shortTypename, schema):
-  if shortTypename.startswith("enum "):
-    raise RuntimeError('shortTypename.startswith("enum "):')
-  enumName = "enum " + shortTypename
-  isEnum = enumName in schema
-
-  if shortTypename.startswith("struct "):
-    raise RuntimeError('shortTypename.startswith("struct "):')
-  structName = "struct " + shortTypename
-  isStruct = ("struct " + shortTypename) in schema
-
-  if isEnum and isStruct:
-    raise RuntimeError('Enums and structs cannot have the same name')
-
-  if isEnum:
-    return enumName
-  if isStruct:
-    return structName
-
-def IsTypename(fullName):
-  return (fullName.startswith("enum ") or fullName.startswith("struct "))
-
-def IsEnumType(fullName):
-  return fullName.startswith("enum ")
-
-def IsStructType(fullName):
-  return fullName.startswith("struct ")
-
-def GetShortTypename(fullTypename):
-  if fullTypename.startswith("struct "):
-    return fullTypename[7:] 
-  elif fullTypename.startswith("enum"):
-    return fullTypename[5:] 
-  else:
-    raise RuntimeError \
-      ('fullTypename should start with either "struct " or "enum "')
-
-def CheckSchemaSchema(schema):
-  if not "rootName" in schema:
-      raise Exception("schema lacks the 'rootName' key")
-  for name in schema.keys():
-    if (not IsEnumType(name)) and (not IsStructType(name)) and \
-      (name != 'rootName'):
-      raise RuntimeError \
-        ('Type "' + str(name) + '" should start with "enum " or "struct "')
-
-  # TODO: check enum fields are unique (in whole namespace)
-  # TODO: check struct fields are unique (in each struct)
-  # TODO: check that in the source schema, there are spaces after each colon
-
-nonTypeKeys = ['rootName']
-def GetTypesInSchema(schema):
-  """Returns the top schema keys that are actual type names"""
-  typeList = [k for k in schema if k not in nonTypeKeys]
-  return typeList
-
-# +-----------------------+
-# | Main processing logic |
-# +-----------------------+
-
-def ComputeRequiredDeclarationOrder(schema):
-  # sanity check
-  CheckSchemaSchema(schema)
-
-  # we traverse the type dependency graph and we fill a queue with
-  # the required struct types, in a bottom-up fashion, to compute
-  # the declaration order
-  # The genOrder list contains the struct full names in the order
-  # where they must be defined.
-  # We do not care about the enums here... They do not depend upon
-  # anything and we'll handle them, in their original declaration 
-  # order, at the start
-  genOrder = []
-  for fullName in GetTypesInSchema(schema):
-    if IsStructType(fullName):
-      realName = GetShortTypename(fullName)
-      ancestors = []
-      ComputeOrderFromTypeTree(ancestors, genOrder, realName, schema)
-  return genOrder
-
-def GetStructFields(fieldDict):
-  """Returns the regular (non __handler) struct fields"""
-  # the following happens for empty structs
-  if fieldDict == None:
-    return fieldDict
-  ret = {}
-  for k,v in fieldDict.items():
-    if k != "__handler":
-      ret[k] = FieldDefinition.fromKeyValue(k, v)
-    if k.startswith("__") and k != "__handler":
-      raise RuntimeError("Fields starting with __ (double underscore) are reserved names!")
-  return ret
-
-def GetStructMetadata(fieldDict):
-  """Returns the __handler struct fields (there are default values that
-     can be overridden by entries in the schema
-     Not tested because it's a fail-safe: if something is broken in this, 
-     dependent projects will not build."""
-  metadataDict = {}
-  metadataDict['handleInCpp'] = False
-  metadataDict['handleInTypescript'] = False
-  
-  if fieldDict != None:
-    for k,v in fieldDict.items():
-      if k.startswith("__") and k != "__handler":
-        raise RuntimeError("Fields starting with __ (double underscore) are reserved names")
-      if k == "__handler":
-        if type(v) == list:
-          for i in v:
-            if i == "cpp":
-              metadataDict['handleInCpp'] = True
-            elif i == "ts":
-              metadataDict['handleInTypescript'] = True
-            else:
-              raise RuntimeError("Error in schema. Allowed values for __handler are \"cpp\" or \"ts\"")
-        elif type(v) == str:
-          if v == "cpp":
-            metadataDict['handleInCpp'] = True
-          elif v == "ts":
-            metadataDict['handleInTypescript'] = True
-          else:
-            raise RuntimeError("Error in schema. Allowed values for __handler are \"cpp\" or \"ts\" (or a list of both)")
-        else:
-            raise RuntimeError("Error in schema. Allowed values for __handler are \"cpp\" or \"ts\" (or a list of both)")
-  return metadataDict
-
-def ProcessSchema(schema, genOrder):
-  # sanity check
-  CheckSchemaSchema(schema)
-
-  # let's doctor the schema to clean it up a bit
-  # order DOES NOT matter for enums, even though it's a list
-  enums = []
-  for fullName in schema.keys():
-    if IsEnumType(fullName):
-      # convert "enum Toto" to "Toto"
-      typename = GetShortTypename(fullName)
-      enum = {}
-      enum['name'] = typename
-      assert(type(schema[fullName]) == list)
-      enum['fields'] = schema[fullName] # must be a list
-      enums.append(enum)
-
-  # now that the order has been established, we actually store\
-  # the structs in the correct order
-  # the structs are like:
-  # example = [
-  #   {
-  #     "name": "Message1",
-  #     "fields": {
-  #       "someMember":"int32",
-  #       "someOtherMember":"vector<string>"
-  #     }
-  #   },
-  #   { 
-  #     "name": "Message2",
-  #     "fields": {
-  #       "someMember":"int32",
-  #       "someOtherMember22":"vector<Message1>"
-  #     }
-  #   }
-  # ]
-
-  structs = []
-  for i in range(len(genOrder)):
-    # this is already the short name
-    typename = genOrder[i]
-    fieldDict = schema["struct " + typename]
-    struct = {}
-    struct['name'] = typename
-    struct['fields'] = GetStructFields(fieldDict)
-    struct['__meta__'] = GetStructMetadata(fieldDict)
-    structs.append(struct)
-  
-  templatingDict = {}
-  templatingDict['enums'] = enums
-  templatingDict['structs'] = structs
-  templatingDict['rootName'] = schema['rootName']
-
-  return templatingDict
-
-# +-----------------------+
-# |    Write to files     |
-# +-----------------------+
-
-# def WriteStreamsToFiles(rootName: str, genc: Dict[str, StringIO]) \
-#   -> None:
-#   pass
-
-def LoadSchema(fn):
-  # latin-1 is a trick, when we do NOT care about NON-ascii chars but
-  # we wish to avoid using a decoding error handler
-  # (see http://python-notes.curiousefficiency.org/en/latest/python3/text_file_processing.html#files-in-an-ascii-compatible-encoding-best-effort-is-acceptable)
-  # TL;DR: all 256 values are mapped to characters in latin-1 so the file 
-  # contents never cause an error.
-  with open(fn, 'r', encoding='latin-1') as f:
-    schemaText = f.read()
-    assert(type(schemaText) == str)
-  return LoadSchemaFromString(schemaText = schemaText)
-
-def LoadSchemaFromString(schemaText:str):
-    # ensure there is a space after each colon. Otherwise, dicts could be
-    # erroneously recognized as an array of strings containing ':'
-    for i in range(len(schemaText)-1):
-      ch = schemaText[i]
-      nextCh = schemaText[i+1]
-      if ch == ':':
-        if not (nextCh == ' ' or nextCh == '\n'):
-          lineNumber = schemaText.count("\n",0,i) + 1
-          raise RuntimeError("Error at line " + str(lineNumber) + " in the schema: colons must be followed by a space or a newline!")
-    schema = yaml.load(schemaText, Loader = yamlloader.ordereddict.SafeLoader)
-    return schema
-
-def GetTemplatingDictFromSchemaFilename(fn):
-  return GetTemplatingDictFromSchema(LoadSchema(fn))
-
-def GetTemplatingDictFromSchema(schema):
-  genOrder = ComputeRequiredDeclarationOrder(schema)
-  templatingDict = ProcessSchema(schema, genOrder)
-  currentDT = datetime.datetime.now()
-  templatingDict['currentDatetime'] = str(currentDT)
-  return templatingDict
-
-# +-----------------------+
-# |      ENTRY POINT      |
-# +-----------------------+
-def Process(schemaFile, outDir):
-  tdico = GetTemplatingDictFromSchemaFilename(schemaFile)
-
-  tsTemplateFile = \
-    os.path.join(os.path.dirname(__file__), 'template.in.ts.j2')
-  template = MakeTemplateFromFile(tsTemplateFile)
-  renderedTsCode = template.render(**tdico)
-  outputTsFile = os.path.join( \
-    outDir,str(tdico['rootName']) + "_generated.ts")
-  with open(outputTsFile,"wt",encoding='utf8') as outFile:
-    outFile.write(renderedTsCode)
-
-  cppTemplateFile = \
-    os.path.join(os.path.dirname(__file__), 'template.in.h.j2')
-  template = MakeTemplateFromFile(cppTemplateFile)
-  renderedCppCode = template.render(**tdico)
-  outputCppFile = os.path.join( \
-    outDir, str(tdico['rootName']) + "_generated.hpp")
-  with open(outputCppFile,"wt",encoding='utf8') as outFile:
-    outFile.write(renderedCppCode)
-
-if __name__ == "__main__":
-  import argparse
-
-  parser = argparse.ArgumentParser(
-    usage="""stonegentool.py [-h] [-o OUT_DIR] [-v] input_schema
-    EXAMPLE: python stonegentool.py -o "generated_files/" """
-      + """ "mainSchema.yaml,App Specific Commands.json" """
-  )
-  parser.add_argument("input_schema", type=str, \
-    help="path to the schema file")
-  parser.add_argument(
-    "-o",
-    "--out_dir",
-    type=str,
-    default=".",
-    help="""path of the directory where the files 
-                          will be generated. Default is current
-                          working folder""",
-  )
-  parser.add_argument(
-    "-v",
-    "--verbosity",
-    action="count",
-    default=0,
-    help="""increase output verbosity (0 == errors 
-                          only, 1 == some verbosity, 2 == nerd
-                          mode""",
-  )
-
-  args = parser.parse_args()
-  schemaFile = args.input_schema
-  outDir = args.out_dir
-  Process(schemaFile, outDir)
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/stonegentool_test.py	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,438 +0,0 @@
-#
-#        1         2         3         4         5         6         7         8
-# 345678901234567890123456789012345678901234567890123456789012345678901234567890
-#
-
-from stonegentool import \
-EatToken,SplitListOfTypes,ParseTemplateType,ProcessSchema, \
-CheckSchemaSchema,LoadSchema,trim,ComputeRequiredDeclarationOrder, \
-GetTemplatingDictFromSchemaFilename,MakeTemplate,MakeTemplateFromFile,LoadSchemaFromString,GetTemplatingDictFromSchema
-import unittest
-import os
-import re
-import pprint
-from jinja2 import Template
-
-def RemoveDateTimeLine(s : str):
-  # regex are non-multiline by default, and $ does NOT match the end of the line
-  s2 = re.sub(r"^// autogenerated by stonegentool on .*\n","",s)
-  return s2
-
-class TestStonegentool(unittest.TestCase):
-  def test_EatToken_empty(self):
-    c = r""
-    a,b = EatToken(c)
-    self.assertEqual(a,r"")
-    self.assertEqual(b,r"")
-
-  def test_EatToken_simpleNonTemplate(self):
-    c = r"int32"
-    a,b = EatToken(c)
-    self.assertEqual(a,r"int32")
-    self.assertEqual(b,r"")
-
-  def test_EatToken_simpleTemplate(self):
-    c = r"vector<string>"
-    a,b = EatToken(c)
-    self.assertEqual(a,r"vector<string>")
-    self.assertEqual(b,r"")
-
-  def test_EatToken_complexTemplate(self):
-    c = r"vector<map<int64,string>>,vector<map<int32,string>>"
-    a,b = EatToken(c)
-    self.assertEqual(a,r"vector<map<int64,string>>")
-    self.assertEqual(b,r"vector<map<int32,string>>")
-
-  def test_EatToken_complexTemplates(self):
-    c = r"vector<map<vector<string>,map<int32,string>>>,map<int32,string>,map<map<int32,string>,string>"
-    a,b = EatToken(c)
-    self.assertEqual(a,r"vector<map<vector<string>,map<int32,string>>>")
-    self.assertEqual(b,r"map<int32,string>,map<map<int32,string>,string>")
-    a,b = EatToken(b)
-    self.assertEqual(a,r"map<int32,string>")
-    self.assertEqual(b,r"map<map<int32,string>,string>")
-
-  def test_SplitListOfTypes(self):
-    c = r"vector<map<vector<string>,map<int32,string>>>,map<int32,string>,map<map<int32,string>,string>"
-    lot = SplitListOfTypes(c)
-    self.assertEqual(3,len(lot))
-    self.assertEqual("vector<map<vector<string>,map<int32,string>>>",lot[0])
-    self.assertEqual("map<int32,string>",lot[1])
-    self.assertEqual("map<map<int32,string>,string>",lot[2])
-
-  def test_SplitListOfTypes_bogus(self):
-    c = r"vector<map<vector<string>,map<int32,string>>,map<int32,string>,map<map<int32,string>,string"
-    self.assertRaises(Exception,SplitListOfTypes,c) # the argument c must be passed to assertRaises, not as a normal call of SplitListOfTypes
-    
-  def test_ParseTemplateType_true(self):
-    c = "map<vector<map<int,vector<string>>>,map<vector<int>,vector<string>>>"
-    (ok,a,b) = ParseTemplateType(c)
-    self.assertEqual(ok,True)
-    self.assertEqual(a,"map")
-    self.assertEqual(b,["vector<map<int,vector<string>>>","map<vector<int>,vector<string>>"])
-
-    (ok2,a2,b2) = ParseTemplateType(b[0])
-    self.assertEqual(ok2,True)
-    self.assertEqual(a2,"vector")
-    self.assertEqual(b2,["map<int,vector<string>>"])
-
-    (ok3,a3,b3) = ParseTemplateType(b[1])
-    self.assertEqual(ok3,True)
-    self.assertEqual(a3,"map")
-    self.assertEqual(b3,["vector<int>","vector<string>"])
-
-    (ok4,a4,b4) = ParseTemplateType(b2[0])
-    self.assertEqual(ok4,True)
-    self.assertEqual(a4,"map")
-    self.assertEqual(b4,["int","vector<string>"])
-    
-  def test_ParseSchema(self):
-    fn = os.path.join(os.path.dirname(__file__), 'test_data', 'testTestStoneCodeGen.yaml')
-    obj = LoadSchema(fn)
-    # we're happy if it does not crash :)
-    CheckSchemaSchema(obj)
-
-  def test_ComputeRequiredDeclarationOrder(self):
-    fn = os.path.join(os.path.dirname(__file__), 'test_data', 'testTestStoneCodeGen.yaml')
-    obj = LoadSchema(fn)
-    genOrder: str = ComputeRequiredDeclarationOrder(obj)
-    self.assertEqual(5,len(genOrder))
-    self.assertEqual("A",genOrder[0])
-    self.assertEqual("B",genOrder[1])
-    self.assertEqual("C",genOrder[2])
-    self.assertEqual("Message1",genOrder[3])
-    self.assertEqual("Message2",genOrder[4])
-
-  # def test_GeneratePreambleEnumerationAndStructs(self):
-  #   fn = os.path.join(os.path.dirname(__file__), 'test', 'test1.jsonc')
-  #   obj = LoadSchema(fn)
-  #   (_,genc,_) = ProcessSchema(obj)
-
-  def test_genEnums(self):
-    self.maxDiff = None
-    fn = os.path.join(os.path.dirname(__file__), 'test_data', 'testTestStoneCodeGen.yaml')
-    obj = LoadSchema(fn)
-    genOrder: str = ComputeRequiredDeclarationOrder(obj)
-    processedSchema = ProcessSchema(obj, genOrder)
-    self.assertTrue('rootName' in processedSchema)
-
-    structs = {}
-    for v in processedSchema['structs']:
-      structs[v['name']] = v
-    enums = {}
-    for v in processedSchema['enums']:
-      enums[v['name']] = v
-
-    self.assertTrue('C' in structs)
-    self.assertTrue('someBs' in structs['C']['fields'])
-    self.assertTrue('CrispType' in enums)
-    self.assertTrue('Message1' in structs)
-    self.assertEqual('int32', structs['Message1']['fields']['memberInt32'].type)
-    self.assertEqual('string', structs['Message1']['fields']['memberString'].type)
-    self.assertEqual('EnumMonth0', structs['Message1']['fields']['memberEnumMonth'].type)
-    self.assertEqual('bool', structs['Message1']['fields']['memberBool'].type)
-    self.assertEqual('float32', structs['Message1']['fields']['memberFloat32'].type)
-    self.assertEqual('float64', structs['Message1']['fields']['memberFloat64'].type)
-
-  def test_GenerateTypeScriptEnums(self):
-    fn = os.path.join(os.path.dirname(__file__), 'test_data', 'testTestStoneCodeGen.yaml')
-    tdico = GetTemplatingDictFromSchemaFilename(fn)
-    template = Template("""  // end of generic methods
-{% for enum in enums%}  export enum {{enum['name']}} {
-{% for key in enum['fields']%}    {{key}},
-{%endfor%}  };
-
-{%endfor%}""")
-    renderedCode = template.render(**tdico)
-    renderedCodeRef = """  // end of generic methods
-  export enum MovieType {
-    RomCom,
-    Horror,
-    ScienceFiction,
-    Vegetables,
-  };
-
-  export enum CrispType {
-    SaltAndPepper,
-    CreamAndChives,
-    Paprika,
-    Barbecue,
-  };
-
-  export enum EnumMonth0 {
-    January,
-    February,
-    March,
-  };
-
-"""
-    self.assertEqual(renderedCodeRef,renderedCode)
-
-  def test_GenerateCplusplusEnums(self):
-    fn = os.path.join(os.path.dirname(__file__), 'test_data', 'testTestStoneCodeGen.yaml')
-    tdico = GetTemplatingDictFromSchemaFilename(fn)
-    template = Template("""  // end of generic methods
-{% for enum in enums%}  enum {{enum['name']}} {
-{% for key in enum['fields']%}    {{key}},
-{%endfor%}  };
-
-{%endfor%}""")
-    renderedCode = template.render(**tdico)
-    renderedCodeRef = """  // end of generic methods
-  enum MovieType {
-    RomCom,
-    Horror,
-    ScienceFiction,
-    Vegetables,
-  };
-
-  enum CrispType {
-    SaltAndPepper,
-    CreamAndChives,
-    Paprika,
-    Barbecue,
-  };
-
-  enum EnumMonth0 {
-    January,
-    February,
-    March,
-  };
-
-"""
-    self.assertEqual(renderedCodeRef,renderedCode)
-
-  def test_generateTsStructType(self):
-    fn = os.path.join(os.path.dirname(__file__), 'test_data', 'testTestStoneCodeGen.yaml')
-    tdico = GetTemplatingDictFromSchemaFilename(fn)
-
-#     template = MakeTemplate("""  // end of generic methods
-# {% for struct in struct%}  export class {{struct['name']}} {
-#   {% for key in struct['fields']%}    {{key}}:{{struct['fields'][key]}},
-#   {% endfor %}  
-#     constructor() {
-#   {% for key in struct['fields']%}
-#     {% if NeedsConstruction(struct['fields']['key'])}
-#       {{key}} = new {{CanonToTs(struct['fields']['key'])}};
-#     {% end if %}
-#   {% endfor %}
-#     }
-# {% endfor %}
-#     public StoneSerialize(): string {
-#       let container: object = {};
-#       container['type'] = '{{rootName}}.{{struct['name']}}';
-#       container['value'] = this;
-#       return JSON.stringify(container);
-#     }  };""")
-    template = MakeTemplate("""  // end of generic methods
-{% for struct in structs%}  export class {{struct['name']}} {
-{% for key in struct['fields']%}    {{key}}:{{CanonToTs(struct['fields'][key]['type'])}};
-{% endfor %}
-    constructor() {
-{% for key in struct['fields']%}      this.{{key}} = new {{CanonToTs(struct['fields'][key]['type'])}}();
-{% endfor %}    }
-
-    public StoneSerialize(): string {
-      let container: object = {};
-      container['type'] = '{{rootName}}.{{struct['name']}}';
-      container['value'] = this;
-      return JSON.stringify(container);
-    }
-  };
-
-{% endfor %}""")
-    renderedCode = template.render(**tdico)
-    renderedCodeRef = """  // end of generic methods
-  export class A {
-    someStrings:Array<string>;
-    someInts2:Array<number>;
-    movies:Array<MovieType>;
-
-    constructor() {
-      this.someStrings = new Array<string>();
-      this.someInts2 = new Array<number>();
-      this.movies = new Array<MovieType>();
-    }
-
-    public StoneSerialize(): string {
-      let container: object = {};
-      container['type'] = 'TestStoneCodeGen.A';
-      container['value'] = this;
-      return JSON.stringify(container);
-    }
-  };
-
-  export class B {
-    someAs:Array<A>;
-    someInts:Array<number>;
-
-    constructor() {
-      this.someAs = new Array<A>();
-      this.someInts = new Array<number>();
-    }
-
-    public StoneSerialize(): string {
-      let container: object = {};
-      container['type'] = 'TestStoneCodeGen.B';
-      container['value'] = this;
-      return JSON.stringify(container);
-    }
-  };
-
-  export class C {
-    someBs:Array<B>;
-    ddd:Array<string>;
-
-    constructor() {
-      this.someBs = new Array<B>();
-      this.ddd = new Array<string>();
-    }
-
-    public StoneSerialize(): string {
-      let container: object = {};
-      container['type'] = 'TestStoneCodeGen.C';
-      container['value'] = this;
-      return JSON.stringify(container);
-    }
-  };
-
-  export class Message1 {
-    memberInt32:number;
-    memberString:string;
-    memberEnumMonth:EnumMonth0;
-    memberBool:boolean;
-    memberFloat32:number;
-    memberFloat64:number;
-
-    constructor() {
-      this.memberInt32 = new number();
-      this.memberString = new string();
-      this.memberEnumMonth = new EnumMonth0();
-      this.memberBool = new boolean();
-      this.memberFloat32 = new number();
-      this.memberFloat64 = new number();
-    }
-
-    public StoneSerialize(): string {
-      let container: object = {};
-      container['type'] = 'TestStoneCodeGen.Message1';
-      container['value'] = this;
-      return JSON.stringify(container);
-    }
-  };
-
-  export class Message2 {
-    memberString:string;
-    memberStringWithDefault:string;
-    memberVectorOfMessage1:Array<Message1>;
-    memberVectorOfString:Array<string>;
-    memberMapStringString:Map<string, string>;
-    memberMapStringStruct:Map<string, Message1>;
-    memberMapEnumFloat:Map<CrispType, number>;
-    memberEnumMovieType:MovieType;
-    memberJson:Object;
-
-    constructor() {
-      this.memberString = new string();
-      this.memberStringWithDefault = new string();
-      this.memberVectorOfMessage1 = new Array<Message1>();
-      this.memberVectorOfString = new Array<string>();
-      this.memberMapStringString = new Map<string, string>();
-      this.memberMapStringStruct = new Map<string, Message1>();
-      this.memberMapEnumFloat = new Map<CrispType, number>();
-      this.memberEnumMovieType = new MovieType();
-      this.memberJson = new Object();
-    }
-
-    public StoneSerialize(): string {
-      let container: object = {};
-      container['type'] = 'TestStoneCodeGen.Message2';
-      container['value'] = this;
-      return JSON.stringify(container);
-    }
-  };
-
-"""
-    # print(renderedCode)
-    self.maxDiff = None
-    self.assertEqual(renderedCodeRef, renderedCode)
-
-  def test_generateWholeTsFile(self):
-    schemaFile = \
-      os.path.join(os.path.dirname(__file__), 'test_data', 'testTestStoneCodeGen.yaml')
-    tdico = GetTemplatingDictFromSchemaFilename(schemaFile)
-    tsTemplateFile = \
-      os.path.join(os.path.dirname(__file__), 'template.in.ts.j2')
-    template = MakeTemplateFromFile(tsTemplateFile)
-    renderedCode = template.render(**tdico)
-    print(renderedCode)
-
-  def test_GenerateTypeScriptHandlerInterface(self):
-    pass
-
-  def test_GenerateCppHandlerInterface(self):
-    pass
-
-  def test_GenerateTypeScriptDispatcher(self):
-    pass
-
-  def test_GenerateCppDispatcher(self):
-    pass
-
-  def test_StringDefaultValueInTs(self):
-    schema = LoadSchemaFromString("""
-                                  rootName: MyTest
-                                  struct Toto:
-                                    withoutDefault: string
-                                    withDefault: string = \"tutu\"
-                                  """)
-    tdico = GetTemplatingDictFromSchema(schema)
-
-    tsTemplateFile = os.path.join(os.path.dirname(__file__), 'template.in.ts.j2')
-    template = MakeTemplateFromFile(tsTemplateFile)
-    renderedCode = template.render(**tdico)
-    self.assertIn("withDefault = \"tutu\"", renderedCode)
-    # print(renderedCode)
-
-    cppTemplateFile = os.path.join(os.path.dirname(__file__), 'template.in.h.j2')
-    template = MakeTemplateFromFile(cppTemplateFile)
-    renderedCode = template.render(**tdico)
-    print(renderedCode)
-    self.assertIn("withDefault = \"tutu\"", renderedCode)
-
-
-  def test_EnumDefaultValue(self):
-    schema = LoadSchemaFromString("""
-                                  rootName: MyTest
-                                  enum MyEnum:
-                                    - Toto
-                                    - Tutu
-                                  struct Toto:
-                                    withoutDefault: MyEnum
-                                    withDefault: MyEnum = Toto
-                                  """)
-    tdico = GetTemplatingDictFromSchema(schema)
-
-    tsTemplateFile = os.path.join(os.path.dirname(__file__), 'template.in.ts.j2')
-    template = MakeTemplateFromFile(tsTemplateFile)
-    renderedCode = template.render(**tdico)
-    # print(renderedCode)
-    self.assertIn("withDefault = MyEnum.Toto", renderedCode)
-
-    tsTemplateFile = os.path.join(os.path.dirname(__file__), 'template.in.h.j2')
-    template = MakeTemplateFromFile(tsTemplateFile)
-    renderedCode = template.render(**tdico)
-    self.assertIn("withDefault = MyTest::MyEnum_Toto", renderedCode)
-    # print(renderedCode)
-
-
-# def test(self):
-#   s = 'hello world'
-#   self.assertEqual(s.split(), ['hello', 'world'])
-#   # check that s.split fails when the separator is not a string
-#   with self.assertRaises(TypeError):
-#   s.split(2)
-
-if __name__ == '__main__':
-  unittest.main()
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/template.in.h.j2	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,551 +0,0 @@
-/*
-         1         2         3         4         5         6         7
-12345678901234567890123456789012345678901234567890123456789012345678901234567890
-
-Generated on {{currentDatetime}} by stonegentool
-
-*/
-#pragma once
-
-#include <exception>
-#include <iostream>
-#include <string>
-#include <sstream>
-#include <assert.h>
-#include <memory>
-#include <set>
-#include <json/json.h>
-
-//#define STONEGEN_NO_CPP11 1
-
-#ifdef STONEGEN_NO_CPP11
-#define StoneSmartPtr std::unique_ptr
-#else 
-#define StoneSmartPtr std::unique_ptr
-#endif 
-
-namespace {{rootName}}
-{
-  /** Throws in case of problem */
-  inline void _StoneDeserializeValue(int32_t& destValue, const Json::Value& jsonValue)
-  {
-    if (!jsonValue.isNull())
-    {
-      destValue = jsonValue.asInt();
-    }
-  }
-
-  inline Json::Value _StoneSerializeValue(int32_t value)
-  {
-    Json::Value result(value);
-    return result;
-  }
-
-  inline void _StoneDeserializeValue(int64_t& destValue, const Json::Value& jsonValue)
-  {
-    if (!jsonValue.isNull())
-    {
-      destValue = jsonValue.asInt64();
-    }
-  }
-
-  inline Json::Value _StoneSerializeValue(int64_t value)
-  {
-    Json::Value result(static_cast<Json::Value::Int64>(value));
-    return result;
-  }
-
-  inline void _StoneDeserializeValue(uint32_t& destValue, const Json::Value& jsonValue)
-  {
-    if (!jsonValue.isNull())
-    {
-      destValue = jsonValue.asUInt();
-    }
-  }
-
-  inline Json::Value _StoneSerializeValue(uint32_t value)
-  {
-    Json::Value result(value);
-    return result;
-  }
-
-  inline void _StoneDeserializeValue(uint64_t& destValue, const Json::Value& jsonValue)
-  {
-    if (!jsonValue.isNull())
-    {
-      destValue = jsonValue.asUInt64();
-    }
-  }
-
-  inline Json::Value _StoneSerializeValue(uint64_t value)
-  {
-    Json::Value result(static_cast<Json::Value::UInt64>(value));
-    return result;
-  }
-
-  inline void _StoneDeserializeValue(Json::Value& destValue, const Json::Value& jsonValue)
-  {
-    destValue = jsonValue;
-  }
-
-  inline Json::Value _StoneSerializeValue(Json::Value value)
-  {
-    return value;
-  }
-
-  /** Throws in case of problem */
-  inline void _StoneDeserializeValue(double& destValue, const Json::Value& jsonValue)
-  {
-    if (!jsonValue.isNull())
-    {
-      destValue = jsonValue.asDouble();
-    }
-  }
-
-  inline Json::Value _StoneSerializeValue(double value)
-  {
-    Json::Value result(value);
-    return result;
-  }
-
-  /** Throws in case of problem */
-  inline void _StoneDeserializeValue(float& destValue, const Json::Value& jsonValue)
-  {
-    if (!jsonValue.isNull())
-    {
-      destValue = jsonValue.asFloat();
-    }
-  }
-
-  inline Json::Value _StoneSerializeValue(float value)
-  {
-    Json::Value result(value);
-    return result;
-  }
-
-  /** Throws in case of problem */
-  inline void _StoneDeserializeValue(bool& destValue, const Json::Value& jsonValue)
-  {
-    if (!jsonValue.isNull())
-    {
-      destValue = jsonValue.asBool();
-    }
-  }
-
-  inline Json::Value _StoneSerializeValue(bool value)
-  {
-    Json::Value result(value);
-    return result;
-  }
-
-  /** Throws in case of problem */
-  inline void _StoneDeserializeValue(
-       std::string& destValue
-     , const Json::Value& jsonValue)
-  {
-    if (!jsonValue.isNull())
-    {
-      destValue = jsonValue.asString();
-    }
-  }
-
-  inline Json::Value _StoneSerializeValue(const std::string& value)
-  {
-    // the following is better than 
-    Json::Value result(value.data(),value.data()+value.size());
-    return result;
-  }
-
-  inline std::string MakeIndent(size_t indent)
-  {
-    char* txt = reinterpret_cast<char*>(malloc(indent+1)); // NO EXCEPTION BELOW!!!!!!!!!!!!
-    for(size_t i = 0; i < indent; ++i)
-      txt[i] = ' ';
-    txt[indent] = 0;
-    std::string retVal(txt);
-    free(txt); // NO EXCEPTION ABOVE !!!!!!!!!!
-    return retVal;
-  }
-
-  // generic dumper
-  template<typename T>
-  std::ostream& StoneDumpValue(std::ostream& out, const T& value, size_t indent)
-  {
-    out << MakeIndent(indent) << value;
-    return out;
-  }
-
-  // string dumper
-  inline std::ostream& StoneDumpValue(std::ostream& out, const std::string& value, size_t indent)
-  {
-    out << MakeIndent(indent) << "\"" << value  << "\"";
-    return out;
-  }
-
-  inline std::string ToString(const std::string& str)
-  {
-    return str;
-  }
-
-  inline void FromString(std::string& value, std::string strValue)
-  {
-    value = strValue;
-  }
-
-
-  /** Throws in case of problem */
-  template<typename TK, typename TV>
-  void _StoneDeserializeValue(
-    std::map<TK, TV>& destValue, const Json::Value& jsonValue)
-  {
-    if (!jsonValue.isNull())
-    {
-      destValue.clear();
-      for (
-        Json::Value::const_iterator itr = jsonValue.begin();
-        itr != jsonValue.end();
-        itr++)
-      {
-        std::string strKey;
-        _StoneDeserializeValue(strKey, itr.key());
-        TK key;
-        FromString(key, strKey);  // if you have a compile error here, it means that your type is not suitable to be the key of a map (or you should overwrite the FromString/ToString in template.in.h.j2)
-
-        TV innerDestValue;
-        _StoneDeserializeValue(innerDestValue, *itr);
-
-        destValue[key] = innerDestValue;
-      }
-    }
-  }
-
-  template<typename TK, typename TV>
-  Json::Value _StoneSerializeValue(const std::map<TK, TV>& value)
-  {
-    Json::Value result(Json::objectValue);
-
-    for (typename std::map<TK, TV>::const_iterator it = value.cbegin();
-      it != value.cend(); ++it)
-    {
-      // it->first it->second
-      result[ToString(it->first)] = _StoneSerializeValue(it->second);
-    }
-    return result;
-  }
-
-  template<typename TK, typename TV>
-  std::ostream& StoneDumpValue(std::ostream& out, const std::map<TK, TV>& value, size_t indent)
-  {
-    out << MakeIndent(indent) << "{\n";
-    for (typename std::map<TK, TV>::const_iterator it = value.cbegin();
-      it != value.cend(); ++it)
-    {
-      out << MakeIndent(indent+2) << "\"" << it->first << "\" : ";
-      StoneDumpValue(out, it->second, indent+2);
-      out << ", \n";
-    }
-    out << MakeIndent(indent) << "}\n";
-    return out;
-  }
-
-  /** Throws in case of problem */
-  template<typename T>
-  void _StoneDeserializeValue(
-    std::vector<T>& destValue, const Json::Value& jsonValue)
-  {
-    if (!jsonValue.isNull() && jsonValue.isArray())
-    {
-      destValue.clear();
-      destValue.reserve(jsonValue.size());
-      for (Json::Value::ArrayIndex i = 0; i != jsonValue.size(); i++)
-      {
-        T innerDestValue;
-        _StoneDeserializeValue(innerDestValue, jsonValue[i]);
-        destValue.push_back(innerDestValue);
-      }
-    }
-  }
-
-  template<typename T>
-  Json::Value _StoneSerializeValue(const std::vector<T>& value)
-  {
-    Json::Value result(Json::arrayValue);
-    for (size_t i = 0; i < value.size(); ++i)
-    {
-      result.append(_StoneSerializeValue(value[i]));
-    }
-    return result;
-  }
-
-  template<typename T>
-  std::ostream& StoneDumpValue(std::ostream& out, const std::vector<T>& value, size_t indent)
-  {
-    out << MakeIndent(indent) << "[\n";
-    for (size_t i = 0; i < value.size(); ++i)
-    {
-      StoneDumpValue(out, value[i], indent+2);
-      out << ", \n";
-    }
-    out << MakeIndent(indent) << "]\n";
-    return out;
-  }
-
-  /** Throws in case of problem */
-  template<typename T>
-  void _StoneDeserializeValue(
-    std::set<T>& destValue, const Json::Value& jsonValue)
-  {
-    if (!jsonValue.isNull() && jsonValue.isArray())
-    {
-      destValue.clear();
-      for (Json::Value::ArrayIndex i = 0; i != jsonValue.size(); i++)
-      {
-        T innerDestValue;
-        _StoneDeserializeValue(innerDestValue, jsonValue[i]);
-        destValue.insert(innerDestValue);
-      }
-    }
-  }
-
-  template<typename T>
-  Json::Value _StoneSerializeValue(const std::set<T>& value)
-  {
-    Json::Value result(Json::arrayValue);
-    for (typename std::set<T>::const_iterator it = value.begin(); it != value.end(); ++it)
-    {
-      result.append(_StoneSerializeValue(*it));
-    }
-    return result;
-  }
-
-  template<typename T>
-  std::ostream& StoneDumpValue(std::ostream& out, const std::set<T>& value, size_t indent)
-  {
-    out << MakeIndent(indent) << "[\n";
-    for (typename std::set<T>::const_iterator it = value.begin(); it != value.end(); ++it)
-    {
-      StoneDumpValue(out, *it, indent+2);
-      out << ", \n";
-    }
-    out << MakeIndent(indent) << "]\n";
-    return out;
-  }
-
-  inline void StoneCheckSerializedValueTypeGeneric(const Json::Value& value)
-  {
-    if ((!value.isMember("type")) || (!value["type"].isString()))
-    {
-      std::stringstream ss;
-      ss << "Cannot deserialize value ('type' key invalid)";
-      throw std::runtime_error(ss.str());
-    }
-  }
-
-  inline void StoneCheckSerializedValueType(
-    const Json::Value& value, std::string typeStr)
-  {
-    StoneCheckSerializedValueTypeGeneric(value);
-
-    std::string actTypeStr = value["type"].asString();
-    if (actTypeStr != typeStr)
-    {
-      std::stringstream ss;
-      ss << "Cannot deserialize type" << actTypeStr
-        << "into " << typeStr;
-      throw std::runtime_error(ss.str());
-    }
-  }
-
-  // end of generic methods
-
-// end of generic methods
-{% for enum in enums%}
-  enum {{enum['name']}} {
-{% for key in enum['fields']%}    {{enum['name']}}_{{key}},
-{%endfor%}  };
-
-  inline std::string ToString(const {{enum['name']}}& value)
-  {
-{% for key in enum['fields']%}    if( value == {{enum['name']}}_{{key}})
-    {
-      return std::string("{{key}}");
-    }
-{%endfor%}    std::stringstream ss;
-    ss << "Value \"" << value << "\" cannot be converted to {{enum['name']}}. Possible values are: "
-{% for key in enum['fields']%}        << " {{key}} = " << static_cast<int64_t>({{enum['name']}}_{{key}})  << ", " 
-{% endfor %}        << std::endl;
-    std::string msg = ss.str();
-    throw std::runtime_error(msg);
-  }
-
-  inline void FromString({{enum['name']}}& value, std::string strValue)
-  {
-{% for key in enum['fields']%}    if( strValue == std::string("{{key}}") )
-    {
-      value = {{enum['name']}}_{{key}};
-      return;
-    }
-{%endfor%}
-    std::stringstream ss;
-    ss << "String \"" << strValue << "\" cannot be converted to {{enum['name']}}. Possible values are: {% for key in enum['fields']%}{{key}} {% endfor %}";
-    std::string msg = ss.str();
-    throw std::runtime_error(msg);
-  }
-
-
-  inline void _StoneDeserializeValue(
-    {{enum['name']}}& destValue, const Json::Value& jsonValue)
-  {
-    if (!jsonValue.isNull())
-    {
-      FromString(destValue, jsonValue.asString());
-    }
-  }
-
-  inline Json::Value _StoneSerializeValue(const {{enum['name']}}& value)
-  {
-    std::string strValue = ToString(value);
-    return Json::Value(strValue);
-  }
-
-  inline std::ostream& StoneDumpValue(std::ostream& out, const {{enum['name']}}& value, size_t indent = 0)
-  {
-{% for key in enum['fields']%}    if( value == {{enum['name']}}_{{key}})
-    {
-      out << MakeIndent(indent) << "{{key}}";
-    }
-{%endfor%}    return out;
-  }
-
-{%endfor%}
-{% for struct in structs%}
-#ifdef _MSC_VER
-#pragma region {{struct['name']}}
-#endif //_MSC_VER
-
-  struct {{struct['name']}}
-  {
-{% if struct %}{% if struct['fields'] %}{% for key in struct['fields'] %}    {{CanonToCpp(struct['fields'][key]['type'])}} {{key}};
-{% endfor %}{% endif %}{% endif %}
-    {{struct['name']}}({% if struct %}{% if struct['fields'] %}{% for key in struct['fields'] %}{{CanonToCpp(struct['fields'][key]['type'])}} {{key}} = {% if struct['fields'][key]['defaultValue'] %}{{DefaultValueToCpp(rootName,enums,struct['fields'][key])}} {%else%} {{CanonToCpp(struct['fields'][key]['type'])}}() {%endif%} {{ ", " if not loop.last }}{% endfor %}{% endif %}{% endif %})
-    {
-{% if struct %}{% if struct['fields'] %}{% for key in struct['fields']%}      this->{{key}} = {{key}};
-{% endfor %}{% endif %}{% endif %}    }
-  };
-
-  inline void _StoneDeserializeValue({{struct['name']}}& destValue, const Json::Value& value)
-  {
-    if (!value.isNull())
-    {
-{% if struct %}{% if struct['fields'] %}{% for key in struct['fields']%}      _StoneDeserializeValue(destValue.{{key}}, value["{{key}}"]);
-{% endfor %}{% endif %}{% endif %}    }
-  }
-
-  inline Json::Value _StoneSerializeValue(const {{struct['name']}}& value)
-  {
-    Json::Value result(Json::objectValue);
-{% if struct %}{% if struct['fields'] %}{% for key in struct['fields']%}    result["{{key}}"] = _StoneSerializeValue(value.{{key}});
-{% endfor %}{% endif %}{% endif %}
-    return result;
-  }
-
-  inline std::ostream& StoneDumpValue(std::ostream& out, const {{struct['name']}}& value, size_t indent = 0)
-  {
-    out << MakeIndent(indent) << "{\n";
-{% if struct %}{% if struct['fields'] %}{% for key in struct['fields']%}    out << MakeIndent(indent+2) << "{{key}}: ";
-    StoneDumpValue(out, value.{{key}},indent+2);
-    out << ", \n";
-{% endfor %}{% endif %}{% endif %}
-    out << MakeIndent(indent) << "}";
-    return out;
-  }
-
-  inline void StoneDeserialize({{struct['name']}}& destValue, const Json::Value& value)
-  {
-    StoneCheckSerializedValueType(value, "{{rootName}}.{{struct['name']}}");
-    _StoneDeserializeValue(destValue, value["value"]);
-  }
-
-  inline Json::Value StoneSerializeToJson(const {{struct['name']}}& value)
-  {
-    Json::Value result(Json::objectValue);
-    result["type"] = "{{rootName}}.{{struct['name']}}";
-    result["value"] = _StoneSerializeValue(value);
-    return result;
-  }
-
-  inline std::string StoneSerialize(const {{struct['name']}}& value)
-  {
-    Json::Value resultJson = StoneSerializeToJson(value);
-    std::string resultStr = resultJson.toStyledString();
-    return resultStr;
-  }
-
-#ifdef _MSC_VER
-#pragma endregion {{struct['name']}}
-#endif //_MSC_VER
-{% endfor %}
-#ifdef _MSC_VER
-#pragma region Dispatching code
-#endif //_MSC_VER
-
-  class IHandler
-  {
-  public:
-{% for struct in structs%}{% if struct['__meta__'].handleInCpp %}    virtual bool Handle(const {{struct['name']}}& value) = 0;
-{% endif %}{% endfor %}  };
-
-  /** Service function for StoneDispatchToHandler */
-  inline bool StoneDispatchJsonToHandler(
-    const Json::Value& jsonValue, IHandler* handler)
-  {
-    StoneCheckSerializedValueTypeGeneric(jsonValue);
-    std::string type = jsonValue["type"].asString();
-    if (type == "")
-    {
-      // this should never ever happen
-      throw std::runtime_error("Caught empty type while dispatching");
-    }
-{% for struct in structs%}{% if struct['__meta__'].handleInCpp %}    else if (type == "{{rootName}}.{{struct['name']}}")
-    {
-      {{struct['name']}} value;
-      _StoneDeserializeValue(value, jsonValue["value"]);
-      return handler->Handle(value);
-    }
-{% endif %}{% endfor %}    else
-    {
-      return false;
-    }
-  }
-
-  /** Takes a serialized type and passes this to the handler */
-  inline bool StoneDispatchToHandler(std::string strValue, IHandler* handler)
-  {
-    Json::Value readValue;
-
-    Json::CharReaderBuilder builder;
-    Json::CharReader* reader = builder.newCharReader();
-
-    StoneSmartPtr<Json::CharReader> ptr(reader);
-
-    std::string errors;
-
-    bool ok = reader->parse(
-      strValue.c_str(),
-      strValue.c_str() + strValue.size(),
-      &readValue,
-      &errors
-    );
-    if (!ok)
-    {
-      std::stringstream ss;
-      ss << "Jsoncpp parsing error: " << errors;
-      throw std::runtime_error(ss.str());
-    }
-    return StoneDispatchJsonToHandler(readValue, handler);
-  }
-
-#ifdef _MSC_VER
-#pragma endregion Dispatching code
-#endif //_MSC_VER
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/template.in.ts.j2	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,136 +0,0 @@
-/*
-         1         2         3         4         5         6         7
-12345678901234567890123456789012345678901234567890123456789012345678901234567890
-
-Generated on {{currentDatetime}} by stonegentool
-
-*/
-
-function StoneCheckSerializedValueType(value: any, typeStr: string)
-{
-  StoneCheckSerializedValueTypeGeneric(value);
-
-  if (value['type'] != typeStr)
-  {
-    throw new Error(
-      `Cannot deserialize type ${value['type']} into ${typeStr}`);
-  }
-}
-
-function isString(val: any) :boolean
-{
-  return ((typeof val === 'string') || (val instanceof String));
-}
-
-function StoneCheckSerializedValueTypeGeneric(value: any)
-{
-  // console.//log("+-------------------------------------------------+");
-  // console.//log("|            StoneCheckSerializedValueTypeGeneric |");
-  // console.//log("+-------------------------------------------------+");
-  // console.//log("value = ");
-  // console.//log(value);
-  if ( (!('type' in value)) || (!isString(value.type)) )
-  {
-    throw new Error(
-      "Cannot deserialize value ('type' key invalid)");
-  }
-}
-
-// end of generic methods
-{% for enum in enums%}
-export enum {{enum['name']}} {
-{% for key in enum['fields']%}  {{key}} = "{{key}}"{% if not loop.last %},{%endif%}
-{%endfor%}};
-
-export function {{enum['name']}}_FromString(strValue:string) : {{enum['name']}}
-{
-{% for key in enum['fields'] %}  if( strValue == "{{key}}" )
-  {
-    return {{enum['name']}}.{{key}};
-  }
-{%endfor%}
-  let msg : string =  `String ${strValue} cannot be converted to {{enum['name']}}. Possible values are: {% for key in enum['fields']%}{{key}}{% if not loop.last %}, {%endif%}{% endfor %}`;
-  throw new Error(msg);
-}
-
-export function {{enum['name']}}_ToString(value:{{enum['name']}}) : string
-{
-{% for key in enum['fields'] %}  if( value == {{enum['name']}}.{{key}} )
-  {
-    return "{{key}}";
-  }
-{%endfor%}
-  let msg : string = `Value ${value} cannot be converted to {{enum['name']}}. Possible values are: `;
-{% for key in enum['fields']%}  {
-    let _{{key}}_enumValue : string = {{enum['name']}}.{{key}}; // enums are strings in stonecodegen, so this will work.
-    let msg_{{key}} : string = `{{key}} (${_{{key}}_enumValue}){% if not loop.last %}, {%endif%}`;
-    msg = msg + msg_{{key}};
-  }
-{%endfor%}  throw new Error(msg);
-}
-{%endfor%}
-
-
-{% for struct in structs%}export class {{struct['name']}} {
-{% if struct %}{% if struct['fields'] %}{% for key in struct['fields']%}  {{key}}:{{CanonToTs(struct['fields'][key]['type'])}};
-{% endfor %}{% endif %}{% endif %}
-  constructor() {
-{% if struct %}{% if struct['fields'] %}{% for key in struct['fields']%}{% if NeedsTsConstruction(enums,CanonToTs(struct['fields'][key]['type'])) %}    this.{{key}} = new {{CanonToTs(struct['fields'][key]['type'])}}();
-{% endif %}
-{% if struct['fields'][key]['defaultValue'] %}    this.{{key}} = {{DefaultValueToTs(enums,struct['fields'][key])}};
-{% endif %}{% endfor %}{% endif %}{% endif %}  }
-
-  public StoneSerialize(): string {
-    let container: object = {};
-    container['type'] = '{{rootName}}.{{struct['name']}}';
-    container['value'] = this;
-    return JSON.stringify(container);
-  }
-
-  public static StoneDeserialize(valueStr: string) : {{struct['name']}}
-  {
-    let value: any = JSON.parse(valueStr);
-    StoneCheckSerializedValueType(value, '{{rootName}}.{{struct['name']}}');
-    let result: {{struct['name']}} = value['value'] as {{struct['name']}};
-    return result;
-  }
-}
-{% endfor %}
-export interface IHandler {
-{% for struct in structs%}{% if struct['__meta__'].handleInTypescript %}  Handle{{struct['name']}}(value:  {{struct['name']}}): boolean;
-{% endif %}{% endfor %}};
-
-/** Service function for StoneDispatchToHandler */
-export function StoneDispatchJsonToHandler(
-  jsonValue: any, handler: IHandler): boolean
-{
-  StoneCheckSerializedValueTypeGeneric(jsonValue);
-  let type: string = jsonValue["type"];
-  if (type == "")
-  {
-    // this should never ever happen
-    throw new Error("Caught empty type while dispatching");
-  }
-{% for struct in structs%}{% if struct['__meta__'].handleInTypescript %}  else if (type == "{{rootName}}.{{struct['name']}}")
-  {
-    let value = jsonValue["value"] as {{struct['name']}};
-    return handler.Handle{{struct['name']}}(value);
-  }
-{% endif %}{% endfor %}  else
-  {
-    return false;
-  }
-}
-
-/** Takes a serialized type and passes this to the handler */
-export function StoneDispatchToHandler(
-  strValue: string, handler: IHandler): boolean
-{
-  // console.//log("+------------------------------------------------+");
-  // console.//log("|            StoneDispatchToHandler              |");
-  // console.//log("+------------------------------------------------+");
-  // console.//log("strValue = ");
-  // console.//log(strValue);
-  let jsonValue: any = JSON.parse(strValue)
-  return StoneDispatchJsonToHandler(jsonValue, handler);
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testCppHandler/CMakeLists.txt	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-cmake_minimum_required(VERSION 2.8)
-
-project(testCppHandler)
-
-set(testCppHandler_Codegen_Deps
-  ${CMAKE_CURRENT_LIST_DIR}/../test_data/testTestStoneCodeGen.yaml 
-  ${CMAKE_CURRENT_LIST_DIR}/../template.in.h.j2
-) 
-
-add_custom_command(
-    OUTPUT  ${CMAKE_CURRENT_BINARY_DIR}/VsolMessages_generated.hpp
-    COMMAND python ${CMAKE_CURRENT_LIST_DIR}/../stonegentool.py -o ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_LIST_DIR}/../test_data/testTestStoneCodeGen.yaml
-    DEPENDS ${testCppHandler_Codegen_Deps}
-)
-
-include(${CMAKE_BINARY_DIR}/conanbuildinfo_multi.cmake)
-conan_basic_setup()
-
-add_executable(testCppHandler main.cpp ${CMAKE_CURRENT_BINARY_DIR}/VsolMessages_generated.hpp ${testCppHandler_Codegen_Deps})
-
-target_include_directories(testCppHandler PUBLIC ${CMAKE_BINARY_DIR})
-
-conan_target_link_libraries(testCppHandler)
-
-set_property(TARGET testCppHandler PROPERTY CXX_STANDARD 17)
-
-install(TARGETS testCppHandler DESTINATION bin)
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testCppHandler/README.md	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-Requirements
-==============
-- Install Python 3.x (tested with 3.7)
-- Install conan with `pip install conan` (tested with 1.12.2)
-- Install CMake (tested with 3.12)
-- Under Windows: Visual Studio 2017
-- Under *nix*: Ninja
-
-How to build under *nix*
-===============================
-- Navigate to `testCppHandler` folder
-- `conan install . -g cmake`
-- `mkdir build`
-- `cd build`
-- `cmake -G "Ninja" ..`
-- `cmake --build . --config Debug` or - `cmake --build . --config Release`
-
-How to build under Windows with Visual Studio
-==============================================
-- Navigate to repo root
-- `mkdir build`
-- `cd build`
-- `conan install .. -g cmake_multi -s build_type=Release`
-- `conan install .. -g cmake_multi -s build_type=Debug`
-- `cmake -G "Visual Studio 15 2017 Win64" ..`  (modify for your current Visual Studio version)
-- `cmake --build . --config Debug` or - `cmake --build . --config Release`
-
-How to execute the test
-=======================
-- `cd test_data && testCppHandler --pattern=*.json`
-
-
-
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testCppHandler/conanfile.txt	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-[requires]
-jsoncpp/1.8.4@theirix/stable
-gtest/1.8.1@bincrafters/stable
-boost/1.69.0@conan/stable
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testCppHandler/main.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,160 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include <string>
-#include <fstream>
-#include <filesystem>
-#include <regex>
-using namespace std;
-namespace fs = std::filesystem;
-
-#include <boost/program_options.hpp>
-using namespace boost::program_options;
-
-#include "TestStoneCodeGen_generated.hpp"
-
-/**
-Transforms `str` by replacing occurrences of `oldStr` with `newStr`, using 
-plain text (*not* regular expressions.)
-*/
-static inline void ReplaceInString(
-  string& str,
-  const std::string& oldStr,
-  const std::string& newStr)
-{
-  std::string::size_type pos = 0u;
-  while ((pos = str.find(oldStr, pos)) != std::string::npos) {
-    str.replace(pos, oldStr.length(), newStr);
-    pos += newStr.length();
-  }
-}
-
-string SlurpFile(const string& fileName)
-{
-  ifstream ifs(fileName.c_str(), ios::in | ios::binary | ios::ate);
-
-  ifstream::pos_type fileSize = ifs.tellg();
-  ifs.seekg(0, ios::beg);
-
-  vector<char> bytes(fileSize);
-  ifs.read(bytes.data(), fileSize);
-
-  return string(bytes.data(), fileSize);
-}
-
-class MyHandler : public TestStoneCodeGen::IHandler
-{
-public:
-  virtual bool Handle(const TestStoneCodeGen::A& value) override
-  {
-    TestStoneCodeGen::StoneDumpValue(cout, value);
-    return true;
-  }
-  virtual bool Handle(const TestStoneCodeGen::B& value) override
-  {
-    TestStoneCodeGen::StoneDumpValue(cout, value);
-    return true;
-  }
-  virtual bool Handle(const TestStoneCodeGen::C& value) override
-  {
-    TestStoneCodeGen::StoneDumpValue(cout, value);
-    return true;
-  }
-  virtual bool Handle(const TestStoneCodeGen::Message1& value) override
-  {
-    TestStoneCodeGen::StoneDumpValue(cout, value);
-    return true;
-  }
-  virtual bool Handle(const TestStoneCodeGen::Message2& value) override
-  {
-    TestStoneCodeGen::StoneDumpValue(cout, value);
-    return true;
-  }
-};
-
-template<typename T>
-void ProcessPath(T filePath)
-{
-  cout << "+--------------------------------------------+\n";
-  cout << "| Processing: " << filePath.path().string() << "\n";
-  cout << "+--------------------------------------------+\n";
-  MyHandler handler;
-  auto contents = SlurpFile(filePath.path().string());
-  TestStoneCodeGen::StoneDispatchToHandler(contents, &handler);
-}
-
-int main(int argc, char** argv)
-{
-  try
-  {
-
-    options_description desc("Allowed options");
-    desc.add_options()
-      // First parameter describes option name/short name
-      // The second is parameter to option
-      // The third is description
-      ("help,h", "print usage message")
-      ("pattern,p", value<string>(), "pattern for input")
-      ;
-
-    variables_map vm;
-    store(parse_command_line(argc, argv, desc), vm);
-
-    if (vm.count("help"))
-    {
-      cout << desc << "\n";
-      return 0;
-    }
-
-    notify(vm);
-
-    string pattern = vm["pattern"].as<string>();
-
-    // tranform globbing pattern into regex
-    // we should deal with -, ., *...
-    string regexPatternStr = pattern;
-    cout << "Pattern is: " << regexPatternStr << endl;
-    ReplaceInString(regexPatternStr, "\\", "\\\\");
-    ReplaceInString(regexPatternStr, "-", "\\-");
-    ReplaceInString(regexPatternStr, ".", "\\.");
-    ReplaceInString(regexPatternStr, "*", ".*");
-    ReplaceInString(regexPatternStr, "?", ".");
-    cout << "Corresponding regex is: " << regexPatternStr << endl;
-
-    regex regexPattern(regexPatternStr);
-
-    for (auto& p : fs::directory_iterator("."))
-    {
-      auto fileName = p.path().filename().string();
-      if (regex_match(fileName, regexPattern))
-      {
-        ProcessPath(p);
-      }
-    }
-    return 0;
-
-
-  }
-  catch (exception& e)
-  {
-    cerr << e.what() << "\n";
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testCppHandler/test_data/test_Message2.json	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-{
-  "type": "TestStoneCodeGen.Message2",
-  "value": {
-    "memberVectorOfMessage1": [
-      {
-        "memberInt32": 42,
-        "memberString": "Benjamin",
-        "memberEnumMonth": "January",
-        "memberBool": false,
-        "memberFloat32": 0.1,
-        "memberFloat64": -0.2
-      },
-      {
-        "memberInt32": 43,
-        "memberString": "Sandrine",
-        "memberEnumMonth": "March"
-      }
-    ],
-    "memberVectorOfString": [
-      "Mercadet",
-      "Poisson"
-    ],
-    "memberMapStringString": {
-      "44": "key 44",
-      "45": "key 45"
-    },
-    "memberMapStringStruct": {
-      "54": {
-        "memberInt32": 43,
-        "memberString": "Sandrine",
-        "memberEnumMonth": "March"
-      },
-      "55": {
-        "memberInt32": 42,
-        "memberString": "Benjamin",
-        "memberEnumMonth": "January",
-        "memberBool": false
-      }
-    },
-    "memberString": "Prout zizi",
-    "memberMapEnumFloat" : {
-      "SaltAndPepper" : 0.1,
-      "CreamAndChives" : -0.2
-    },
-    "memberJson" : {"custom-key": "custom-value"}
-  }
-}
\ No newline at end of file
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/CMakeLists.txt	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-cmake_minimum_required(VERSION 2.8)
-
-project(testWasmIntegratedCpp)
-
-set(WASM_FLAGS "-s WASM=1 -O0 -g0")
-set(WASM_MODULE_NAME "TestWasmIntegratedModule" CACHE STRING "Name of the WebAssembly module")
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WASM_FLAGS}")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WASM_FLAGS}")
-#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --js-library ${STONE_SOURCES_DIR}/Platforms/Wasm/WasmWebService.js --js-library ${STONE_SOURCES_DIR}/Platforms/Wasm/WasmDelayedCallExecutor.js --js-library ${STONE_SOURCES_DIR}/Platforms/Wasm/default-library.js  -s EXTRA_EXPORTED_RUNTIME_METHODS='[\"ccall\", \"cwrap\"]'")
-set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --js-library ${CMAKE_CURRENT_LIST_DIR}/DefaultLibrary.js -s EXTRA_EXPORTED_RUNTIME_METHODS='[\"ccall\", \"cwrap\"]'")
-set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s DISABLE_EXCEPTION_CATCHING=0 -s EXPORT_NAME='\"${WASM_MODULE_NAME}\"' -s ALLOW_MEMORY_GROWTH=1 -s TOTAL_MEMORY=536870912 -s TOTAL_STACK=128000000")  # 512MB + resize
-
-add_definitions(-DORTHANC_ENABLE_WASM=1)
-
-set(testWasmIntegratedCpp_Codegen_Deps
-  ${CMAKE_CURRENT_LIST_DIR}/testWasmIntegratedCpp_api.yaml 
-  ${CMAKE_CURRENT_LIST_DIR}/../template.in.h.j2
-  ${CMAKE_CURRENT_LIST_DIR}/../template.in.ts.j2
-) 
-
-set(jsoncppRootDir ${CMAKE_CURRENT_LIST_DIR}/jsoncpp-1.8.4)
-
-add_custom_command(
-    OUTPUT  ${CMAKE_CURRENT_BINARY_DIR}/TestStoneCodeGen_generated.hpp ${CMAKE_CURRENT_BINARY_DIR}/TestStoneCodeGen_generated.ts
-    COMMAND python3 ${CMAKE_CURRENT_LIST_DIR}/../stonegentool.py -o ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_LIST_DIR}/../test_data/testTestStoneCodeGen.yaml
-    DEPENDS ${testCppHandler_Codegen_Deps} ${CMAKE_CURRENT_LIST_DIR}/../test_data/testTestStoneCodeGen.yaml 
-)
-
-add_executable(testWasmIntegratedCpp
-  main.cpp
-  ${CMAKE_CURRENT_BINARY_DIR}/TestStoneCodeGen_generated.hpp
-  ${jsoncppRootDir}/jsoncpp.cpp
-  ${testCppHandler_Codegen_Deps})
-
-target_include_directories(testWasmIntegratedCpp  PUBLIC ${CMAKE_BINARY_DIR})
-target_include_directories(testWasmIntegratedCpp  PUBLIC ${jsoncppRootDir})
-
-set_property(TARGET testWasmIntegratedCpp PROPERTY CXX_STANDARD 11)
-
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/DefaultLibrary.js	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-// this file contains the JS method you want to expose to C++ code
-
-mergeInto(LibraryManager.library, {
-  // each time the Application updates its status, it may signal it through this method. i.e, to change the status of a button in the web interface
-  // It needs to be put in this file so that the emscripten SDK linker knows where to find it.
-  SendFreeTextFromCppJS: function(statusUpdateMessage) {
-    var statusUpdateMessage_ = UTF8ToString(statusUpdateMessage);
-    window.SendFreeTextFromCpp(statusUpdateMessage_);
-  },
-  SendMessageFromCppJS: function(statusUpdateMessage) {
-    var statusUpdateMessage_ = UTF8ToString(statusUpdateMessage);
-    window.SendMessageFromCpp(statusUpdateMessage_);
-  }
-});
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/build-web.sh	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-#!/bin/bash
-set -e
-
-mkdir -p build-final
-
-# compile TS to JS
-tsc --module commonjs --sourceMap -t ES2015 --outDir "build-tsc/" build-wasm/TestStoneCodeGen_generated.ts testWasmIntegrated.ts 
-
-# bundle JS files to final build dir 
-browserify "build-tsc/build-wasm/testWasmIntegratedCpp_generated.js" "build-tsc/testWasmIntegrated.js" -o "build-final/testWasmIntegratedApp.js"
-
-# copy WASM loader JS file to final build dir 
-cp build-wasm/testWasmIntegratedCpp.js build-final/
-
-# copy HTML start page to output dir
-cp testWasmIntegrated.html build-final/
-
-
-# copy styles to output dir
-cp styles.css build-final/
-
-# copy WASM binary to output dir
-cp build-wasm/testWasmIntegratedCpp.wasm  build-final/
-
-cp ../test_data/testTestStoneCodeGen.yaml build-final/
-cp ../testCppHandler/test_data/test_Message2.json build-final/cppHandler_test_Message2.json
-
-echo "...Serving files at http://127.0.0.1:8080/build-final/testWasmIntegrated.html"
-
-sudo python3 serve.py
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/build.sh	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-#!/bin/bash
-
-set -e
-
-mkdir -p build-wasm
-cd build-wasm
-
-# shellcheck source="$HOME/apps/emsdk/emsdk_env.sh"
-source "$HOME/apps/emsdk/emsdk_env.sh"
-cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN}/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_BUILD_TYPE=Debug -DENABLE_WASM=ON ..
-
-ninja
-
-cd ..
-
-./build-web.sh
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/jsoncpp-1.8.4/json/json-forwards.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,344 +0,0 @@
-/// Json-cpp amalgamated forward header (http://jsoncpp.sourceforge.net/).
-/// It is intended to be used with #include "json/json-forwards.h"
-/// This header provides forward declaration for all JsonCpp types.
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: LICENSE
-// //////////////////////////////////////////////////////////////////////
-
-/*
-The JsonCpp library's source code, including accompanying documentation, 
-tests and demonstration applications, are licensed under the following
-conditions...
-
-Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all 
-jurisdictions which recognize such a disclaimer. In such jurisdictions, 
-this software is released into the Public Domain.
-
-In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
-2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and
-The JsonCpp Authors, and is released under the terms of the MIT License (see below).
-
-In jurisdictions which recognize Public Domain property, the user of this 
-software may choose to accept it either as 1) Public Domain, 2) under the 
-conditions of the MIT License (see below), or 3) under the terms of dual 
-Public Domain/MIT License conditions described here, as they choose.
-
-The MIT License is about as close to Public Domain as a license can get, and is
-described in clear, concise terms at:
-
-   http://en.wikipedia.org/wiki/MIT_License
-   
-The full text of the MIT License follows:
-
-========================================================================
-Copyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use, copy,
-modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-========================================================================
-(END LICENSE TEXT)
-
-The MIT license is compatible with both the GPL and commercial
-software, affording one all of the rights of Public Domain with the
-minor nuisance of being required to keep the above copyright notice
-and license text in the source code. Note also that by accepting the
-Public Domain "license" you can re-license your copy using whatever
-license you like.
-
-*/
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: LICENSE
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-#ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED
-# define JSON_FORWARD_AMALGAMATED_H_INCLUDED
-/// If defined, indicates that the source file is amalgamated
-/// to prevent private header inclusion.
-#define JSON_IS_AMALGAMATION
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/config.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef JSON_CONFIG_H_INCLUDED
-#define JSON_CONFIG_H_INCLUDED
-#include <cstddef>
-#include <cstdint>
-#include <istream>
-#include <memory>
-#include <ostream>
-#include <sstream>
-#include <string>
-#include <type_traits>
-
-/// If defined, indicates that json library is embedded in CppTL library.
-//# define JSON_IN_CPPTL 1
-
-/// If defined, indicates that json may leverage CppTL library
-//#  define JSON_USE_CPPTL 1
-/// If defined, indicates that cpptl vector based map should be used instead of
-/// std::map
-/// as Value container.
-//#  define JSON_USE_CPPTL_SMALLMAP 1
-
-// If non-zero, the library uses exceptions to report bad input instead of C
-// assertion macros. The default is to use exceptions.
-#ifndef JSON_USE_EXCEPTION
-#define JSON_USE_EXCEPTION 1
-#endif
-
-/// If defined, indicates that the source file is amalgamated
-/// to prevent private header inclusion.
-/// Remarks: it is automatically defined in the generated amalgamated header.
-// #define JSON_IS_AMALGAMATION
-
-#ifdef JSON_IN_CPPTL
-#include <cpptl/config.h>
-#ifndef JSON_USE_CPPTL
-#define JSON_USE_CPPTL 1
-#endif
-#endif
-
-#ifdef JSON_IN_CPPTL
-#define JSON_API CPPTL_API
-#elif defined(JSON_DLL_BUILD)
-#if defined(_MSC_VER) || defined(__MINGW32__)
-#define JSON_API __declspec(dllexport)
-#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
-#endif // if defined(_MSC_VER)
-#elif defined(JSON_DLL)
-#if defined(_MSC_VER) || defined(__MINGW32__)
-#define JSON_API __declspec(dllimport)
-#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
-#endif // if defined(_MSC_VER)
-#endif // ifdef JSON_IN_CPPTL
-#if !defined(JSON_API)
-#define JSON_API
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER < 1800
-#error                                                                         \
-    "ERROR:  Visual Studio 12 (2013) with _MSC_VER=1800 is the oldest supported compiler with sufficient C++11 capabilities"
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER < 1900
-// As recommended at
-// https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010
-extern JSON_API int
-msvc_pre1900_c99_snprintf(char* outBuf, size_t size, const char* format, ...);
-#define jsoncpp_snprintf msvc_pre1900_c99_snprintf
-#else
-#define jsoncpp_snprintf std::snprintf
-#endif
-
-// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for
-// integer
-// Storages, and 64 bits integer support is disabled.
-// #define JSON_NO_INT64 1
-
-#if defined(_MSC_VER) // MSVC
-#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
-#endif // defined(_MSC_VER)
-
-// JSONCPP_OVERRIDE is maintained for backwards compatibility of external tools.
-// C++11 should be used directly in JSONCPP.
-#define JSONCPP_OVERRIDE override
-
-#if __cplusplus >= 201103L
-#define JSONCPP_NOEXCEPT noexcept
-#define JSONCPP_OP_EXPLICIT explicit
-#elif defined(_MSC_VER) && _MSC_VER < 1900
-#define JSONCPP_NOEXCEPT throw()
-#define JSONCPP_OP_EXPLICIT explicit
-#elif defined(_MSC_VER) && _MSC_VER >= 1900
-#define JSONCPP_NOEXCEPT noexcept
-#define JSONCPP_OP_EXPLICIT explicit
-#else
-#define JSONCPP_NOEXCEPT throw()
-#define JSONCPP_OP_EXPLICIT
-#endif
-
-#ifndef JSON_HAS_RVALUE_REFERENCES
-
-#if defined(_MSC_VER)
-#define JSON_HAS_RVALUE_REFERENCES 1
-#endif // MSVC >= 2013
-
-#ifdef __clang__
-#if __has_feature(cxx_rvalue_references)
-#define JSON_HAS_RVALUE_REFERENCES 1
-#endif // has_feature
-
-#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
-#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
-#define JSON_HAS_RVALUE_REFERENCES 1
-#endif // GXX_EXPERIMENTAL
-
-#endif // __clang__ || __GNUC__
-
-#endif // not defined JSON_HAS_RVALUE_REFERENCES
-
-#ifndef JSON_HAS_RVALUE_REFERENCES
-#define JSON_HAS_RVALUE_REFERENCES 0
-#endif
-
-#ifdef __clang__
-#if __has_extension(attribute_deprecated_with_message)
-#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
-#endif
-#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
-#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
-#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
-#elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
-#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
-#endif // GNUC version
-#endif // __clang__ || __GNUC__
-
-#if !defined(JSONCPP_DEPRECATED)
-#define JSONCPP_DEPRECATED(message)
-#endif // if !defined(JSONCPP_DEPRECATED)
-
-#if __GNUC__ >= 6
-#define JSON_USE_INT64_DOUBLE_CONVERSION 1
-#endif
-
-#if !defined(JSON_IS_AMALGAMATION)
-
-#include "allocator.h"
-#include "version.h"
-
-#endif // if !defined(JSON_IS_AMALGAMATION)
-
-namespace Json {
-typedef int Int;
-typedef unsigned int UInt;
-#if defined(JSON_NO_INT64)
-typedef int LargestInt;
-typedef unsigned int LargestUInt;
-#undef JSON_HAS_INT64
-#else                 // if defined(JSON_NO_INT64)
-// For Microsoft Visual use specific types as long long is not supported
-#if defined(_MSC_VER) // Microsoft Visual Studio
-typedef __int64 Int64;
-typedef unsigned __int64 UInt64;
-#else                 // if defined(_MSC_VER) // Other platforms, use long long
-typedef int64_t Int64;
-typedef uint64_t UInt64;
-#endif                // if defined(_MSC_VER)
-typedef Int64 LargestInt;
-typedef UInt64 LargestUInt;
-#define JSON_HAS_INT64
-#endif // if defined(JSON_NO_INT64)
-
-template <typename T>
-using Allocator = typename std::conditional<JSONCPP_USING_SECURE_MEMORY,
-                                            SecureAllocator<T>,
-                                            std::allocator<T>>::type;
-using String = std::basic_string<char, std::char_traits<char>, Allocator<char>>;
-using IStringStream = std::basic_istringstream<String::value_type,
-                                               String::traits_type,
-                                               String::allocator_type>;
-using OStringStream = std::basic_ostringstream<String::value_type,
-                                               String::traits_type,
-                                               String::allocator_type>;
-using IStream = std::istream;
-using OStream = std::ostream;
-} // namespace Json
-
-// Legacy names (formerly macros).
-using JSONCPP_STRING = Json::String;
-using JSONCPP_ISTRINGSTREAM = Json::IStringStream;
-using JSONCPP_OSTRINGSTREAM = Json::OStringStream;
-using JSONCPP_ISTREAM = Json::IStream;
-using JSONCPP_OSTREAM = Json::OStream;
-
-#endif // JSON_CONFIG_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/config.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/forwards.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef JSON_FORWARDS_H_INCLUDED
-#define JSON_FORWARDS_H_INCLUDED
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include "config.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-
-namespace Json {
-
-// writer.h
-class FastWriter;
-class StyledWriter;
-
-// reader.h
-class Reader;
-
-// features.h
-class Features;
-
-// value.h
-typedef unsigned int ArrayIndex;
-class StaticString;
-class Path;
-class PathArgument;
-class Value;
-class ValueIteratorBase;
-class ValueIterator;
-class ValueConstIterator;
-
-} // namespace Json
-
-#endif // JSON_FORWARDS_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/forwards.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-#endif //ifndef JSON_FORWARD_AMALGAMATED_H_INCLUDED
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/jsoncpp-1.8.4/json/json.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2366 +0,0 @@
-/// Json-cpp amalgamated header (http://jsoncpp.sourceforge.net/).
-/// It is intended to be used with #include "json/json.h"
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: LICENSE
-// //////////////////////////////////////////////////////////////////////
-
-/*
-The JsonCpp library's source code, including accompanying documentation, 
-tests and demonstration applications, are licensed under the following
-conditions...
-
-Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all 
-jurisdictions which recognize such a disclaimer. In such jurisdictions, 
-this software is released into the Public Domain.
-
-In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
-2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and
-The JsonCpp Authors, and is released under the terms of the MIT License (see below).
-
-In jurisdictions which recognize Public Domain property, the user of this 
-software may choose to accept it either as 1) Public Domain, 2) under the 
-conditions of the MIT License (see below), or 3) under the terms of dual 
-Public Domain/MIT License conditions described here, as they choose.
-
-The MIT License is about as close to Public Domain as a license can get, and is
-described in clear, concise terms at:
-
-   http://en.wikipedia.org/wiki/MIT_License
-   
-The full text of the MIT License follows:
-
-========================================================================
-Copyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use, copy,
-modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-========================================================================
-(END LICENSE TEXT)
-
-The MIT license is compatible with both the GPL and commercial
-software, affording one all of the rights of Public Domain with the
-minor nuisance of being required to keep the above copyright notice
-and license text in the source code. Note also that by accepting the
-Public Domain "license" you can re-license your copy using whatever
-license you like.
-
-*/
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: LICENSE
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-#ifndef JSON_AMALGAMATED_H_INCLUDED
-# define JSON_AMALGAMATED_H_INCLUDED
-/// If defined, indicates that the source file is amalgamated
-/// to prevent private header inclusion.
-#define JSON_IS_AMALGAMATION
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/version.h
-// //////////////////////////////////////////////////////////////////////
-
-// DO NOT EDIT. This file (and "version") is generated by CMake.
-// Run CMake configure step to update it.
-#ifndef JSON_VERSION_H_INCLUDED
-#define JSON_VERSION_H_INCLUDED
-
-#define JSONCPP_VERSION_STRING "1.8.4"
-#define JSONCPP_VERSION_MAJOR 1
-#define JSONCPP_VERSION_MINOR 8
-#define JSONCPP_VERSION_PATCH 4
-#define JSONCPP_VERSION_QUALIFIER
-#define JSONCPP_VERSION_HEXA                                                   \
-  ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) |             \
-   (JSONCPP_VERSION_PATCH << 8))
-
-#ifdef JSONCPP_USING_SECURE_MEMORY
-#undef JSONCPP_USING_SECURE_MEMORY
-#endif
-#define JSONCPP_USING_SECURE_MEMORY 0
-// If non-zero, the library zeroes any memory that it has allocated before
-// it frees its memory.
-
-#endif // JSON_VERSION_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/version.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/allocator.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef CPPTL_JSON_ALLOCATOR_H_INCLUDED
-#define CPPTL_JSON_ALLOCATOR_H_INCLUDED
-
-#include <cstring>
-#include <memory>
-
-#pragma pack(push, 8)
-
-namespace Json {
-template <typename T> class SecureAllocator {
-public:
-  // Type definitions
-  using value_type = T;
-  using pointer = T*;
-  using const_pointer = const T*;
-  using reference = T&;
-  using const_reference = const T&;
-  using size_type = std::size_t;
-  using difference_type = std::ptrdiff_t;
-
-  /**
-   * Allocate memory for N items using the standard allocator.
-   */
-  pointer allocate(size_type n) {
-    // allocate using "global operator new"
-    return static_cast<pointer>(::operator new(n * sizeof(T)));
-  }
-
-  /**
-   * Release memory which was allocated for N items at pointer P.
-   *
-   * The memory block is filled with zeroes before being released.
-   * The pointer argument is tagged as "volatile" to prevent the
-   * compiler optimizing out this critical step.
-   */
-  void deallocate(volatile pointer p, size_type n) {
-    std::memset(p, 0, n * sizeof(T));
-    // free using "global operator delete"
-    ::operator delete(p);
-  }
-
-  /**
-   * Construct an item in-place at pointer P.
-   */
-  template <typename... Args> void construct(pointer p, Args&&... args) {
-    // construct using "placement new" and "perfect forwarding"
-    ::new (static_cast<void*>(p)) T(std::forward<Args>(args)...);
-  }
-
-  size_type max_size() const { return size_t(-1) / sizeof(T); }
-
-  pointer address(reference x) const { return std::addressof(x); }
-
-  const_pointer address(const_reference x) const { return std::addressof(x); }
-
-  /**
-   * Destroy an item in-place at pointer P.
-   */
-  void destroy(pointer p) {
-    // destroy using "explicit destructor"
-    p->~T();
-  }
-
-  // Boilerplate
-  SecureAllocator() {}
-  template <typename U> SecureAllocator(const SecureAllocator<U>&) {}
-  template <typename U> struct rebind { using other = SecureAllocator<U>; };
-};
-
-template <typename T, typename U>
-bool operator==(const SecureAllocator<T>&, const SecureAllocator<U>&) {
-  return true;
-}
-
-template <typename T, typename U>
-bool operator!=(const SecureAllocator<T>&, const SecureAllocator<U>&) {
-  return false;
-}
-
-} // namespace Json
-
-#pragma pack(pop)
-
-#endif // CPPTL_JSON_ALLOCATOR_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/allocator.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/config.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef JSON_CONFIG_H_INCLUDED
-#define JSON_CONFIG_H_INCLUDED
-#include <cstddef>
-#include <cstdint>
-#include <istream>
-#include <memory>
-#include <ostream>
-#include <sstream>
-#include <string>
-#include <type_traits>
-
-/// If defined, indicates that json library is embedded in CppTL library.
-//# define JSON_IN_CPPTL 1
-
-/// If defined, indicates that json may leverage CppTL library
-//#  define JSON_USE_CPPTL 1
-/// If defined, indicates that cpptl vector based map should be used instead of
-/// std::map
-/// as Value container.
-//#  define JSON_USE_CPPTL_SMALLMAP 1
-
-// If non-zero, the library uses exceptions to report bad input instead of C
-// assertion macros. The default is to use exceptions.
-#ifndef JSON_USE_EXCEPTION
-#define JSON_USE_EXCEPTION 1
-#endif
-
-/// If defined, indicates that the source file is amalgamated
-/// to prevent private header inclusion.
-/// Remarks: it is automatically defined in the generated amalgamated header.
-// #define JSON_IS_AMALGAMATION
-
-#ifdef JSON_IN_CPPTL
-#include <cpptl/config.h>
-#ifndef JSON_USE_CPPTL
-#define JSON_USE_CPPTL 1
-#endif
-#endif
-
-#ifdef JSON_IN_CPPTL
-#define JSON_API CPPTL_API
-#elif defined(JSON_DLL_BUILD)
-#if defined(_MSC_VER) || defined(__MINGW32__)
-#define JSON_API __declspec(dllexport)
-#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
-#endif // if defined(_MSC_VER)
-#elif defined(JSON_DLL)
-#if defined(_MSC_VER) || defined(__MINGW32__)
-#define JSON_API __declspec(dllimport)
-#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
-#endif // if defined(_MSC_VER)
-#endif // ifdef JSON_IN_CPPTL
-#if !defined(JSON_API)
-#define JSON_API
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER < 1800
-#error                                                                         \
-    "ERROR:  Visual Studio 12 (2013) with _MSC_VER=1800 is the oldest supported compiler with sufficient C++11 capabilities"
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER < 1900
-// As recommended at
-// https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010
-extern JSON_API int
-msvc_pre1900_c99_snprintf(char* outBuf, size_t size, const char* format, ...);
-#define jsoncpp_snprintf msvc_pre1900_c99_snprintf
-#else
-#define jsoncpp_snprintf std::snprintf
-#endif
-
-// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for
-// integer
-// Storages, and 64 bits integer support is disabled.
-// #define JSON_NO_INT64 1
-
-#if defined(_MSC_VER) // MSVC
-#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
-#endif // defined(_MSC_VER)
-
-// JSONCPP_OVERRIDE is maintained for backwards compatibility of external tools.
-// C++11 should be used directly in JSONCPP.
-#define JSONCPP_OVERRIDE override
-
-#if __cplusplus >= 201103L
-#define JSONCPP_NOEXCEPT noexcept
-#define JSONCPP_OP_EXPLICIT explicit
-#elif defined(_MSC_VER) && _MSC_VER < 1900
-#define JSONCPP_NOEXCEPT throw()
-#define JSONCPP_OP_EXPLICIT explicit
-#elif defined(_MSC_VER) && _MSC_VER >= 1900
-#define JSONCPP_NOEXCEPT noexcept
-#define JSONCPP_OP_EXPLICIT explicit
-#else
-#define JSONCPP_NOEXCEPT throw()
-#define JSONCPP_OP_EXPLICIT
-#endif
-
-#ifndef JSON_HAS_RVALUE_REFERENCES
-
-#if defined(_MSC_VER)
-#define JSON_HAS_RVALUE_REFERENCES 1
-#endif // MSVC >= 2013
-
-#ifdef __clang__
-#if __has_feature(cxx_rvalue_references)
-#define JSON_HAS_RVALUE_REFERENCES 1
-#endif // has_feature
-
-#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
-#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
-#define JSON_HAS_RVALUE_REFERENCES 1
-#endif // GXX_EXPERIMENTAL
-
-#endif // __clang__ || __GNUC__
-
-#endif // not defined JSON_HAS_RVALUE_REFERENCES
-
-#ifndef JSON_HAS_RVALUE_REFERENCES
-#define JSON_HAS_RVALUE_REFERENCES 0
-#endif
-
-#ifdef __clang__
-#if __has_extension(attribute_deprecated_with_message)
-#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
-#endif
-#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
-#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
-#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
-#elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
-#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
-#endif // GNUC version
-#endif // __clang__ || __GNUC__
-
-#if !defined(JSONCPP_DEPRECATED)
-#define JSONCPP_DEPRECATED(message)
-#endif // if !defined(JSONCPP_DEPRECATED)
-
-#if __GNUC__ >= 6
-#define JSON_USE_INT64_DOUBLE_CONVERSION 1
-#endif
-
-#if !defined(JSON_IS_AMALGAMATION)
-
-#include "allocator.h"
-#include "version.h"
-
-#endif // if !defined(JSON_IS_AMALGAMATION)
-
-namespace Json {
-typedef int Int;
-typedef unsigned int UInt;
-#if defined(JSON_NO_INT64)
-typedef int LargestInt;
-typedef unsigned int LargestUInt;
-#undef JSON_HAS_INT64
-#else                 // if defined(JSON_NO_INT64)
-// For Microsoft Visual use specific types as long long is not supported
-#if defined(_MSC_VER) // Microsoft Visual Studio
-typedef __int64 Int64;
-typedef unsigned __int64 UInt64;
-#else                 // if defined(_MSC_VER) // Other platforms, use long long
-typedef int64_t Int64;
-typedef uint64_t UInt64;
-#endif                // if defined(_MSC_VER)
-typedef Int64 LargestInt;
-typedef UInt64 LargestUInt;
-#define JSON_HAS_INT64
-#endif // if defined(JSON_NO_INT64)
-
-template <typename T>
-using Allocator = typename std::conditional<JSONCPP_USING_SECURE_MEMORY,
-                                            SecureAllocator<T>,
-                                            std::allocator<T>>::type;
-using String = std::basic_string<char, std::char_traits<char>, Allocator<char>>;
-using IStringStream = std::basic_istringstream<String::value_type,
-                                               String::traits_type,
-                                               String::allocator_type>;
-using OStringStream = std::basic_ostringstream<String::value_type,
-                                               String::traits_type,
-                                               String::allocator_type>;
-using IStream = std::istream;
-using OStream = std::ostream;
-} // namespace Json
-
-// Legacy names (formerly macros).
-using JSONCPP_STRING = Json::String;
-using JSONCPP_ISTRINGSTREAM = Json::IStringStream;
-using JSONCPP_OSTRINGSTREAM = Json::OStringStream;
-using JSONCPP_ISTREAM = Json::IStream;
-using JSONCPP_OSTREAM = Json::OStream;
-
-#endif // JSON_CONFIG_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/config.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/forwards.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef JSON_FORWARDS_H_INCLUDED
-#define JSON_FORWARDS_H_INCLUDED
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include "config.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-
-namespace Json {
-
-// writer.h
-class FastWriter;
-class StyledWriter;
-
-// reader.h
-class Reader;
-
-// features.h
-class Features;
-
-// value.h
-typedef unsigned int ArrayIndex;
-class StaticString;
-class Path;
-class PathArgument;
-class Value;
-class ValueIteratorBase;
-class ValueIterator;
-class ValueConstIterator;
-
-} // namespace Json
-
-#endif // JSON_FORWARDS_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/forwards.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/features.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef CPPTL_JSON_FEATURES_H_INCLUDED
-#define CPPTL_JSON_FEATURES_H_INCLUDED
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include "forwards.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-
-#pragma pack(push, 8)
-
-namespace Json {
-
-/** \brief Configuration passed to reader and writer.
- * This configuration object can be used to force the Reader or Writer
- * to behave in a standard conforming way.
- */
-class JSON_API Features {
-public:
-  /** \brief A configuration that allows all features and assumes all strings
-   * are UTF-8.
-   * - C & C++ comments are allowed
-   * - Root object can be any JSON value
-   * - Assumes Value strings are encoded in UTF-8
-   */
-  static Features all();
-
-  /** \brief A configuration that is strictly compatible with the JSON
-   * specification.
-   * - Comments are forbidden.
-   * - Root object must be either an array or an object value.
-   * - Assumes Value strings are encoded in UTF-8
-   */
-  static Features strictMode();
-
-  /** \brief Initialize the configuration like JsonConfig::allFeatures;
-   */
-  Features();
-
-  /// \c true if comments are allowed. Default: \c true.
-  bool allowComments_{true};
-
-  /// \c true if root must be either an array or an object value. Default: \c
-  /// false.
-  bool strictRoot_{false};
-
-  /// \c true if dropped null placeholders are allowed. Default: \c false.
-  bool allowDroppedNullPlaceholders_{false};
-
-  /// \c true if numeric object key are allowed. Default: \c false.
-  bool allowNumericKeys_{false};
-};
-
-} // namespace Json
-
-#pragma pack(pop)
-
-#endif // CPPTL_JSON_FEATURES_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/features.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/value.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef CPPTL_JSON_H_INCLUDED
-#define CPPTL_JSON_H_INCLUDED
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include "forwards.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-#include <exception>
-#include <string>
-#include <vector>
-
-#ifndef JSON_USE_CPPTL_SMALLMAP
-#include <map>
-#else
-#include <cpptl/smallmap.h>
-#endif
-#ifdef JSON_USE_CPPTL
-#include <cpptl/forwards.h>
-#endif
-
-// Conditional NORETURN attribute on the throw functions would:
-// a) suppress false positives from static code analysis
-// b) possibly improve optimization opportunities.
-#if !defined(JSONCPP_NORETURN)
-#if defined(_MSC_VER)
-#define JSONCPP_NORETURN __declspec(noreturn)
-#elif defined(__GNUC__)
-#define JSONCPP_NORETURN __attribute__((__noreturn__))
-#else
-#define JSONCPP_NORETURN
-#endif
-#endif
-
-// Disable warning C4251: <data member>: <type> needs to have dll-interface to
-// be used by...
-#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-#pragma warning(push)
-#pragma warning(disable : 4251)
-#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-
-#pragma pack(push, 8)
-
-/** \brief JSON (JavaScript Object Notation).
- */
-namespace Json {
-
-/** Base class for all exceptions we throw.
- *
- * We use nothing but these internally. Of course, STL can throw others.
- */
-class JSON_API Exception : public std::exception {
-public:
-  Exception(String msg);
-  ~Exception() JSONCPP_NOEXCEPT override;
-  char const* what() const JSONCPP_NOEXCEPT override;
-
-protected:
-  String msg_;
-};
-
-/** Exceptions which the user cannot easily avoid.
- *
- * E.g. out-of-memory (when we use malloc), stack-overflow, malicious input
- *
- * \remark derived from Json::Exception
- */
-class JSON_API RuntimeError : public Exception {
-public:
-  RuntimeError(String const& msg);
-};
-
-/** Exceptions thrown by JSON_ASSERT/JSON_FAIL macros.
- *
- * These are precondition-violations (user bugs) and internal errors (our bugs).
- *
- * \remark derived from Json::Exception
- */
-class JSON_API LogicError : public Exception {
-public:
-  LogicError(String const& msg);
-};
-
-/// used internally
-JSONCPP_NORETURN void throwRuntimeError(String const& msg);
-/// used internally
-JSONCPP_NORETURN void throwLogicError(String const& msg);
-
-/** \brief Type of the value held by a Value object.
- */
-enum ValueType {
-  nullValue = 0, ///< 'null' value
-  intValue,      ///< signed integer value
-  uintValue,     ///< unsigned integer value
-  realValue,     ///< double value
-  stringValue,   ///< UTF-8 string value
-  booleanValue,  ///< bool value
-  arrayValue,    ///< array value (ordered list)
-  objectValue    ///< object value (collection of name/value pairs).
-};
-
-enum CommentPlacement {
-  commentBefore = 0,      ///< a comment placed on the line before a value
-  commentAfterOnSameLine, ///< a comment just after a value on the same line
-  commentAfter, ///< a comment on the line after a value (only make sense for
-  /// root value)
-  numberOfCommentPlacement
-};
-
-/** \brief Type of precision for formatting of real values.
- */
-enum PrecisionType {
-  significantDigits = 0, ///< we set max number of significant digits in string
-  decimalPlaces          ///< we set max number of digits after "." in string
-};
-
-//# ifdef JSON_USE_CPPTL
-//   typedef CppTL::AnyEnumerator<const char *> EnumMemberNames;
-//   typedef CppTL::AnyEnumerator<const Value &> EnumValues;
-//# endif
-
-/** \brief Lightweight wrapper to tag static string.
- *
- * Value constructor and objectValue member assignment takes advantage of the
- * StaticString and avoid the cost of string duplication when storing the
- * string or the member name.
- *
- * Example of usage:
- * \code
- * Json::Value aValue( StaticString("some text") );
- * Json::Value object;
- * static const StaticString code("code");
- * object[code] = 1234;
- * \endcode
- */
-class JSON_API StaticString {
-public:
-  explicit StaticString(const char* czstring) : c_str_(czstring) {}
-
-  operator const char*() const { return c_str_; }
-
-  const char* c_str() const { return c_str_; }
-
-private:
-  const char* c_str_;
-};
-
-/** \brief Represents a <a HREF="http://www.json.org">JSON</a> value.
- *
- * This class is a discriminated union wrapper that can represents a:
- * - signed integer [range: Value::minInt - Value::maxInt]
- * - unsigned integer (range: 0 - Value::maxUInt)
- * - double
- * - UTF-8 string
- * - boolean
- * - 'null'
- * - an ordered list of Value
- * - collection of name/value pairs (javascript object)
- *
- * The type of the held value is represented by a #ValueType and
- * can be obtained using type().
- *
- * Values of an #objectValue or #arrayValue can be accessed using operator[]()
- * methods.
- * Non-const methods will automatically create the a #nullValue element
- * if it does not exist.
- * The sequence of an #arrayValue will be automatically resized and initialized
- * with #nullValue. resize() can be used to enlarge or truncate an #arrayValue.
- *
- * The get() methods can be used to obtain default value in the case the
- * required element does not exist.
- *
- * It is possible to iterate over the list of member keys of an object using
- * the getMemberNames() method.
- *
- * \note #Value string-length fit in size_t, but keys must be < 2^30.
- * (The reason is an implementation detail.) A #CharReader will raise an
- * exception if a bound is exceeded to avoid security holes in your app,
- * but the Value API does *not* check bounds. That is the responsibility
- * of the caller.
- */
-class JSON_API Value {
-  friend class ValueIteratorBase;
-
-public:
-  typedef std::vector<String> Members;
-  typedef ValueIterator iterator;
-  typedef ValueConstIterator const_iterator;
-  typedef Json::UInt UInt;
-  typedef Json::Int Int;
-#if defined(JSON_HAS_INT64)
-  typedef Json::UInt64 UInt64;
-  typedef Json::Int64 Int64;
-#endif // defined(JSON_HAS_INT64)
-  typedef Json::LargestInt LargestInt;
-  typedef Json::LargestUInt LargestUInt;
-  typedef Json::ArrayIndex ArrayIndex;
-
-  // Required for boost integration, e. g. BOOST_TEST
-  typedef std::string value_type;
-
-  static const Value& null; ///< We regret this reference to a global instance;
-                            ///< prefer the simpler Value().
-  static const Value& nullRef; ///< just a kludge for binary-compatibility; same
-                               ///< as null
-  static Value const& nullSingleton(); ///< Prefer this to null or nullRef.
-
-  /// Minimum signed integer value that can be stored in a Json::Value.
-  static const LargestInt minLargestInt;
-  /// Maximum signed integer value that can be stored in a Json::Value.
-  static const LargestInt maxLargestInt;
-  /// Maximum unsigned integer value that can be stored in a Json::Value.
-  static const LargestUInt maxLargestUInt;
-
-  /// Minimum signed int value that can be stored in a Json::Value.
-  static const Int minInt;
-  /// Maximum signed int value that can be stored in a Json::Value.
-  static const Int maxInt;
-  /// Maximum unsigned int value that can be stored in a Json::Value.
-  static const UInt maxUInt;
-
-#if defined(JSON_HAS_INT64)
-  /// Minimum signed 64 bits int value that can be stored in a Json::Value.
-  static const Int64 minInt64;
-  /// Maximum signed 64 bits int value that can be stored in a Json::Value.
-  static const Int64 maxInt64;
-  /// Maximum unsigned 64 bits int value that can be stored in a Json::Value.
-  static const UInt64 maxUInt64;
-#endif // defined(JSON_HAS_INT64)
-
-  /// Default precision for real value for string representation.
-  static const UInt defaultRealPrecision;
-
-// Workaround for bug in the NVIDIAs CUDA 9.1 nvcc compiler
-// when using gcc and clang backend compilers.  CZString
-// cannot be defined as private.  See issue #486
-#ifdef __NVCC__
-public:
-#else
-private:
-#endif
-#ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
-  class CZString {
-  public:
-    enum DuplicationPolicy { noDuplication = 0, duplicate, duplicateOnCopy };
-    CZString(ArrayIndex index);
-    CZString(char const* str, unsigned length, DuplicationPolicy allocate);
-    CZString(CZString const& other);
-#if JSON_HAS_RVALUE_REFERENCES
-    CZString(CZString&& other);
-#endif
-    ~CZString();
-    CZString& operator=(const CZString& other);
-
-#if JSON_HAS_RVALUE_REFERENCES
-    CZString& operator=(CZString&& other);
-#endif
-
-    bool operator<(CZString const& other) const;
-    bool operator==(CZString const& other) const;
-    ArrayIndex index() const;
-    // const char* c_str() const; ///< \deprecated
-    char const* data() const;
-    unsigned length() const;
-    bool isStaticString() const;
-
-  private:
-    void swap(CZString& other);
-
-    struct StringStorage {
-      unsigned policy_ : 2;
-      unsigned length_ : 30; // 1GB max
-    };
-
-    char const* cstr_; // actually, a prefixed string, unless policy is noDup
-    union {
-      ArrayIndex index_;
-      StringStorage storage_;
-    };
-  };
-
-public:
-#ifndef JSON_USE_CPPTL_SMALLMAP
-  typedef std::map<CZString, Value> ObjectValues;
-#else
-  typedef CppTL::SmallMap<CZString, Value> ObjectValues;
-#endif // ifndef JSON_USE_CPPTL_SMALLMAP
-#endif // ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
-
-public:
-  /** \brief Create a default Value of the given type.
-
-    This is a very useful constructor.
-    To create an empty array, pass arrayValue.
-    To create an empty object, pass objectValue.
-    Another Value can then be set to this one by assignment.
-This is useful since clear() and resize() will not alter types.
-
-    Examples:
-\code
-Json::Value null_value; // null
-Json::Value arr_value(Json::arrayValue); // []
-Json::Value obj_value(Json::objectValue); // {}
-\endcode
-  */
-  Value(ValueType type = nullValue);
-  Value(Int value);
-  Value(UInt value);
-#if defined(JSON_HAS_INT64)
-  Value(Int64 value);
-  Value(UInt64 value);
-#endif // if defined(JSON_HAS_INT64)
-  Value(double value);
-  Value(const char* value); ///< Copy til first 0. (NULL causes to seg-fault.)
-  Value(const char* begin, const char* end); ///< Copy all, incl zeroes.
-  /** \brief Constructs a value from a static string.
-
-   * Like other value string constructor but do not duplicate the string for
-   * internal storage. The given string must remain alive after the call to this
-   * constructor.
-   * \note This works only for null-terminated strings. (We cannot change the
-   *   size of this class, so we have nowhere to store the length,
-   *   which might be computed later for various operations.)
-   *
-   * Example of usage:
-   * \code
-   * static StaticString foo("some text");
-   * Json::Value aValue(foo);
-   * \endcode
-   */
-  Value(const StaticString& value);
-  Value(const String& value); ///< Copy data() til size(). Embedded
-                              ///< zeroes too.
-#ifdef JSON_USE_CPPTL
-  Value(const CppTL::ConstString& value);
-#endif
-  Value(bool value);
-  Value(const Value& other);
-  Value(Value&& other);
-  ~Value();
-
-  /// \note Overwrite existing comments. To preserve comments, use
-  /// #swapPayload().
-  Value& operator=(const Value& other);
-  Value& operator=(Value&& other);
-
-  /// Swap everything.
-  void swap(Value& other);
-  /// Swap values but leave comments and source offsets in place.
-  void swapPayload(Value& other);
-
-  /// copy everything.
-  void copy(const Value& other);
-  /// copy values but leave comments and source offsets in place.
-  void copyPayload(const Value& other);
-
-  ValueType type() const;
-
-  /// Compare payload only, not comments etc.
-  bool operator<(const Value& other) const;
-  bool operator<=(const Value& other) const;
-  bool operator>=(const Value& other) const;
-  bool operator>(const Value& other) const;
-  bool operator==(const Value& other) const;
-  bool operator!=(const Value& other) const;
-  int compare(const Value& other) const;
-
-  const char* asCString() const; ///< Embedded zeroes could cause you trouble!
-#if JSONCPP_USING_SECURE_MEMORY
-  unsigned getCStringLength() const; // Allows you to understand the length of
-                                     // the CString
-#endif
-  String asString() const; ///< Embedded zeroes are possible.
-  /** Get raw char* of string-value.
-   *  \return false if !string. (Seg-fault if str or end are NULL.)
-   */
-  bool getString(char const** begin, char const** end) const;
-#ifdef JSON_USE_CPPTL
-  CppTL::ConstString asConstString() const;
-#endif
-  Int asInt() const;
-  UInt asUInt() const;
-#if defined(JSON_HAS_INT64)
-  Int64 asInt64() const;
-  UInt64 asUInt64() const;
-#endif // if defined(JSON_HAS_INT64)
-  LargestInt asLargestInt() const;
-  LargestUInt asLargestUInt() const;
-  float asFloat() const;
-  double asDouble() const;
-  bool asBool() const;
-
-  bool isNull() const;
-  bool isBool() const;
-  bool isInt() const;
-  bool isInt64() const;
-  bool isUInt() const;
-  bool isUInt64() const;
-  bool isIntegral() const;
-  bool isDouble() const;
-  bool isNumeric() const;
-  bool isString() const;
-  bool isArray() const;
-  bool isObject() const;
-
-  bool isConvertibleTo(ValueType other) const;
-
-  /// Number of values in array or object
-  ArrayIndex size() const;
-
-  /// \brief Return true if empty array, empty object, or null;
-  /// otherwise, false.
-  bool empty() const;
-
-  /// Return !isNull()
-  JSONCPP_OP_EXPLICIT operator bool() const;
-
-  /// Remove all object members and array elements.
-  /// \pre type() is arrayValue, objectValue, or nullValue
-  /// \post type() is unchanged
-  void clear();
-
-  /// Resize the array to newSize elements.
-  /// New elements are initialized to null.
-  /// May only be called on nullValue or arrayValue.
-  /// \pre type() is arrayValue or nullValue
-  /// \post type() is arrayValue
-  void resize(ArrayIndex newSize);
-
-  /// Access an array element (zero based index ).
-  /// If the array contains less than index element, then null value are
-  /// inserted
-  /// in the array so that its size is index+1.
-  /// (You may need to say 'value[0u]' to get your compiler to distinguish
-  ///  this from the operator[] which takes a string.)
-  Value& operator[](ArrayIndex index);
-
-  /// Access an array element (zero based index ).
-  /// If the array contains less than index element, then null value are
-  /// inserted
-  /// in the array so that its size is index+1.
-  /// (You may need to say 'value[0u]' to get your compiler to distinguish
-  ///  this from the operator[] which takes a string.)
-  Value& operator[](int index);
-
-  /// Access an array element (zero based index )
-  /// (You may need to say 'value[0u]' to get your compiler to distinguish
-  ///  this from the operator[] which takes a string.)
-  const Value& operator[](ArrayIndex index) const;
-
-  /// Access an array element (zero based index )
-  /// (You may need to say 'value[0u]' to get your compiler to distinguish
-  ///  this from the operator[] which takes a string.)
-  const Value& operator[](int index) const;
-
-  /// If the array contains at least index+1 elements, returns the element
-  /// value,
-  /// otherwise returns defaultValue.
-  Value get(ArrayIndex index, const Value& defaultValue) const;
-  /// Return true if index < size().
-  bool isValidIndex(ArrayIndex index) const;
-  /// \brief Append value to array at the end.
-  ///
-  /// Equivalent to jsonvalue[jsonvalue.size()] = value;
-  Value& append(const Value& value);
-
-#if JSON_HAS_RVALUE_REFERENCES
-  Value& append(Value&& value);
-#endif
-
-  /// Access an object value by name, create a null member if it does not exist.
-  /// \note Because of our implementation, keys are limited to 2^30 -1 chars.
-  ///  Exceeding that will cause an exception.
-  Value& operator[](const char* key);
-  /// Access an object value by name, returns null if there is no member with
-  /// that name.
-  const Value& operator[](const char* key) const;
-  /// Access an object value by name, create a null member if it does not exist.
-  /// \param key may contain embedded nulls.
-  Value& operator[](const String& key);
-  /// Access an object value by name, returns null if there is no member with
-  /// that name.
-  /// \param key may contain embedded nulls.
-  const Value& operator[](const String& key) const;
-  /** \brief Access an object value by name, create a null member if it does not
-   exist.
-
-   * If the object has no entry for that name, then the member name used to
-   store
-   * the new entry is not duplicated.
-   * Example of use:
-   * \code
-   * Json::Value object;
-   * static const StaticString code("code");
-   * object[code] = 1234;
-   * \endcode
-   */
-  Value& operator[](const StaticString& key);
-#ifdef JSON_USE_CPPTL
-  /// Access an object value by name, create a null member if it does not exist.
-  Value& operator[](const CppTL::ConstString& key);
-  /// Access an object value by name, returns null if there is no member with
-  /// that name.
-  const Value& operator[](const CppTL::ConstString& key) const;
-#endif
-  /// Return the member named key if it exist, defaultValue otherwise.
-  /// \note deep copy
-  Value get(const char* key, const Value& defaultValue) const;
-  /// Return the member named key if it exist, defaultValue otherwise.
-  /// \note deep copy
-  /// \note key may contain embedded nulls.
-  Value
-  get(const char* begin, const char* end, const Value& defaultValue) const;
-  /// Return the member named key if it exist, defaultValue otherwise.
-  /// \note deep copy
-  /// \param key may contain embedded nulls.
-  Value get(const String& key, const Value& defaultValue) const;
-#ifdef JSON_USE_CPPTL
-  /// Return the member named key if it exist, defaultValue otherwise.
-  /// \note deep copy
-  Value get(const CppTL::ConstString& key, const Value& defaultValue) const;
-#endif
-  /// Most general and efficient version of isMember()const, get()const,
-  /// and operator[]const
-  /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
-  Value const* find(char const* begin, char const* end) const;
-  /// Most general and efficient version of object-mutators.
-  /// \note As stated elsewhere, behavior is undefined if (end-begin) >= 2^30
-  /// \return non-zero, but JSON_ASSERT if this is neither object nor nullValue.
-  Value const* demand(char const* begin, char const* end);
-  /// \brief Remove and return the named member.
-  ///
-  /// Do nothing if it did not exist.
-  /// \pre type() is objectValue or nullValue
-  /// \post type() is unchanged
-  void removeMember(const char* key);
-  /// Same as removeMember(const char*)
-  /// \param key may contain embedded nulls.
-  void removeMember(const String& key);
-  /// Same as removeMember(const char* begin, const char* end, Value* removed),
-  /// but 'key' is null-terminated.
-  bool removeMember(const char* key, Value* removed);
-  /** \brief Remove the named map member.
-
-      Update 'removed' iff removed.
-      \param key may contain embedded nulls.
-      \return true iff removed (no exceptions)
-  */
-  bool removeMember(String const& key, Value* removed);
-  /// Same as removeMember(String const& key, Value* removed)
-  bool removeMember(const char* begin, const char* end, Value* removed);
-  /** \brief Remove the indexed array element.
-
-      O(n) expensive operations.
-      Update 'removed' iff removed.
-      \return true if removed (no exceptions)
-  */
-  bool removeIndex(ArrayIndex index, Value* removed);
-
-  /// Return true if the object has a member named key.
-  /// \note 'key' must be null-terminated.
-  bool isMember(const char* key) const;
-  /// Return true if the object has a member named key.
-  /// \param key may contain embedded nulls.
-  bool isMember(const String& key) const;
-  /// Same as isMember(String const& key)const
-  bool isMember(const char* begin, const char* end) const;
-#ifdef JSON_USE_CPPTL
-  /// Return true if the object has a member named key.
-  bool isMember(const CppTL::ConstString& key) const;
-#endif
-
-  /// \brief Return a list of the member names.
-  ///
-  /// If null, return an empty list.
-  /// \pre type() is objectValue or nullValue
-  /// \post if type() was nullValue, it remains nullValue
-  Members getMemberNames() const;
-
-  //# ifdef JSON_USE_CPPTL
-  //      EnumMemberNames enumMemberNames() const;
-  //      EnumValues enumValues() const;
-  //# endif
-
-  /// \deprecated Always pass len.
-  JSONCPP_DEPRECATED("Use setComment(String const&) instead.")
-  void setComment(const char* comment, CommentPlacement placement);
-  /// Comments must be //... or /* ... */
-  void setComment(const char* comment, size_t len, CommentPlacement placement);
-  /// Comments must be //... or /* ... */
-  void setComment(const String& comment, CommentPlacement placement);
-  bool hasComment(CommentPlacement placement) const;
-  /// Include delimiters and embedded newlines.
-  String getComment(CommentPlacement placement) const;
-
-  String toStyledString() const;
-
-  const_iterator begin() const;
-  const_iterator end() const;
-
-  iterator begin();
-  iterator end();
-
-  // Accessors for the [start, limit) range of bytes within the JSON text from
-  // which this value was parsed, if any.
-  void setOffsetStart(ptrdiff_t start);
-  void setOffsetLimit(ptrdiff_t limit);
-  ptrdiff_t getOffsetStart() const;
-  ptrdiff_t getOffsetLimit() const;
-
-private:
-  void setType(ValueType v) { bits_.value_type_ = v; }
-  bool isAllocated() const { return bits_.allocated_; }
-  void setIsAllocated(bool v) { bits_.allocated_ = v; }
-
-  void initBasic(ValueType type, bool allocated = false);
-  void dupPayload(const Value& other);
-  void releasePayload();
-  void dupMeta(const Value& other);
-
-  Value& resolveReference(const char* key);
-  Value& resolveReference(const char* key, const char* end);
-
-  struct CommentInfo {
-    CommentInfo();
-    ~CommentInfo();
-
-    void setComment(const char* text, size_t len);
-
-    char* comment_{nullptr};
-  };
-
-  // struct MemberNamesTransform
-  //{
-  //   typedef const char *result_type;
-  //   const char *operator()( const CZString &name ) const
-  //   {
-  //      return name.c_str();
-  //   }
-  //};
-
-  union ValueHolder {
-    LargestInt int_;
-    LargestUInt uint_;
-    double real_;
-    bool bool_;
-    char* string_; // if allocated_, ptr to { unsigned, char[] }.
-    ObjectValues* map_;
-  } value_;
-
-  struct {
-    // Really a ValueType, but types should agree for bitfield packing.
-    unsigned int value_type_ : 8;
-    // Unless allocated_, string_ must be null-terminated.
-    unsigned int allocated_ : 1;
-  } bits_;
-
-  CommentInfo* comments_;
-
-  // [start, limit) byte offsets in the source JSON text from which this Value
-  // was extracted.
-  ptrdiff_t start_;
-  ptrdiff_t limit_;
-};
-
-/** \brief Experimental and untested: represents an element of the "path" to
- * access a node.
- */
-class JSON_API PathArgument {
-public:
-  friend class Path;
-
-  PathArgument();
-  PathArgument(ArrayIndex index);
-  PathArgument(const char* key);
-  PathArgument(const String& key);
-
-private:
-  enum Kind { kindNone = 0, kindIndex, kindKey };
-  String key_;
-  ArrayIndex index_{};
-  Kind kind_{kindNone};
-};
-
-/** \brief Experimental and untested: represents a "path" to access a node.
- *
- * Syntax:
- * - "." => root node
- * - ".[n]" => elements at index 'n' of root node (an array value)
- * - ".name" => member named 'name' of root node (an object value)
- * - ".name1.name2.name3"
- * - ".[0][1][2].name1[3]"
- * - ".%" => member name is provided as parameter
- * - ".[%]" => index is provied as parameter
- */
-class JSON_API Path {
-public:
-  Path(const String& path,
-       const PathArgument& a1 = PathArgument(),
-       const PathArgument& a2 = PathArgument(),
-       const PathArgument& a3 = PathArgument(),
-       const PathArgument& a4 = PathArgument(),
-       const PathArgument& a5 = PathArgument());
-
-  const Value& resolve(const Value& root) const;
-  Value resolve(const Value& root, const Value& defaultValue) const;
-  /// Creates the "path" to access the specified node and returns a reference on
-  /// the node.
-  Value& make(Value& root) const;
-
-private:
-  typedef std::vector<const PathArgument*> InArgs;
-  typedef std::vector<PathArgument> Args;
-
-  void makePath(const String& path, const InArgs& in);
-  void addPathInArg(const String& path,
-                    const InArgs& in,
-                    InArgs::const_iterator& itInArg,
-                    PathArgument::Kind kind);
-  static void invalidPath(const String& path, int location);
-
-  Args args_;
-};
-
-/** \brief base class for Value iterators.
- *
- */
-class JSON_API ValueIteratorBase {
-public:
-  typedef std::bidirectional_iterator_tag iterator_category;
-  typedef unsigned int size_t;
-  typedef int difference_type;
-  typedef ValueIteratorBase SelfType;
-
-  bool operator==(const SelfType& other) const { return isEqual(other); }
-
-  bool operator!=(const SelfType& other) const { return !isEqual(other); }
-
-  difference_type operator-(const SelfType& other) const {
-    return other.computeDistance(*this);
-  }
-
-  /// Return either the index or the member name of the referenced value as a
-  /// Value.
-  Value key() const;
-
-  /// Return the index of the referenced Value, or -1 if it is not an
-  /// arrayValue.
-  UInt index() const;
-
-  /// Return the member name of the referenced Value, or "" if it is not an
-  /// objectValue.
-  /// \note Avoid `c_str()` on result, as embedded zeroes are possible.
-  String name() const;
-
-  /// Return the member name of the referenced Value. "" if it is not an
-  /// objectValue.
-  /// \deprecated This cannot be used for UTF-8 strings, since there can be
-  /// embedded nulls.
-  JSONCPP_DEPRECATED("Use `key = name();` instead.")
-  char const* memberName() const;
-  /// Return the member name of the referenced Value, or NULL if it is not an
-  /// objectValue.
-  /// \note Better version than memberName(). Allows embedded nulls.
-  char const* memberName(char const** end) const;
-
-protected:
-  Value& deref() const;
-
-  void increment();
-
-  void decrement();
-
-  difference_type computeDistance(const SelfType& other) const;
-
-  bool isEqual(const SelfType& other) const;
-
-  void copy(const SelfType& other);
-
-private:
-  Value::ObjectValues::iterator current_;
-  // Indicates that iterator is for a null value.
-  bool isNull_{true};
-
-public:
-  // For some reason, BORLAND needs these at the end, rather
-  // than earlier. No idea why.
-  ValueIteratorBase();
-  explicit ValueIteratorBase(const Value::ObjectValues::iterator& current);
-};
-
-/** \brief const iterator for object and array value.
- *
- */
-class JSON_API ValueConstIterator : public ValueIteratorBase {
-  friend class Value;
-
-public:
-  typedef const Value value_type;
-  // typedef unsigned int size_t;
-  // typedef int difference_type;
-  typedef const Value& reference;
-  typedef const Value* pointer;
-  typedef ValueConstIterator SelfType;
-
-  ValueConstIterator();
-  ValueConstIterator(ValueIterator const& other);
-
-private:
-  /*! \internal Use by Value to create an iterator.
-   */
-  explicit ValueConstIterator(const Value::ObjectValues::iterator& current);
-
-public:
-  SelfType& operator=(const ValueIteratorBase& other);
-
-  SelfType operator++(int) {
-    SelfType temp(*this);
-    ++*this;
-    return temp;
-  }
-
-  SelfType operator--(int) {
-    SelfType temp(*this);
-    --*this;
-    return temp;
-  }
-
-  SelfType& operator--() {
-    decrement();
-    return *this;
-  }
-
-  SelfType& operator++() {
-    increment();
-    return *this;
-  }
-
-  reference operator*() const { return deref(); }
-
-  pointer operator->() const { return &deref(); }
-};
-
-/** \brief Iterator for object and array value.
- */
-class JSON_API ValueIterator : public ValueIteratorBase {
-  friend class Value;
-
-public:
-  typedef Value value_type;
-  typedef unsigned int size_t;
-  typedef int difference_type;
-  typedef Value& reference;
-  typedef Value* pointer;
-  typedef ValueIterator SelfType;
-
-  ValueIterator();
-  explicit ValueIterator(const ValueConstIterator& other);
-  ValueIterator(const ValueIterator& other);
-
-private:
-  /*! \internal Use by Value to create an iterator.
-   */
-  explicit ValueIterator(const Value::ObjectValues::iterator& current);
-
-public:
-  SelfType& operator=(const SelfType& other);
-
-  SelfType operator++(int) {
-    SelfType temp(*this);
-    ++*this;
-    return temp;
-  }
-
-  SelfType operator--(int) {
-    SelfType temp(*this);
-    --*this;
-    return temp;
-  }
-
-  SelfType& operator--() {
-    decrement();
-    return *this;
-  }
-
-  SelfType& operator++() {
-    increment();
-    return *this;
-  }
-
-  reference operator*() const { return deref(); }
-
-  pointer operator->() const { return &deref(); }
-};
-
-inline void swap(Value& a, Value& b) { a.swap(b); }
-
-} // namespace Json
-
-#pragma pack(pop)
-
-#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-#pragma warning(pop)
-#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-
-#endif // CPPTL_JSON_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/value.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/reader.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef CPPTL_JSON_READER_H_INCLUDED
-#define CPPTL_JSON_READER_H_INCLUDED
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include "features.h"
-#include "value.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-#include <deque>
-#include <iosfwd>
-#include <istream>
-#include <stack>
-#include <string>
-
-// Disable warning C4251: <data member>: <type> needs to have dll-interface to
-// be used by...
-#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-#pragma warning(push)
-#pragma warning(disable : 4251)
-#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-
-#pragma pack(push, 8)
-
-namespace Json {
-
-/** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a
- *Value.
- *
- * \deprecated Use CharReader and CharReaderBuilder.
- */
-class JSON_API Reader {
-public:
-  typedef char Char;
-  typedef const Char* Location;
-
-  /** \brief An error tagged with where in the JSON text it was encountered.
-   *
-   * The offsets give the [start, limit) range of bytes within the text. Note
-   * that this is bytes, not codepoints.
-   *
-   */
-  struct StructuredError {
-    ptrdiff_t offset_start;
-    ptrdiff_t offset_limit;
-    String message;
-  };
-
-  /** \brief Constructs a Reader allowing all features
-   * for parsing.
-   */
-  JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead")
-  Reader();
-
-  /** \brief Constructs a Reader allowing the specified feature set
-   * for parsing.
-   */
-  JSONCPP_DEPRECATED("Use CharReader and CharReaderBuilder instead")
-  Reader(const Features& features);
-
-  /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
-   * document.
-   * \param document UTF-8 encoded string containing the document to read.
-   * \param root [out] Contains the root value of the document if it was
-   *             successfully parsed.
-   * \param collectComments \c true to collect comment and allow writing them
-   * back during
-   *                        serialization, \c false to discard comments.
-   *                        This parameter is ignored if
-   * Features::allowComments_
-   *                        is \c false.
-   * \return \c true if the document was successfully parsed, \c false if an
-   * error occurred.
-   */
-  bool
-  parse(const std::string& document, Value& root, bool collectComments = true);
-
-  /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
-   document.
-   * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
-   document to read.
-   * \param endDoc Pointer on the end of the UTF-8 encoded string of the
-   document to read.
-   *               Must be >= beginDoc.
-   * \param root [out] Contains the root value of the document if it was
-   *             successfully parsed.
-   * \param collectComments \c true to collect comment and allow writing them
-   back during
-   *                        serialization, \c false to discard comments.
-   *                        This parameter is ignored if
-   Features::allowComments_
-   *                        is \c false.
-   * \return \c true if the document was successfully parsed, \c false if an
-   error occurred.
-   */
-  bool parse(const char* beginDoc,
-             const char* endDoc,
-             Value& root,
-             bool collectComments = true);
-
-  /// \brief Parse from input stream.
-  /// \see Json::operator>>(std::istream&, Json::Value&).
-  bool parse(IStream& is, Value& root, bool collectComments = true);
-
-  /** \brief Returns a user friendly string that list errors in the parsed
-   * document.
-   * \return Formatted error message with the list of errors with their location
-   * in
-   *         the parsed document. An empty string is returned if no error
-   * occurred
-   *         during parsing.
-   * \deprecated Use getFormattedErrorMessages() instead (typo fix).
-   */
-  JSONCPP_DEPRECATED("Use getFormattedErrorMessages() instead.")
-  String getFormatedErrorMessages() const;
-
-  /** \brief Returns a user friendly string that list errors in the parsed
-   * document.
-   * \return Formatted error message with the list of errors with their location
-   * in
-   *         the parsed document. An empty string is returned if no error
-   * occurred
-   *         during parsing.
-   */
-  String getFormattedErrorMessages() const;
-
-  /** \brief Returns a vector of structured erros encounted while parsing.
-   * \return A (possibly empty) vector of StructuredError objects. Currently
-   *         only one error can be returned, but the caller should tolerate
-   * multiple
-   *         errors.  This can occur if the parser recovers from a non-fatal
-   *         parse error and then encounters additional errors.
-   */
-  std::vector<StructuredError> getStructuredErrors() const;
-
-  /** \brief Add a semantic error message.
-   * \param value JSON Value location associated with the error
-   * \param message The error message.
-   * \return \c true if the error was successfully added, \c false if the
-   * Value offset exceeds the document size.
-   */
-  bool pushError(const Value& value, const String& message);
-
-  /** \brief Add a semantic error message with extra context.
-   * \param value JSON Value location associated with the error
-   * \param message The error message.
-   * \param extra Additional JSON Value location to contextualize the error
-   * \return \c true if the error was successfully added, \c false if either
-   * Value offset exceeds the document size.
-   */
-  bool pushError(const Value& value, const String& message, const Value& extra);
-
-  /** \brief Return whether there are any errors.
-   * \return \c true if there are no errors to report \c false if
-   * errors have occurred.
-   */
-  bool good() const;
-
-private:
-  enum TokenType {
-    tokenEndOfStream = 0,
-    tokenObjectBegin,
-    tokenObjectEnd,
-    tokenArrayBegin,
-    tokenArrayEnd,
-    tokenString,
-    tokenNumber,
-    tokenTrue,
-    tokenFalse,
-    tokenNull,
-    tokenArraySeparator,
-    tokenMemberSeparator,
-    tokenComment,
-    tokenError
-  };
-
-  class Token {
-  public:
-    TokenType type_;
-    Location start_;
-    Location end_;
-  };
-
-  class ErrorInfo {
-  public:
-    Token token_;
-    String message_;
-    Location extra_;
-  };
-
-  typedef std::deque<ErrorInfo> Errors;
-
-  bool readToken(Token& token);
-  void skipSpaces();
-  bool match(Location pattern, int patternLength);
-  bool readComment();
-  bool readCStyleComment();
-  bool readCppStyleComment();
-  bool readString();
-  void readNumber();
-  bool readValue();
-  bool readObject(Token& token);
-  bool readArray(Token& token);
-  bool decodeNumber(Token& token);
-  bool decodeNumber(Token& token, Value& decoded);
-  bool decodeString(Token& token);
-  bool decodeString(Token& token, String& decoded);
-  bool decodeDouble(Token& token);
-  bool decodeDouble(Token& token, Value& decoded);
-  bool decodeUnicodeCodePoint(Token& token,
-                              Location& current,
-                              Location end,
-                              unsigned int& unicode);
-  bool decodeUnicodeEscapeSequence(Token& token,
-                                   Location& current,
-                                   Location end,
-                                   unsigned int& unicode);
-  bool addError(const String& message, Token& token, Location extra = nullptr);
-  bool recoverFromError(TokenType skipUntilToken);
-  bool addErrorAndRecover(const String& message,
-                          Token& token,
-                          TokenType skipUntilToken);
-  void skipUntilSpace();
-  Value& currentValue();
-  Char getNextChar();
-  void
-  getLocationLineAndColumn(Location location, int& line, int& column) const;
-  String getLocationLineAndColumn(Location location) const;
-  void addComment(Location begin, Location end, CommentPlacement placement);
-  void skipCommentTokens(Token& token);
-
-  static bool containsNewLine(Location begin, Location end);
-  static String normalizeEOL(Location begin, Location end);
-
-  typedef std::stack<Value*> Nodes;
-  Nodes nodes_;
-  Errors errors_;
-  String document_;
-  Location begin_{};
-  Location end_{};
-  Location current_{};
-  Location lastValueEnd_{};
-  Value* lastValue_{};
-  String commentsBefore_;
-  Features features_;
-  bool collectComments_{};
-}; // Reader
-
-/** Interface for reading JSON from a char array.
- */
-class JSON_API CharReader {
-public:
-  virtual ~CharReader() = default;
-  /** \brief Read a Value from a <a HREF="http://www.json.org">JSON</a>
-   document.
-   * The document must be a UTF-8 encoded string containing the document to
-   read.
-   *
-   * \param beginDoc Pointer on the beginning of the UTF-8 encoded string of the
-   document to read.
-   * \param endDoc Pointer on the end of the UTF-8 encoded string of the
-   document to read.
-   *        Must be >= beginDoc.
-   * \param root [out] Contains the root value of the document if it was
-   *             successfully parsed.
-   * \param errs [out] Formatted error messages (if not NULL)
-   *        a user friendly string that lists errors in the parsed
-   * document.
-   * \return \c true if the document was successfully parsed, \c false if an
-   error occurred.
-   */
-  virtual bool parse(char const* beginDoc,
-                     char const* endDoc,
-                     Value* root,
-                     String* errs) = 0;
-
-  class JSON_API Factory {
-  public:
-    virtual ~Factory() = default;
-    /** \brief Allocate a CharReader via operator new().
-     * \throw std::exception if something goes wrong (e.g. invalid settings)
-     */
-    virtual CharReader* newCharReader() const = 0;
-  }; // Factory
-};   // CharReader
-
-/** \brief Build a CharReader implementation.
-
-Usage:
-\code
-  using namespace Json;
-  CharReaderBuilder builder;
-  builder["collectComments"] = false;
-  Value value;
-  String errs;
-  bool ok = parseFromStream(builder, std::cin, &value, &errs);
-\endcode
-*/
-class JSON_API CharReaderBuilder : public CharReader::Factory {
-public:
-  // Note: We use a Json::Value so that we can add data-members to this class
-  // without a major version bump.
-  /** Configuration of this builder.
-    These are case-sensitive.
-    Available settings (case-sensitive):
-    - `"collectComments": false or true`
-      - true to collect comment and allow writing them
-        back during serialization, false to discard comments.
-        This parameter is ignored if allowComments is false.
-    - `"allowComments": false or true`
-      - true if comments are allowed.
-    - `"strictRoot": false or true`
-      - true if root must be either an array or an object value
-    - `"allowDroppedNullPlaceholders": false or true`
-      - true if dropped null placeholders are allowed. (See
-    StreamWriterBuilder.)
-    - `"allowNumericKeys": false or true`
-      - true if numeric object keys are allowed.
-    - `"allowSingleQuotes": false or true`
-      - true if '' are allowed for strings (both keys and values)
-    - `"stackLimit": integer`
-      - Exceeding stackLimit (recursive depth of `readValue()`) will
-        cause an exception.
-      - This is a security issue (seg-faults caused by deeply nested JSON),
-        so the default is low.
-    - `"failIfExtra": false or true`
-      - If true, `parse()` returns false when extra non-whitespace trails
-        the JSON value in the input string.
-    - `"rejectDupKeys": false or true`
-      - If true, `parse()` returns false when a key is duplicated within an
-    object.
-    - `"allowSpecialFloats": false or true`
-      - If true, special float values (NaNs and infinities) are allowed
-        and their values are lossfree restorable.
-
-    You can examine 'settings_` yourself
-    to see the defaults. You can also write and read them just like any
-    JSON Value.
-    \sa setDefaults()
-    */
-  Json::Value settings_;
-
-  CharReaderBuilder();
-  ~CharReaderBuilder() override;
-
-  CharReader* newCharReader() const override;
-
-  /** \return true if 'settings' are legal and consistent;
-   *   otherwise, indicate bad settings via 'invalid'.
-   */
-  bool validate(Json::Value* invalid) const;
-
-  /** A simple way to update a specific setting.
-   */
-  Value& operator[](const String& key);
-
-  /** Called by ctor, but you can use this to reset settings_.
-   * \pre 'settings' != NULL (but Json::null is fine)
-   * \remark Defaults:
-   * \snippet src/lib_json/json_reader.cpp CharReaderBuilderDefaults
-   */
-  static void setDefaults(Json::Value* settings);
-  /** Same as old Features::strictMode().
-   * \pre 'settings' != NULL (but Json::null is fine)
-   * \remark Defaults:
-   * \snippet src/lib_json/json_reader.cpp CharReaderBuilderStrictMode
-   */
-  static void strictMode(Json::Value* settings);
-};
-
-/** Consume entire stream and use its begin/end.
- * Someday we might have a real StreamReader, but for now this
- * is convenient.
- */
-bool JSON_API parseFromStream(CharReader::Factory const&,
-                              IStream&,
-                              Value* root,
-                              std::string* errs);
-
-/** \brief Read from 'sin' into 'root'.
-
- Always keep comments from the input JSON.
-
- This can be used to read a file into a particular sub-object.
- For example:
- \code
- Json::Value root;
- cin >> root["dir"]["file"];
- cout << root;
- \endcode
- Result:
- \verbatim
- {
- "dir": {
-     "file": {
-     // The input stream JSON would be nested here.
-     }
- }
- }
- \endverbatim
- \throw std::exception on parse error.
- \see Json::operator<<()
-*/
-JSON_API IStream& operator>>(IStream&, Value&);
-
-} // namespace Json
-
-#pragma pack(pop)
-
-#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-#pragma warning(pop)
-#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-
-#endif // CPPTL_JSON_READER_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/reader.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/writer.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef JSON_WRITER_H_INCLUDED
-#define JSON_WRITER_H_INCLUDED
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include "value.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-#include <ostream>
-#include <string>
-#include <vector>
-
-// Disable warning C4251: <data member>: <type> needs to have dll-interface to
-// be used by...
-#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING) && defined(_MSC_VER)
-#pragma warning(push)
-#pragma warning(disable : 4251)
-#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-
-#pragma pack(push, 8)
-
-namespace Json {
-
-class Value;
-
-/**
-
-Usage:
-\code
-  using namespace Json;
-  void writeToStdout(StreamWriter::Factory const& factory, Value const& value) {
-    std::unique_ptr<StreamWriter> const writer(
-      factory.newStreamWriter());
-    writer->write(value, &std::cout);
-    std::cout << std::endl;  // add lf and flush
-  }
-\endcode
-*/
-class JSON_API StreamWriter {
-protected:
-  OStream* sout_; // not owned; will not delete
-public:
-  StreamWriter();
-  virtual ~StreamWriter();
-  /** Write Value into document as configured in sub-class.
-      Do not take ownership of sout, but maintain a reference during function.
-      \pre sout != NULL
-      \return zero on success (For now, we always return zero, so check the
-     stream instead.) \throw std::exception possibly, depending on configuration
-   */
-  virtual int write(Value const& root, OStream* sout) = 0;
-
-  /** \brief A simple abstract factory.
-   */
-  class JSON_API Factory {
-  public:
-    virtual ~Factory();
-    /** \brief Allocate a CharReader via operator new().
-     * \throw std::exception if something goes wrong (e.g. invalid settings)
-     */
-    virtual StreamWriter* newStreamWriter() const = 0;
-  }; // Factory
-};   // StreamWriter
-
-/** \brief Write into stringstream, then return string, for convenience.
- * A StreamWriter will be created from the factory, used, and then deleted.
- */
-String JSON_API writeString(StreamWriter::Factory const& factory,
-                            Value const& root);
-
-/** \brief Build a StreamWriter implementation.
-
-Usage:
-\code
-  using namespace Json;
-  Value value = ...;
-  StreamWriterBuilder builder;
-  builder["commentStyle"] = "None";
-  builder["indentation"] = "   ";  // or whatever you like
-  std::unique_ptr<Json::StreamWriter> writer(
-      builder.newStreamWriter());
-  writer->write(value, &std::cout);
-  std::cout << std::endl;  // add lf and flush
-\endcode
-*/
-class JSON_API StreamWriterBuilder : public StreamWriter::Factory {
-public:
-  // Note: We use a Json::Value so that we can add data-members to this class
-  // without a major version bump.
-  /** Configuration of this builder.
-    Available settings (case-sensitive):
-    - "commentStyle": "None" or "All"
-    - "indentation":  "<anything>".
-      - Setting this to an empty string also omits newline characters.
-    - "enableYAMLCompatibility": false or true
-      - slightly change the whitespace around colons
-    - "dropNullPlaceholders": false or true
-      - Drop the "null" string from the writer's output for nullValues.
-        Strictly speaking, this is not valid JSON. But when the output is being
-        fed to a browser's JavaScript, it makes for smaller output and the
-        browser can handle the output just fine.
-    - "useSpecialFloats": false or true
-      - If true, outputs non-finite floating point values in the following way:
-        NaN values as "NaN", positive infinity as "Infinity", and negative
-    infinity as "-Infinity".
-    - "precision": int
-      - Number of precision digits for formatting of real values.
-    - "precisionType": "significant"(default) or "decimal"
-      - Type of precision for formatting of real values.
-
-    You can examine 'settings_` yourself
-    to see the defaults. You can also write and read them just like any
-    JSON Value.
-    \sa setDefaults()
-    */
-  Json::Value settings_;
-
-  StreamWriterBuilder();
-  ~StreamWriterBuilder() override;
-
-  /**
-   * \throw std::exception if something goes wrong (e.g. invalid settings)
-   */
-  StreamWriter* newStreamWriter() const override;
-
-  /** \return true if 'settings' are legal and consistent;
-   *   otherwise, indicate bad settings via 'invalid'.
-   */
-  bool validate(Json::Value* invalid) const;
-  /** A simple way to update a specific setting.
-   */
-  Value& operator[](const String& key);
-
-  /** Called by ctor, but you can use this to reset settings_.
-   * \pre 'settings' != NULL (but Json::null is fine)
-   * \remark Defaults:
-   * \snippet src/lib_json/json_writer.cpp StreamWriterBuilderDefaults
-   */
-  static void setDefaults(Json::Value* settings);
-};
-
-/** \brief Abstract class for writers.
- * \deprecated Use StreamWriter. (And really, this is an implementation detail.)
- */
-class JSONCPP_DEPRECATED("Use StreamWriter instead") JSON_API Writer {
-public:
-  virtual ~Writer();
-
-  virtual String write(const Value& root) = 0;
-};
-
-/** \brief Outputs a Value in <a HREF="http://www.json.org">JSON</a> format
- *without formatting (not human friendly).
- *
- * The JSON document is written in a single line. It is not intended for 'human'
- *consumption,
- * but may be useful to support feature such as RPC where bandwidth is limited.
- * \sa Reader, Value
- * \deprecated Use StreamWriterBuilder.
- */
-#if defined(_MSC_VER)
-#pragma warning(push)
-#pragma warning(disable : 4996) // Deriving from deprecated class
-#endif
-class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API FastWriter
-    : public Writer {
-public:
-  FastWriter();
-  ~FastWriter() override = default;
-
-  void enableYAMLCompatibility();
-
-  /** \brief Drop the "null" string from the writer's output for nullValues.
-   * Strictly speaking, this is not valid JSON. But when the output is being
-   * fed to a browser's JavaScript, it makes for smaller output and the
-   * browser can handle the output just fine.
-   */
-  void dropNullPlaceholders();
-
-  void omitEndingLineFeed();
-
-public: // overridden from Writer
-  String write(const Value& root) override;
-
-private:
-  void writeValue(const Value& value);
-
-  String document_;
-  bool yamlCompatibilityEnabled_{false};
-  bool dropNullPlaceholders_{false};
-  bool omitEndingLineFeed_{false};
-};
-#if defined(_MSC_VER)
-#pragma warning(pop)
-#endif
-
-/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
- *human friendly way.
- *
- * The rules for line break and indent are as follow:
- * - Object value:
- *     - if empty then print {} without indent and line break
- *     - if not empty the print '{', line break & indent, print one value per
- *line
- *       and then unindent and line break and print '}'.
- * - Array value:
- *     - if empty then print [] without indent and line break
- *     - if the array contains no object value, empty array or some other value
- *types,
- *       and all the values fit on one lines, then print the array on a single
- *line.
- *     - otherwise, it the values do not fit on one line, or the array contains
- *       object or non empty array, then print one value per line.
- *
- * If the Value have comments then they are outputed according to their
- *#CommentPlacement.
- *
- * \sa Reader, Value, Value::setComment()
- * \deprecated Use StreamWriterBuilder.
- */
-#if defined(_MSC_VER)
-#pragma warning(push)
-#pragma warning(disable : 4996) // Deriving from deprecated class
-#endif
-class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API
-    StyledWriter : public Writer {
-public:
-  StyledWriter();
-  ~StyledWriter() override = default;
-
-public: // overridden from Writer
-  /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
-   * \param root Value to serialize.
-   * \return String containing the JSON document that represents the root value.
-   */
-  String write(const Value& root) override;
-
-private:
-  void writeValue(const Value& value);
-  void writeArrayValue(const Value& value);
-  bool isMultilineArray(const Value& value);
-  void pushValue(const String& value);
-  void writeIndent();
-  void writeWithIndent(const String& value);
-  void indent();
-  void unindent();
-  void writeCommentBeforeValue(const Value& root);
-  void writeCommentAfterValueOnSameLine(const Value& root);
-  static bool hasCommentForValue(const Value& value);
-  static String normalizeEOL(const String& text);
-
-  typedef std::vector<String> ChildValues;
-
-  ChildValues childValues_;
-  String document_;
-  String indentString_;
-  unsigned int rightMargin_{74};
-  unsigned int indentSize_{3};
-  bool addChildValues_{false};
-};
-#if defined(_MSC_VER)
-#pragma warning(pop)
-#endif
-
-/** \brief Writes a Value in <a HREF="http://www.json.org">JSON</a> format in a
- human friendly way,
-     to a stream rather than to a string.
- *
- * The rules for line break and indent are as follow:
- * - Object value:
- *     - if empty then print {} without indent and line break
- *     - if not empty the print '{', line break & indent, print one value per
- line
- *       and then unindent and line break and print '}'.
- * - Array value:
- *     - if empty then print [] without indent and line break
- *     - if the array contains no object value, empty array or some other value
- types,
- *       and all the values fit on one lines, then print the array on a single
- line.
- *     - otherwise, it the values do not fit on one line, or the array contains
- *       object or non empty array, then print one value per line.
- *
- * If the Value have comments then they are outputed according to their
- #CommentPlacement.
- *
- * \sa Reader, Value, Value::setComment()
- * \deprecated Use StreamWriterBuilder.
- */
-#if defined(_MSC_VER)
-#pragma warning(push)
-#pragma warning(disable : 4996) // Deriving from deprecated class
-#endif
-class JSONCPP_DEPRECATED("Use StreamWriterBuilder instead") JSON_API
-    StyledStreamWriter {
-public:
-  /**
-   * \param indentation Each level will be indented by this amount extra.
-   */
-  StyledStreamWriter(String indentation = "\t");
-  ~StyledStreamWriter() = default;
-
-public:
-  /** \brief Serialize a Value in <a HREF="http://www.json.org">JSON</a> format.
-   * \param out Stream to write to. (Can be ostringstream, e.g.)
-   * \param root Value to serialize.
-   * \note There is no point in deriving from Writer, since write() should not
-   * return a value.
-   */
-  void write(OStream& out, const Value& root);
-
-private:
-  void writeValue(const Value& value);
-  void writeArrayValue(const Value& value);
-  bool isMultilineArray(const Value& value);
-  void pushValue(const String& value);
-  void writeIndent();
-  void writeWithIndent(const String& value);
-  void indent();
-  void unindent();
-  void writeCommentBeforeValue(const Value& root);
-  void writeCommentAfterValueOnSameLine(const Value& root);
-  static bool hasCommentForValue(const Value& value);
-  static String normalizeEOL(const String& text);
-
-  typedef std::vector<String> ChildValues;
-
-  ChildValues childValues_;
-  OStream* document_;
-  String indentString_;
-  unsigned int rightMargin_{74};
-  String indentation_;
-  bool addChildValues_ : 1;
-  bool indented_ : 1;
-};
-#if defined(_MSC_VER)
-#pragma warning(pop)
-#endif
-
-#if defined(JSON_HAS_INT64)
-String JSON_API valueToString(Int value);
-String JSON_API valueToString(UInt value);
-#endif // if defined(JSON_HAS_INT64)
-String JSON_API valueToString(LargestInt value);
-String JSON_API valueToString(LargestUInt value);
-String JSON_API
-valueToString(double value,
-              unsigned int precision = Value::defaultRealPrecision,
-              PrecisionType precisionType = PrecisionType::significantDigits);
-String JSON_API valueToString(bool value);
-String JSON_API valueToQuotedString(const char* value);
-
-/// \brief Output using the StyledStreamWriter.
-/// \see Json::operator>>()
-JSON_API OStream& operator<<(OStream&, const Value& root);
-
-} // namespace Json
-
-#pragma pack(pop)
-
-#if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-#pragma warning(pop)
-#endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
-
-#endif // JSON_WRITER_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/writer.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: include/json/assertions.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef CPPTL_JSON_ASSERTIONS_H_INCLUDED
-#define CPPTL_JSON_ASSERTIONS_H_INCLUDED
-
-#include <cstdlib>
-#include <sstream>
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include "config.h"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-
-/** It should not be possible for a maliciously designed file to
- *  cause an abort() or seg-fault, so these macros are used only
- *  for pre-condition violations and internal logic errors.
- */
-#if JSON_USE_EXCEPTION
-
-// @todo <= add detail about condition in exception
-#define JSON_ASSERT(condition)                                                 \
-  {                                                                            \
-    if (!(condition)) {                                                        \
-      Json::throwLogicError("assert json failed");                             \
-    }                                                                          \
-  }
-
-#define JSON_FAIL_MESSAGE(message)                                             \
-  {                                                                            \
-    OStringStream oss;                                                         \
-    oss << message;                                                            \
-    Json::throwLogicError(oss.str());                                          \
-    abort();                                                                   \
-  }
-
-#else // JSON_USE_EXCEPTION
-
-#define JSON_ASSERT(condition) assert(condition)
-
-// The call to assert() will show the failure message in debug builds. In
-// release builds we abort, for a core-dump or debugger.
-#define JSON_FAIL_MESSAGE(message)                                             \
-  {                                                                            \
-    OStringStream oss;                                                         \
-    oss << message;                                                            \
-    assert(false && oss.str().c_str());                                        \
-    abort();                                                                   \
-  }
-
-#endif
-
-#define JSON_ASSERT_MESSAGE(condition, message)                                \
-  if (!(condition)) {                                                          \
-    JSON_FAIL_MESSAGE(message);                                                \
-  }
-
-#endif // CPPTL_JSON_ASSERTIONS_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: include/json/assertions.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-#endif //ifndef JSON_AMALGAMATED_H_INCLUDED
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/jsoncpp-1.8.4/jsoncpp.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5418 +0,0 @@
-/// Json-cpp amalgamated source (http://jsoncpp.sourceforge.net/).
-/// It is intended to be used with #include "json/json.h"
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: LICENSE
-// //////////////////////////////////////////////////////////////////////
-
-/*
-The JsonCpp library's source code, including accompanying documentation, 
-tests and demonstration applications, are licensed under the following
-conditions...
-
-Baptiste Lepilleur and The JsonCpp Authors explicitly disclaim copyright in all 
-jurisdictions which recognize such a disclaimer. In such jurisdictions, 
-this software is released into the Public Domain.
-
-In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
-2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur and
-The JsonCpp Authors, and is released under the terms of the MIT License (see below).
-
-In jurisdictions which recognize Public Domain property, the user of this 
-software may choose to accept it either as 1) Public Domain, 2) under the 
-conditions of the MIT License (see below), or 3) under the terms of dual 
-Public Domain/MIT License conditions described here, as they choose.
-
-The MIT License is about as close to Public Domain as a license can get, and is
-described in clear, concise terms at:
-
-   http://en.wikipedia.org/wiki/MIT_License
-   
-The full text of the MIT License follows:
-
-========================================================================
-Copyright (c) 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use, copy,
-modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-========================================================================
-(END LICENSE TEXT)
-
-The MIT license is compatible with both the GPL and commercial
-software, affording one all of the rights of Public Domain with the
-minor nuisance of being required to keep the above copyright notice
-and license text in the source code. Note also that by accepting the
-Public Domain "license" you can re-license your copy using whatever
-license you like.
-
-*/
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: LICENSE
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-#include "json/json.h"
-
-#ifndef JSON_IS_AMALGAMATION
-#error "Compile with -I PATH_TO_JSON_DIRECTORY"
-#endif
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: src/lib_json/json_tool.h
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED
-#define LIB_JSONCPP_JSON_TOOL_H_INCLUDED
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include <json/config.h>
-#endif
-
-// Also support old flag NO_LOCALE_SUPPORT
-#ifdef NO_LOCALE_SUPPORT
-#define JSONCPP_NO_LOCALE_SUPPORT
-#endif
-
-#ifndef JSONCPP_NO_LOCALE_SUPPORT
-#include <clocale>
-#endif
-
-/* This header provides common string manipulation support, such as UTF-8,
- * portable conversion from/to string...
- *
- * It is an internal header that must not be exposed.
- */
-
-namespace Json {
-static inline char getDecimalPoint() {
-#ifdef JSONCPP_NO_LOCALE_SUPPORT
-  return '\0';
-#else
-  struct lconv* lc = localeconv();
-  return lc ? *(lc->decimal_point) : '\0';
-#endif
-}
-
-/// Converts a unicode code-point to UTF-8.
-static inline String codePointToUTF8(unsigned int cp) {
-  String result;
-
-  // based on description from http://en.wikipedia.org/wiki/UTF-8
-
-  if (cp <= 0x7f) {
-    result.resize(1);
-    result[0] = static_cast<char>(cp);
-  } else if (cp <= 0x7FF) {
-    result.resize(2);
-    result[1] = static_cast<char>(0x80 | (0x3f & cp));
-    result[0] = static_cast<char>(0xC0 | (0x1f & (cp >> 6)));
-  } else if (cp <= 0xFFFF) {
-    result.resize(3);
-    result[2] = static_cast<char>(0x80 | (0x3f & cp));
-    result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));
-    result[0] = static_cast<char>(0xE0 | (0xf & (cp >> 12)));
-  } else if (cp <= 0x10FFFF) {
-    result.resize(4);
-    result[3] = static_cast<char>(0x80 | (0x3f & cp));
-    result[2] = static_cast<char>(0x80 | (0x3f & (cp >> 6)));
-    result[1] = static_cast<char>(0x80 | (0x3f & (cp >> 12)));
-    result[0] = static_cast<char>(0xF0 | (0x7 & (cp >> 18)));
-  }
-
-  return result;
-}
-
-enum {
-  /// Constant that specify the size of the buffer that must be passed to
-  /// uintToString.
-  uintToStringBufferSize = 3 * sizeof(LargestUInt) + 1
-};
-
-// Defines a char buffer for use with uintToString().
-typedef char UIntToStringBuffer[uintToStringBufferSize];
-
-/** Converts an unsigned integer to string.
- * @param value Unsigned integer to convert to string
- * @param current Input/Output string buffer.
- *        Must have at least uintToStringBufferSize chars free.
- */
-static inline void uintToString(LargestUInt value, char*& current) {
-  *--current = 0;
-  do {
-    *--current = static_cast<char>(value % 10U + static_cast<unsigned>('0'));
-    value /= 10;
-  } while (value != 0);
-}
-
-/** Change ',' to '.' everywhere in buffer.
- *
- * We had a sophisticated way, but it did not work in WinCE.
- * @see https://github.com/open-source-parsers/jsoncpp/pull/9
- */
-template <typename Iter> Iter fixNumericLocale(Iter begin, Iter end) {
-  for (; begin != end; ++begin) {
-    if (*begin == ',') {
-      *begin = '.';
-    }
-  }
-  return begin;
-}
-
-template <typename Iter> void fixNumericLocaleInput(Iter begin, Iter end) {
-  char decimalPoint = getDecimalPoint();
-  if (decimalPoint == '\0' || decimalPoint == '.') {
-    return;
-  }
-  for (; begin != end; ++begin) {
-    if (*begin == '.') {
-      *begin = decimalPoint;
-    }
-  }
-}
-
-/**
- * Return iterator that would be the new end of the range [begin,end), if we
- * were to delete zeros in the end of string, but not the last zero before '.'.
- */
-template <typename Iter> Iter fixZerosInTheEnd(Iter begin, Iter end) {
-  for (; begin != end; --end) {
-    if (*(end - 1) != '0') {
-      return end;
-    }
-    // Don't delete the last zero before the decimal point.
-    if (begin != (end - 1) && *(end - 2) == '.') {
-      return end;
-    }
-  }
-  return end;
-}
-
-} // namespace Json
-
-#endif // LIB_JSONCPP_JSON_TOOL_H_INCLUDED
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: src/lib_json/json_tool.h
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: src/lib_json/json_reader.cpp
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2011 Baptiste Lepilleur and The JsonCpp Authors
-// Copyright (C) 2016 InfoTeCS JSC. All rights reserved.
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include "json_tool.h"
-#include <json/assertions.h>
-#include <json/reader.h>
-#include <json/value.h>
-#endif // if !defined(JSON_IS_AMALGAMATION)
-#include <cassert>
-#include <cstring>
-#include <istream>
-#include <limits>
-#include <memory>
-#include <set>
-#include <sstream>
-#include <utility>
-
-#include <cstdio>
-#if __cplusplus >= 201103L
-
-#if !defined(sscanf)
-#define sscanf std::sscanf
-#endif
-
-#endif //__cplusplus
-
-#if defined(_MSC_VER)
-#if !defined(_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES)
-#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
-#endif //_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES
-#endif //_MSC_VER
-
-#if defined(_MSC_VER)
-// Disable warning about strdup being deprecated.
-#pragma warning(disable : 4996)
-#endif
-
-// Define JSONCPP_DEPRECATED_STACK_LIMIT as an appropriate integer at compile
-// time to change the stack limit
-#if !defined(JSONCPP_DEPRECATED_STACK_LIMIT)
-#define JSONCPP_DEPRECATED_STACK_LIMIT 1000
-#endif
-
-static size_t const stackLimit_g =
-    JSONCPP_DEPRECATED_STACK_LIMIT; // see readValue()
-
-namespace Json {
-
-#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520)
-typedef std::unique_ptr<CharReader> CharReaderPtr;
-#else
-typedef std::unique_ptr<CharReader> CharReaderPtr;
-#endif
-
-// Implementation of class Features
-// ////////////////////////////////
-
-Features::Features() = default;
-
-Features Features::all() { return {}; }
-
-Features Features::strictMode() {
-  Features features;
-  features.allowComments_ = false;
-  features.strictRoot_ = true;
-  features.allowDroppedNullPlaceholders_ = false;
-  features.allowNumericKeys_ = false;
-  return features;
-}
-
-// Implementation of class Reader
-// ////////////////////////////////
-
-bool Reader::containsNewLine(Reader::Location begin, Reader::Location end) {
-  for (; begin < end; ++begin)
-    if (*begin == '\n' || *begin == '\r')
-      return true;
-  return false;
-}
-
-// Class Reader
-// //////////////////////////////////////////////////////////////////
-
-Reader::Reader()
-    : errors_(), document_(), commentsBefore_(), features_(Features::all()) {}
-
-Reader::Reader(const Features& features)
-    : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
-      lastValue_(), commentsBefore_(), features_(features), collectComments_() {
-}
-
-bool Reader::parse(const std::string& document,
-                   Value& root,
-                   bool collectComments) {
-  document_.assign(document.begin(), document.end());
-  const char* begin = document_.c_str();
-  const char* end = begin + document_.length();
-  return parse(begin, end, root, collectComments);
-}
-
-bool Reader::parse(std::istream& is, Value& root, bool collectComments) {
-  // std::istream_iterator<char> begin(is);
-  // std::istream_iterator<char> end;
-  // Those would allow streamed input from a file, if parse() were a
-  // template function.
-
-  // Since String is reference-counted, this at least does not
-  // create an extra copy.
-  String doc;
-  std::getline(is, doc, (char)EOF);
-  return parse(doc.data(), doc.data() + doc.size(), root, collectComments);
-}
-
-bool Reader::parse(const char* beginDoc,
-                   const char* endDoc,
-                   Value& root,
-                   bool collectComments) {
-  if (!features_.allowComments_) {
-    collectComments = false;
-  }
-
-  begin_ = beginDoc;
-  end_ = endDoc;
-  collectComments_ = collectComments;
-  current_ = begin_;
-  lastValueEnd_ = nullptr;
-  lastValue_ = nullptr;
-  commentsBefore_.clear();
-  errors_.clear();
-  while (!nodes_.empty())
-    nodes_.pop();
-  nodes_.push(&root);
-
-  bool successful = readValue();
-  Token token;
-  skipCommentTokens(token);
-  if (collectComments_ && !commentsBefore_.empty())
-    root.setComment(commentsBefore_, commentAfter);
-  if (features_.strictRoot_) {
-    if (!root.isArray() && !root.isObject()) {
-      // Set error location to start of doc, ideally should be first token found
-      // in doc
-      token.type_ = tokenError;
-      token.start_ = beginDoc;
-      token.end_ = endDoc;
-      addError(
-          "A valid JSON document must be either an array or an object value.",
-          token);
-      return false;
-    }
-  }
-  return successful;
-}
-
-bool Reader::readValue() {
-  // readValue() may call itself only if it calls readObject() or ReadArray().
-  // These methods execute nodes_.push() just before and nodes_.pop)() just
-  // after calling readValue(). parse() executes one nodes_.push(), so > instead
-  // of >=.
-  if (nodes_.size() > stackLimit_g)
-    throwRuntimeError("Exceeded stackLimit in readValue().");
-
-  Token token;
-  skipCommentTokens(token);
-  bool successful = true;
-
-  if (collectComments_ && !commentsBefore_.empty()) {
-    currentValue().setComment(commentsBefore_, commentBefore);
-    commentsBefore_.clear();
-  }
-
-  switch (token.type_) {
-  case tokenObjectBegin:
-    successful = readObject(token);
-    currentValue().setOffsetLimit(current_ - begin_);
-    break;
-  case tokenArrayBegin:
-    successful = readArray(token);
-    currentValue().setOffsetLimit(current_ - begin_);
-    break;
-  case tokenNumber:
-    successful = decodeNumber(token);
-    break;
-  case tokenString:
-    successful = decodeString(token);
-    break;
-  case tokenTrue: {
-    Value v(true);
-    currentValue().swapPayload(v);
-    currentValue().setOffsetStart(token.start_ - begin_);
-    currentValue().setOffsetLimit(token.end_ - begin_);
-  } break;
-  case tokenFalse: {
-    Value v(false);
-    currentValue().swapPayload(v);
-    currentValue().setOffsetStart(token.start_ - begin_);
-    currentValue().setOffsetLimit(token.end_ - begin_);
-  } break;
-  case tokenNull: {
-    Value v;
-    currentValue().swapPayload(v);
-    currentValue().setOffsetStart(token.start_ - begin_);
-    currentValue().setOffsetLimit(token.end_ - begin_);
-  } break;
-  case tokenArraySeparator:
-  case tokenObjectEnd:
-  case tokenArrayEnd:
-    if (features_.allowDroppedNullPlaceholders_) {
-      // "Un-read" the current token and mark the current value as a null
-      // token.
-      current_--;
-      Value v;
-      currentValue().swapPayload(v);
-      currentValue().setOffsetStart(current_ - begin_ - 1);
-      currentValue().setOffsetLimit(current_ - begin_);
-      break;
-    } // Else, fall through...
-  default:
-    currentValue().setOffsetStart(token.start_ - begin_);
-    currentValue().setOffsetLimit(token.end_ - begin_);
-    return addError("Syntax error: value, object or array expected.", token);
-  }
-
-  if (collectComments_) {
-    lastValueEnd_ = current_;
-    lastValue_ = &currentValue();
-  }
-
-  return successful;
-}
-
-void Reader::skipCommentTokens(Token& token) {
-  if (features_.allowComments_) {
-    do {
-      readToken(token);
-    } while (token.type_ == tokenComment);
-  } else {
-    readToken(token);
-  }
-}
-
-bool Reader::readToken(Token& token) {
-  skipSpaces();
-  token.start_ = current_;
-  Char c = getNextChar();
-  bool ok = true;
-  switch (c) {
-  case '{':
-    token.type_ = tokenObjectBegin;
-    break;
-  case '}':
-    token.type_ = tokenObjectEnd;
-    break;
-  case '[':
-    token.type_ = tokenArrayBegin;
-    break;
-  case ']':
-    token.type_ = tokenArrayEnd;
-    break;
-  case '"':
-    token.type_ = tokenString;
-    ok = readString();
-    break;
-  case '/':
-    token.type_ = tokenComment;
-    ok = readComment();
-    break;
-  case '0':
-  case '1':
-  case '2':
-  case '3':
-  case '4':
-  case '5':
-  case '6':
-  case '7':
-  case '8':
-  case '9':
-  case '-':
-    token.type_ = tokenNumber;
-    readNumber();
-    break;
-  case 't':
-    token.type_ = tokenTrue;
-    ok = match("rue", 3);
-    break;
-  case 'f':
-    token.type_ = tokenFalse;
-    ok = match("alse", 4);
-    break;
-  case 'n':
-    token.type_ = tokenNull;
-    ok = match("ull", 3);
-    break;
-  case ',':
-    token.type_ = tokenArraySeparator;
-    break;
-  case ':':
-    token.type_ = tokenMemberSeparator;
-    break;
-  case 0:
-    token.type_ = tokenEndOfStream;
-    break;
-  default:
-    ok = false;
-    break;
-  }
-  if (!ok)
-    token.type_ = tokenError;
-  token.end_ = current_;
-  return true;
-}
-
-void Reader::skipSpaces() {
-  while (current_ != end_) {
-    Char c = *current_;
-    if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
-      ++current_;
-    else
-      break;
-  }
-}
-
-bool Reader::match(Location pattern, int patternLength) {
-  if (end_ - current_ < patternLength)
-    return false;
-  int index = patternLength;
-  while (index--)
-    if (current_[index] != pattern[index])
-      return false;
-  current_ += patternLength;
-  return true;
-}
-
-bool Reader::readComment() {
-  Location commentBegin = current_ - 1;
-  Char c = getNextChar();
-  bool successful = false;
-  if (c == '*')
-    successful = readCStyleComment();
-  else if (c == '/')
-    successful = readCppStyleComment();
-  if (!successful)
-    return false;
-
-  if (collectComments_) {
-    CommentPlacement placement = commentBefore;
-    if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) {
-      if (c != '*' || !containsNewLine(commentBegin, current_))
-        placement = commentAfterOnSameLine;
-    }
-
-    addComment(commentBegin, current_, placement);
-  }
-  return true;
-}
-
-String Reader::normalizeEOL(Reader::Location begin, Reader::Location end) {
-  String normalized;
-  normalized.reserve(static_cast<size_t>(end - begin));
-  Reader::Location current = begin;
-  while (current != end) {
-    char c = *current++;
-    if (c == '\r') {
-      if (current != end && *current == '\n')
-        // convert dos EOL
-        ++current;
-      // convert Mac EOL
-      normalized += '\n';
-    } else {
-      normalized += c;
-    }
-  }
-  return normalized;
-}
-
-void Reader::addComment(Location begin,
-                        Location end,
-                        CommentPlacement placement) {
-  assert(collectComments_);
-  const String& normalized = normalizeEOL(begin, end);
-  if (placement == commentAfterOnSameLine) {
-    assert(lastValue_ != nullptr);
-    lastValue_->setComment(normalized, placement);
-  } else {
-    commentsBefore_ += normalized;
-  }
-}
-
-bool Reader::readCStyleComment() {
-  while ((current_ + 1) < end_) {
-    Char c = getNextChar();
-    if (c == '*' && *current_ == '/')
-      break;
-  }
-  return getNextChar() == '/';
-}
-
-bool Reader::readCppStyleComment() {
-  while (current_ != end_) {
-    Char c = getNextChar();
-    if (c == '\n')
-      break;
-    if (c == '\r') {
-      // Consume DOS EOL. It will be normalized in addComment.
-      if (current_ != end_ && *current_ == '\n')
-        getNextChar();
-      // Break on Moc OS 9 EOL.
-      break;
-    }
-  }
-  return true;
-}
-
-void Reader::readNumber() {
-  const char* p = current_;
-  char c = '0'; // stopgap for already consumed character
-  // integral part
-  while (c >= '0' && c <= '9')
-    c = (current_ = p) < end_ ? *p++ : '\0';
-  // fractional part
-  if (c == '.') {
-    c = (current_ = p) < end_ ? *p++ : '\0';
-    while (c >= '0' && c <= '9')
-      c = (current_ = p) < end_ ? *p++ : '\0';
-  }
-  // exponential part
-  if (c == 'e' || c == 'E') {
-    c = (current_ = p) < end_ ? *p++ : '\0';
-    if (c == '+' || c == '-')
-      c = (current_ = p) < end_ ? *p++ : '\0';
-    while (c >= '0' && c <= '9')
-      c = (current_ = p) < end_ ? *p++ : '\0';
-  }
-}
-
-bool Reader::readString() {
-  Char c = '\0';
-  while (current_ != end_) {
-    c = getNextChar();
-    if (c == '\\')
-      getNextChar();
-    else if (c == '"')
-      break;
-  }
-  return c == '"';
-}
-
-bool Reader::readObject(Token& token) {
-  Token tokenName;
-  String name;
-  Value init(objectValue);
-  currentValue().swapPayload(init);
-  currentValue().setOffsetStart(token.start_ - begin_);
-  while (readToken(tokenName)) {
-    bool initialTokenOk = true;
-    while (tokenName.type_ == tokenComment && initialTokenOk)
-      initialTokenOk = readToken(tokenName);
-    if (!initialTokenOk)
-      break;
-    if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object
-      return true;
-    name.clear();
-    if (tokenName.type_ == tokenString) {
-      if (!decodeString(tokenName, name))
-        return recoverFromError(tokenObjectEnd);
-    } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) {
-      Value numberName;
-      if (!decodeNumber(tokenName, numberName))
-        return recoverFromError(tokenObjectEnd);
-      name = String(numberName.asCString());
-    } else {
-      break;
-    }
-
-    Token colon;
-    if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
-      return addErrorAndRecover("Missing ':' after object member name", colon,
-                                tokenObjectEnd);
-    }
-    Value& value = currentValue()[name];
-    nodes_.push(&value);
-    bool ok = readValue();
-    nodes_.pop();
-    if (!ok) // error already set
-      return recoverFromError(tokenObjectEnd);
-
-    Token comma;
-    if (!readToken(comma) ||
-        (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
-         comma.type_ != tokenComment)) {
-      return addErrorAndRecover("Missing ',' or '}' in object declaration",
-                                comma, tokenObjectEnd);
-    }
-    bool finalizeTokenOk = true;
-    while (comma.type_ == tokenComment && finalizeTokenOk)
-      finalizeTokenOk = readToken(comma);
-    if (comma.type_ == tokenObjectEnd)
-      return true;
-  }
-  return addErrorAndRecover("Missing '}' or object member name", tokenName,
-                            tokenObjectEnd);
-}
-
-bool Reader::readArray(Token& token) {
-  Value init(arrayValue);
-  currentValue().swapPayload(init);
-  currentValue().setOffsetStart(token.start_ - begin_);
-  skipSpaces();
-  if (current_ != end_ && *current_ == ']') // empty array
-  {
-    Token endArray;
-    readToken(endArray);
-    return true;
-  }
-  int index = 0;
-  for (;;) {
-    Value& value = currentValue()[index++];
-    nodes_.push(&value);
-    bool ok = readValue();
-    nodes_.pop();
-    if (!ok) // error already set
-      return recoverFromError(tokenArrayEnd);
-
-    Token currentToken;
-    // Accept Comment after last item in the array.
-    ok = readToken(currentToken);
-    while (currentToken.type_ == tokenComment && ok) {
-      ok = readToken(currentToken);
-    }
-    bool badTokenType = (currentToken.type_ != tokenArraySeparator &&
-                         currentToken.type_ != tokenArrayEnd);
-    if (!ok || badTokenType) {
-      return addErrorAndRecover("Missing ',' or ']' in array declaration",
-                                currentToken, tokenArrayEnd);
-    }
-    if (currentToken.type_ == tokenArrayEnd)
-      break;
-  }
-  return true;
-}
-
-bool Reader::decodeNumber(Token& token) {
-  Value decoded;
-  if (!decodeNumber(token, decoded))
-    return false;
-  currentValue().swapPayload(decoded);
-  currentValue().setOffsetStart(token.start_ - begin_);
-  currentValue().setOffsetLimit(token.end_ - begin_);
-  return true;
-}
-
-bool Reader::decodeNumber(Token& token, Value& decoded) {
-  // Attempts to parse the number as an integer. If the number is
-  // larger than the maximum supported value of an integer then
-  // we decode the number as a double.
-  Location current = token.start_;
-  bool isNegative = *current == '-';
-  if (isNegative)
-    ++current;
-  // TODO: Help the compiler do the div and mod at compile time or get rid of
-  // them.
-  Value::LargestUInt maxIntegerValue =
-      isNegative ? Value::LargestUInt(Value::maxLargestInt) + 1
-                 : Value::maxLargestUInt;
-  Value::LargestUInt threshold = maxIntegerValue / 10;
-  Value::LargestUInt value = 0;
-  while (current < token.end_) {
-    Char c = *current++;
-    if (c < '0' || c > '9')
-      return decodeDouble(token, decoded);
-    auto digit(static_cast<Value::UInt>(c - '0'));
-    if (value >= threshold) {
-      // We've hit or exceeded the max value divided by 10 (rounded down). If
-      // a) we've only just touched the limit, b) this is the last digit, and
-      // c) it's small enough to fit in that rounding delta, we're okay.
-      // Otherwise treat this number as a double to avoid overflow.
-      if (value > threshold || current != token.end_ ||
-          digit > maxIntegerValue % 10) {
-        return decodeDouble(token, decoded);
-      }
-    }
-    value = value * 10 + digit;
-  }
-  if (isNegative && value == maxIntegerValue)
-    decoded = Value::minLargestInt;
-  else if (isNegative)
-    decoded = -Value::LargestInt(value);
-  else if (value <= Value::LargestUInt(Value::maxInt))
-    decoded = Value::LargestInt(value);
-  else
-    decoded = value;
-  return true;
-}
-
-bool Reader::decodeDouble(Token& token) {
-  Value decoded;
-  if (!decodeDouble(token, decoded))
-    return false;
-  currentValue().swapPayload(decoded);
-  currentValue().setOffsetStart(token.start_ - begin_);
-  currentValue().setOffsetLimit(token.end_ - begin_);
-  return true;
-}
-
-bool Reader::decodeDouble(Token& token, Value& decoded) {
-  double value = 0;
-  String buffer(token.start_, token.end_);
-  IStringStream is(buffer);
-  if (!(is >> value))
-    return addError(
-        "'" + String(token.start_, token.end_) + "' is not a number.", token);
-  decoded = value;
-  return true;
-}
-
-bool Reader::decodeString(Token& token) {
-  String decoded_string;
-  if (!decodeString(token, decoded_string))
-    return false;
-  Value decoded(decoded_string);
-  currentValue().swapPayload(decoded);
-  currentValue().setOffsetStart(token.start_ - begin_);
-  currentValue().setOffsetLimit(token.end_ - begin_);
-  return true;
-}
-
-bool Reader::decodeString(Token& token, String& decoded) {
-  decoded.reserve(static_cast<size_t>(token.end_ - token.start_ - 2));
-  Location current = token.start_ + 1; // skip '"'
-  Location end = token.end_ - 1;       // do not include '"'
-  while (current != end) {
-    Char c = *current++;
-    if (c == '"')
-      break;
-    else if (c == '\\') {
-      if (current == end)
-        return addError("Empty escape sequence in string", token, current);
-      Char escape = *current++;
-      switch (escape) {
-      case '"':
-        decoded += '"';
-        break;
-      case '/':
-        decoded += '/';
-        break;
-      case '\\':
-        decoded += '\\';
-        break;
-      case 'b':
-        decoded += '\b';
-        break;
-      case 'f':
-        decoded += '\f';
-        break;
-      case 'n':
-        decoded += '\n';
-        break;
-      case 'r':
-        decoded += '\r';
-        break;
-      case 't':
-        decoded += '\t';
-        break;
-      case 'u': {
-        unsigned int unicode;
-        if (!decodeUnicodeCodePoint(token, current, end, unicode))
-          return false;
-        decoded += codePointToUTF8(unicode);
-      } break;
-      default:
-        return addError("Bad escape sequence in string", token, current);
-      }
-    } else {
-      decoded += c;
-    }
-  }
-  return true;
-}
-
-bool Reader::decodeUnicodeCodePoint(Token& token,
-                                    Location& current,
-                                    Location end,
-                                    unsigned int& unicode) {
-
-  if (!decodeUnicodeEscapeSequence(token, current, end, unicode))
-    return false;
-  if (unicode >= 0xD800 && unicode <= 0xDBFF) {
-    // surrogate pairs
-    if (end - current < 6)
-      return addError(
-          "additional six characters expected to parse unicode surrogate pair.",
-          token, current);
-    if (*(current++) == '\\' && *(current++) == 'u') {
-      unsigned int surrogatePair;
-      if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
-        unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
-      } else
-        return false;
-    } else
-      return addError("expecting another \\u token to begin the second half of "
-                      "a unicode surrogate pair",
-                      token, current);
-  }
-  return true;
-}
-
-bool Reader::decodeUnicodeEscapeSequence(Token& token,
-                                         Location& current,
-                                         Location end,
-                                         unsigned int& ret_unicode) {
-  if (end - current < 4)
-    return addError(
-        "Bad unicode escape sequence in string: four digits expected.", token,
-        current);
-  int unicode = 0;
-  for (int index = 0; index < 4; ++index) {
-    Char c = *current++;
-    unicode *= 16;
-    if (c >= '0' && c <= '9')
-      unicode += c - '0';
-    else if (c >= 'a' && c <= 'f')
-      unicode += c - 'a' + 10;
-    else if (c >= 'A' && c <= 'F')
-      unicode += c - 'A' + 10;
-    else
-      return addError(
-          "Bad unicode escape sequence in string: hexadecimal digit expected.",
-          token, current);
-  }
-  ret_unicode = static_cast<unsigned int>(unicode);
-  return true;
-}
-
-bool Reader::addError(const String& message, Token& token, Location extra) {
-  ErrorInfo info;
-  info.token_ = token;
-  info.message_ = message;
-  info.extra_ = extra;
-  errors_.push_back(info);
-  return false;
-}
-
-bool Reader::recoverFromError(TokenType skipUntilToken) {
-  size_t const errorCount = errors_.size();
-  Token skip;
-  for (;;) {
-    if (!readToken(skip))
-      errors_.resize(errorCount); // discard errors caused by recovery
-    if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
-      break;
-  }
-  errors_.resize(errorCount);
-  return false;
-}
-
-bool Reader::addErrorAndRecover(const String& message,
-                                Token& token,
-                                TokenType skipUntilToken) {
-  addError(message, token);
-  return recoverFromError(skipUntilToken);
-}
-
-Value& Reader::currentValue() { return *(nodes_.top()); }
-
-Reader::Char Reader::getNextChar() {
-  if (current_ == end_)
-    return 0;
-  return *current_++;
-}
-
-void Reader::getLocationLineAndColumn(Location location,
-                                      int& line,
-                                      int& column) const {
-  Location current = begin_;
-  Location lastLineStart = current;
-  line = 0;
-  while (current < location && current != end_) {
-    Char c = *current++;
-    if (c == '\r') {
-      if (*current == '\n')
-        ++current;
-      lastLineStart = current;
-      ++line;
-    } else if (c == '\n') {
-      lastLineStart = current;
-      ++line;
-    }
-  }
-  // column & line start at 1
-  column = int(location - lastLineStart) + 1;
-  ++line;
-}
-
-String Reader::getLocationLineAndColumn(Location location) const {
-  int line, column;
-  getLocationLineAndColumn(location, line, column);
-  char buffer[18 + 16 + 16 + 1];
-  jsoncpp_snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
-  return buffer;
-}
-
-// Deprecated. Preserved for backward compatibility
-String Reader::getFormatedErrorMessages() const {
-  return getFormattedErrorMessages();
-}
-
-String Reader::getFormattedErrorMessages() const {
-  String formattedMessage;
-  for (const auto& error : errors_) {
-    formattedMessage +=
-        "* " + getLocationLineAndColumn(error.token_.start_) + "\n";
-    formattedMessage += "  " + error.message_ + "\n";
-    if (error.extra_)
-      formattedMessage +=
-          "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n";
-  }
-  return formattedMessage;
-}
-
-std::vector<Reader::StructuredError> Reader::getStructuredErrors() const {
-  std::vector<Reader::StructuredError> allErrors;
-  for (const auto& error : errors_) {
-    Reader::StructuredError structured;
-    structured.offset_start = error.token_.start_ - begin_;
-    structured.offset_limit = error.token_.end_ - begin_;
-    structured.message = error.message_;
-    allErrors.push_back(structured);
-  }
-  return allErrors;
-}
-
-bool Reader::pushError(const Value& value, const String& message) {
-  ptrdiff_t const length = end_ - begin_;
-  if (value.getOffsetStart() > length || value.getOffsetLimit() > length)
-    return false;
-  Token token;
-  token.type_ = tokenError;
-  token.start_ = begin_ + value.getOffsetStart();
-  token.end_ = end_ + value.getOffsetLimit();
-  ErrorInfo info;
-  info.token_ = token;
-  info.message_ = message;
-  info.extra_ = nullptr;
-  errors_.push_back(info);
-  return true;
-}
-
-bool Reader::pushError(const Value& value,
-                       const String& message,
-                       const Value& extra) {
-  ptrdiff_t const length = end_ - begin_;
-  if (value.getOffsetStart() > length || value.getOffsetLimit() > length ||
-      extra.getOffsetLimit() > length)
-    return false;
-  Token token;
-  token.type_ = tokenError;
-  token.start_ = begin_ + value.getOffsetStart();
-  token.end_ = begin_ + value.getOffsetLimit();
-  ErrorInfo info;
-  info.token_ = token;
-  info.message_ = message;
-  info.extra_ = begin_ + extra.getOffsetStart();
-  errors_.push_back(info);
-  return true;
-}
-
-bool Reader::good() const { return errors_.empty(); }
-
-// exact copy of Features
-class OurFeatures {
-public:
-  static OurFeatures all();
-  bool allowComments_;
-  bool strictRoot_;
-  bool allowDroppedNullPlaceholders_;
-  bool allowNumericKeys_;
-  bool allowSingleQuotes_;
-  bool failIfExtra_;
-  bool rejectDupKeys_;
-  bool allowSpecialFloats_;
-  size_t stackLimit_;
-}; // OurFeatures
-
-// exact copy of Implementation of class Features
-// ////////////////////////////////
-
-OurFeatures OurFeatures::all() { return {}; }
-
-// Implementation of class Reader
-// ////////////////////////////////
-
-// exact copy of Reader, renamed to OurReader
-class OurReader {
-public:
-  typedef char Char;
-  typedef const Char* Location;
-  struct StructuredError {
-    ptrdiff_t offset_start;
-    ptrdiff_t offset_limit;
-    String message;
-  };
-
-  OurReader(OurFeatures const& features);
-  bool parse(const char* beginDoc,
-             const char* endDoc,
-             Value& root,
-             bool collectComments = true);
-  String getFormattedErrorMessages() const;
-  std::vector<StructuredError> getStructuredErrors() const;
-  bool pushError(const Value& value, const String& message);
-  bool pushError(const Value& value, const String& message, const Value& extra);
-  bool good() const;
-
-private:
-  OurReader(OurReader const&);      // no impl
-  void operator=(OurReader const&); // no impl
-
-  enum TokenType {
-    tokenEndOfStream = 0,
-    tokenObjectBegin,
-    tokenObjectEnd,
-    tokenArrayBegin,
-    tokenArrayEnd,
-    tokenString,
-    tokenNumber,
-    tokenTrue,
-    tokenFalse,
-    tokenNull,
-    tokenNaN,
-    tokenPosInf,
-    tokenNegInf,
-    tokenArraySeparator,
-    tokenMemberSeparator,
-    tokenComment,
-    tokenError
-  };
-
-  class Token {
-  public:
-    TokenType type_;
-    Location start_;
-    Location end_;
-  };
-
-  class ErrorInfo {
-  public:
-    Token token_;
-    String message_;
-    Location extra_;
-  };
-
-  typedef std::deque<ErrorInfo> Errors;
-
-  bool readToken(Token& token);
-  void skipSpaces();
-  bool match(Location pattern, int patternLength);
-  bool readComment();
-  bool readCStyleComment();
-  bool readCppStyleComment();
-  bool readString();
-  bool readStringSingleQuote();
-  bool readNumber(bool checkInf);
-  bool readValue();
-  bool readObject(Token& token);
-  bool readArray(Token& token);
-  bool decodeNumber(Token& token);
-  bool decodeNumber(Token& token, Value& decoded);
-  bool decodeString(Token& token);
-  bool decodeString(Token& token, String& decoded);
-  bool decodeDouble(Token& token);
-  bool decodeDouble(Token& token, Value& decoded);
-  bool decodeUnicodeCodePoint(Token& token,
-                              Location& current,
-                              Location end,
-                              unsigned int& unicode);
-  bool decodeUnicodeEscapeSequence(Token& token,
-                                   Location& current,
-                                   Location end,
-                                   unsigned int& unicode);
-  bool addError(const String& message, Token& token, Location extra = nullptr);
-  bool recoverFromError(TokenType skipUntilToken);
-  bool addErrorAndRecover(const String& message,
-                          Token& token,
-                          TokenType skipUntilToken);
-  void skipUntilSpace();
-  Value& currentValue();
-  Char getNextChar();
-  void
-  getLocationLineAndColumn(Location location, int& line, int& column) const;
-  String getLocationLineAndColumn(Location location) const;
-  void addComment(Location begin, Location end, CommentPlacement placement);
-  void skipCommentTokens(Token& token);
-
-  static String normalizeEOL(Location begin, Location end);
-  static bool containsNewLine(Location begin, Location end);
-
-  typedef std::stack<Value*> Nodes;
-  Nodes nodes_;
-  Errors errors_;
-  String document_;
-  Location begin_;
-  Location end_;
-  Location current_;
-  Location lastValueEnd_;
-  Value* lastValue_;
-  String commentsBefore_;
-
-  OurFeatures const features_;
-  bool collectComments_;
-}; // OurReader
-
-// complete copy of Read impl, for OurReader
-
-bool OurReader::containsNewLine(OurReader::Location begin,
-                                OurReader::Location end) {
-  for (; begin < end; ++begin)
-    if (*begin == '\n' || *begin == '\r')
-      return true;
-  return false;
-}
-
-OurReader::OurReader(OurFeatures const& features)
-    : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
-      lastValue_(), commentsBefore_(), features_(features), collectComments_() {
-}
-
-bool OurReader::parse(const char* beginDoc,
-                      const char* endDoc,
-                      Value& root,
-                      bool collectComments) {
-  if (!features_.allowComments_) {
-    collectComments = false;
-  }
-
-  begin_ = beginDoc;
-  end_ = endDoc;
-  collectComments_ = collectComments;
-  current_ = begin_;
-  lastValueEnd_ = nullptr;
-  lastValue_ = nullptr;
-  commentsBefore_.clear();
-  errors_.clear();
-  while (!nodes_.empty())
-    nodes_.pop();
-  nodes_.push(&root);
-
-  bool successful = readValue();
-  Token token;
-  skipCommentTokens(token);
-  if (features_.failIfExtra_) {
-    if ((features_.strictRoot_ || token.type_ != tokenError) &&
-        token.type_ != tokenEndOfStream) {
-      addError("Extra non-whitespace after JSON value.", token);
-      return false;
-    }
-  }
-  if (collectComments_ && !commentsBefore_.empty())
-    root.setComment(commentsBefore_, commentAfter);
-  if (features_.strictRoot_) {
-    if (!root.isArray() && !root.isObject()) {
-      // Set error location to start of doc, ideally should be first token found
-      // in doc
-      token.type_ = tokenError;
-      token.start_ = beginDoc;
-      token.end_ = endDoc;
-      addError(
-          "A valid JSON document must be either an array or an object value.",
-          token);
-      return false;
-    }
-  }
-  return successful;
-}
-
-bool OurReader::readValue() {
-  //  To preserve the old behaviour we cast size_t to int.
-  if (nodes_.size() > features_.stackLimit_)
-    throwRuntimeError("Exceeded stackLimit in readValue().");
-  Token token;
-  skipCommentTokens(token);
-  bool successful = true;
-
-  if (collectComments_ && !commentsBefore_.empty()) {
-    currentValue().setComment(commentsBefore_, commentBefore);
-    commentsBefore_.clear();
-  }
-
-  switch (token.type_) {
-  case tokenObjectBegin:
-    successful = readObject(token);
-    currentValue().setOffsetLimit(current_ - begin_);
-    break;
-  case tokenArrayBegin:
-    successful = readArray(token);
-    currentValue().setOffsetLimit(current_ - begin_);
-    break;
-  case tokenNumber:
-    successful = decodeNumber(token);
-    break;
-  case tokenString:
-    successful = decodeString(token);
-    break;
-  case tokenTrue: {
-    Value v(true);
-    currentValue().swapPayload(v);
-    currentValue().setOffsetStart(token.start_ - begin_);
-    currentValue().setOffsetLimit(token.end_ - begin_);
-  } break;
-  case tokenFalse: {
-    Value v(false);
-    currentValue().swapPayload(v);
-    currentValue().setOffsetStart(token.start_ - begin_);
-    currentValue().setOffsetLimit(token.end_ - begin_);
-  } break;
-  case tokenNull: {
-    Value v;
-    currentValue().swapPayload(v);
-    currentValue().setOffsetStart(token.start_ - begin_);
-    currentValue().setOffsetLimit(token.end_ - begin_);
-  } break;
-  case tokenNaN: {
-    Value v(std::numeric_limits<double>::quiet_NaN());
-    currentValue().swapPayload(v);
-    currentValue().setOffsetStart(token.start_ - begin_);
-    currentValue().setOffsetLimit(token.end_ - begin_);
-  } break;
-  case tokenPosInf: {
-    Value v(std::numeric_limits<double>::infinity());
-    currentValue().swapPayload(v);
-    currentValue().setOffsetStart(token.start_ - begin_);
-    currentValue().setOffsetLimit(token.end_ - begin_);
-  } break;
-  case tokenNegInf: {
-    Value v(-std::numeric_limits<double>::infinity());
-    currentValue().swapPayload(v);
-    currentValue().setOffsetStart(token.start_ - begin_);
-    currentValue().setOffsetLimit(token.end_ - begin_);
-  } break;
-  case tokenArraySeparator:
-  case tokenObjectEnd:
-  case tokenArrayEnd:
-    if (features_.allowDroppedNullPlaceholders_) {
-      // "Un-read" the current token and mark the current value as a null
-      // token.
-      current_--;
-      Value v;
-      currentValue().swapPayload(v);
-      currentValue().setOffsetStart(current_ - begin_ - 1);
-      currentValue().setOffsetLimit(current_ - begin_);
-      break;
-    } // else, fall through ...
-  default:
-    currentValue().setOffsetStart(token.start_ - begin_);
-    currentValue().setOffsetLimit(token.end_ - begin_);
-    return addError("Syntax error: value, object or array expected.", token);
-  }
-
-  if (collectComments_) {
-    lastValueEnd_ = current_;
-    lastValue_ = &currentValue();
-  }
-
-  return successful;
-}
-
-void OurReader::skipCommentTokens(Token& token) {
-  if (features_.allowComments_) {
-    do {
-      readToken(token);
-    } while (token.type_ == tokenComment);
-  } else {
-    readToken(token);
-  }
-}
-
-bool OurReader::readToken(Token& token) {
-  skipSpaces();
-  token.start_ = current_;
-  Char c = getNextChar();
-  bool ok = true;
-  switch (c) {
-  case '{':
-    token.type_ = tokenObjectBegin;
-    break;
-  case '}':
-    token.type_ = tokenObjectEnd;
-    break;
-  case '[':
-    token.type_ = tokenArrayBegin;
-    break;
-  case ']':
-    token.type_ = tokenArrayEnd;
-    break;
-  case '"':
-    token.type_ = tokenString;
-    ok = readString();
-    break;
-  case '\'':
-    if (features_.allowSingleQuotes_) {
-      token.type_ = tokenString;
-      ok = readStringSingleQuote();
-      break;
-    } // else fall through
-  case '/':
-    token.type_ = tokenComment;
-    ok = readComment();
-    break;
-  case '0':
-  case '1':
-  case '2':
-  case '3':
-  case '4':
-  case '5':
-  case '6':
-  case '7':
-  case '8':
-  case '9':
-    token.type_ = tokenNumber;
-    readNumber(false);
-    break;
-  case '-':
-    if (readNumber(true)) {
-      token.type_ = tokenNumber;
-    } else {
-      token.type_ = tokenNegInf;
-      ok = features_.allowSpecialFloats_ && match("nfinity", 7);
-    }
-    break;
-  case 't':
-    token.type_ = tokenTrue;
-    ok = match("rue", 3);
-    break;
-  case 'f':
-    token.type_ = tokenFalse;
-    ok = match("alse", 4);
-    break;
-  case 'n':
-    token.type_ = tokenNull;
-    ok = match("ull", 3);
-    break;
-  case 'N':
-    if (features_.allowSpecialFloats_) {
-      token.type_ = tokenNaN;
-      ok = match("aN", 2);
-    } else {
-      ok = false;
-    }
-    break;
-  case 'I':
-    if (features_.allowSpecialFloats_) {
-      token.type_ = tokenPosInf;
-      ok = match("nfinity", 7);
-    } else {
-      ok = false;
-    }
-    break;
-  case ',':
-    token.type_ = tokenArraySeparator;
-    break;
-  case ':':
-    token.type_ = tokenMemberSeparator;
-    break;
-  case 0:
-    token.type_ = tokenEndOfStream;
-    break;
-  default:
-    ok = false;
-    break;
-  }
-  if (!ok)
-    token.type_ = tokenError;
-  token.end_ = current_;
-  return true;
-}
-
-void OurReader::skipSpaces() {
-  while (current_ != end_) {
-    Char c = *current_;
-    if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
-      ++current_;
-    else
-      break;
-  }
-}
-
-bool OurReader::match(Location pattern, int patternLength) {
-  if (end_ - current_ < patternLength)
-    return false;
-  int index = patternLength;
-  while (index--)
-    if (current_[index] != pattern[index])
-      return false;
-  current_ += patternLength;
-  return true;
-}
-
-bool OurReader::readComment() {
-  Location commentBegin = current_ - 1;
-  Char c = getNextChar();
-  bool successful = false;
-  if (c == '*')
-    successful = readCStyleComment();
-  else if (c == '/')
-    successful = readCppStyleComment();
-  if (!successful)
-    return false;
-
-  if (collectComments_) {
-    CommentPlacement placement = commentBefore;
-    if (lastValueEnd_ && !containsNewLine(lastValueEnd_, commentBegin)) {
-      if (c != '*' || !containsNewLine(commentBegin, current_))
-        placement = commentAfterOnSameLine;
-    }
-
-    addComment(commentBegin, current_, placement);
-  }
-  return true;
-}
-
-String OurReader::normalizeEOL(OurReader::Location begin,
-                               OurReader::Location end) {
-  String normalized;
-  normalized.reserve(static_cast<size_t>(end - begin));
-  OurReader::Location current = begin;
-  while (current != end) {
-    char c = *current++;
-    if (c == '\r') {
-      if (current != end && *current == '\n')
-        // convert dos EOL
-        ++current;
-      // convert Mac EOL
-      normalized += '\n';
-    } else {
-      normalized += c;
-    }
-  }
-  return normalized;
-}
-
-void OurReader::addComment(Location begin,
-                           Location end,
-                           CommentPlacement placement) {
-  assert(collectComments_);
-  const String& normalized = normalizeEOL(begin, end);
-  if (placement == commentAfterOnSameLine) {
-    assert(lastValue_ != nullptr);
-    lastValue_->setComment(normalized, placement);
-  } else {
-    commentsBefore_ += normalized;
-  }
-}
-
-bool OurReader::readCStyleComment() {
-  while ((current_ + 1) < end_) {
-    Char c = getNextChar();
-    if (c == '*' && *current_ == '/')
-      break;
-  }
-  return getNextChar() == '/';
-}
-
-bool OurReader::readCppStyleComment() {
-  while (current_ != end_) {
-    Char c = getNextChar();
-    if (c == '\n')
-      break;
-    if (c == '\r') {
-      // Consume DOS EOL. It will be normalized in addComment.
-      if (current_ != end_ && *current_ == '\n')
-        getNextChar();
-      // Break on Moc OS 9 EOL.
-      break;
-    }
-  }
-  return true;
-}
-
-bool OurReader::readNumber(bool checkInf) {
-  const char* p = current_;
-  if (checkInf && p != end_ && *p == 'I') {
-    current_ = ++p;
-    return false;
-  }
-  char c = '0'; // stopgap for already consumed character
-  // integral part
-  while (c >= '0' && c <= '9')
-    c = (current_ = p) < end_ ? *p++ : '\0';
-  // fractional part
-  if (c == '.') {
-    c = (current_ = p) < end_ ? *p++ : '\0';
-    while (c >= '0' && c <= '9')
-      c = (current_ = p) < end_ ? *p++ : '\0';
-  }
-  // exponential part
-  if (c == 'e' || c == 'E') {
-    c = (current_ = p) < end_ ? *p++ : '\0';
-    if (c == '+' || c == '-')
-      c = (current_ = p) < end_ ? *p++ : '\0';
-    while (c >= '0' && c <= '9')
-      c = (current_ = p) < end_ ? *p++ : '\0';
-  }
-  return true;
-}
-bool OurReader::readString() {
-  Char c = 0;
-  while (current_ != end_) {
-    c = getNextChar();
-    if (c == '\\')
-      getNextChar();
-    else if (c == '"')
-      break;
-  }
-  return c == '"';
-}
-
-bool OurReader::readStringSingleQuote() {
-  Char c = 0;
-  while (current_ != end_) {
-    c = getNextChar();
-    if (c == '\\')
-      getNextChar();
-    else if (c == '\'')
-      break;
-  }
-  return c == '\'';
-}
-
-bool OurReader::readObject(Token& token) {
-  Token tokenName;
-  String name;
-  Value init(objectValue);
-  currentValue().swapPayload(init);
-  currentValue().setOffsetStart(token.start_ - begin_);
-  while (readToken(tokenName)) {
-    bool initialTokenOk = true;
-    while (tokenName.type_ == tokenComment && initialTokenOk)
-      initialTokenOk = readToken(tokenName);
-    if (!initialTokenOk)
-      break;
-    if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object
-      return true;
-    name.clear();
-    if (tokenName.type_ == tokenString) {
-      if (!decodeString(tokenName, name))
-        return recoverFromError(tokenObjectEnd);
-    } else if (tokenName.type_ == tokenNumber && features_.allowNumericKeys_) {
-      Value numberName;
-      if (!decodeNumber(tokenName, numberName))
-        return recoverFromError(tokenObjectEnd);
-      name = numberName.asString();
-    } else {
-      break;
-    }
-
-    Token colon;
-    if (!readToken(colon) || colon.type_ != tokenMemberSeparator) {
-      return addErrorAndRecover("Missing ':' after object member name", colon,
-                                tokenObjectEnd);
-    }
-    if (name.length() >= (1U << 30))
-      throwRuntimeError("keylength >= 2^30");
-    if (features_.rejectDupKeys_ && currentValue().isMember(name)) {
-      String msg = "Duplicate key: '" + name + "'";
-      return addErrorAndRecover(msg, tokenName, tokenObjectEnd);
-    }
-    Value& value = currentValue()[name];
-    nodes_.push(&value);
-    bool ok = readValue();
-    nodes_.pop();
-    if (!ok) // error already set
-      return recoverFromError(tokenObjectEnd);
-
-    Token comma;
-    if (!readToken(comma) ||
-        (comma.type_ != tokenObjectEnd && comma.type_ != tokenArraySeparator &&
-         comma.type_ != tokenComment)) {
-      return addErrorAndRecover("Missing ',' or '}' in object declaration",
-                                comma, tokenObjectEnd);
-    }
-    bool finalizeTokenOk = true;
-    while (comma.type_ == tokenComment && finalizeTokenOk)
-      finalizeTokenOk = readToken(comma);
-    if (comma.type_ == tokenObjectEnd)
-      return true;
-  }
-  return addErrorAndRecover("Missing '}' or object member name", tokenName,
-                            tokenObjectEnd);
-}
-
-bool OurReader::readArray(Token& token) {
-  Value init(arrayValue);
-  currentValue().swapPayload(init);
-  currentValue().setOffsetStart(token.start_ - begin_);
-  skipSpaces();
-  if (current_ != end_ && *current_ == ']') // empty array
-  {
-    Token endArray;
-    readToken(endArray);
-    return true;
-  }
-  int index = 0;
-  for (;;) {
-    Value& value = currentValue()[index++];
-    nodes_.push(&value);
-    bool ok = readValue();
-    nodes_.pop();
-    if (!ok) // error already set
-      return recoverFromError(tokenArrayEnd);
-
-    Token currentToken;
-    // Accept Comment after last item in the array.
-    ok = readToken(currentToken);
-    while (currentToken.type_ == tokenComment && ok) {
-      ok = readToken(currentToken);
-    }
-    bool badTokenType = (currentToken.type_ != tokenArraySeparator &&
-                         currentToken.type_ != tokenArrayEnd);
-    if (!ok || badTokenType) {
-      return addErrorAndRecover("Missing ',' or ']' in array declaration",
-                                currentToken, tokenArrayEnd);
-    }
-    if (currentToken.type_ == tokenArrayEnd)
-      break;
-  }
-  return true;
-}
-
-bool OurReader::decodeNumber(Token& token) {
-  Value decoded;
-  if (!decodeNumber(token, decoded))
-    return false;
-  currentValue().swapPayload(decoded);
-  currentValue().setOffsetStart(token.start_ - begin_);
-  currentValue().setOffsetLimit(token.end_ - begin_);
-  return true;
-}
-
-bool OurReader::decodeNumber(Token& token, Value& decoded) {
-  // Attempts to parse the number as an integer. If the number is
-  // larger than the maximum supported value of an integer then
-  // we decode the number as a double.
-  Location current = token.start_;
-  bool isNegative = *current == '-';
-  if (isNegative)
-    ++current;
-  // TODO: Help the compiler do the div and mod at compile time or get rid of
-  // them.
-  Value::LargestUInt maxIntegerValue =
-      isNegative ? Value::LargestUInt(Value::minLargestInt)
-                 : Value::maxLargestUInt;
-  Value::LargestUInt threshold = maxIntegerValue / 10;
-  Value::LargestUInt value = 0;
-  while (current < token.end_) {
-    Char c = *current++;
-    if (c < '0' || c > '9')
-      return decodeDouble(token, decoded);
-    auto digit(static_cast<Value::UInt>(c - '0'));
-    if (value >= threshold) {
-      // We've hit or exceeded the max value divided by 10 (rounded down). If
-      // a) we've only just touched the limit, b) this is the last digit, and
-      // c) it's small enough to fit in that rounding delta, we're okay.
-      // Otherwise treat this number as a double to avoid overflow.
-      if (value > threshold || current != token.end_ ||
-          digit > maxIntegerValue % 10) {
-        return decodeDouble(token, decoded);
-      }
-    }
-    value = value * 10 + digit;
-  }
-  if (isNegative)
-    decoded = -Value::LargestInt(value);
-  else if (value <= Value::LargestUInt(Value::maxInt))
-    decoded = Value::LargestInt(value);
-  else
-    decoded = value;
-  return true;
-}
-
-bool OurReader::decodeDouble(Token& token) {
-  Value decoded;
-  if (!decodeDouble(token, decoded))
-    return false;
-  currentValue().swapPayload(decoded);
-  currentValue().setOffsetStart(token.start_ - begin_);
-  currentValue().setOffsetLimit(token.end_ - begin_);
-  return true;
-}
-
-bool OurReader::decodeDouble(Token& token, Value& decoded) {
-  double value = 0;
-  const int bufferSize = 32;
-  int count;
-  ptrdiff_t const length = token.end_ - token.start_;
-
-  // Sanity check to avoid buffer overflow exploits.
-  if (length < 0) {
-    return addError("Unable to parse token length", token);
-  }
-  auto const ulength = static_cast<size_t>(length);
-
-  // Avoid using a string constant for the format control string given to
-  // sscanf, as this can cause hard to debug crashes on OS X. See here for more
-  // info:
-  //
-  //     http://developer.apple.com/library/mac/#DOCUMENTATION/DeveloperTools/gcc-4.0.1/gcc/Incompatibilities.html
-  char format[] = "%lf";
-
-  if (length <= bufferSize) {
-    Char buffer[bufferSize + 1];
-    memcpy(buffer, token.start_, ulength);
-    buffer[length] = 0;
-    fixNumericLocaleInput(buffer, buffer + length);
-    count = sscanf(buffer, format, &value);
-  } else {
-    String buffer(token.start_, token.end_);
-    count = sscanf(buffer.c_str(), format, &value);
-  }
-
-  if (count != 1)
-    return addError(
-        "'" + String(token.start_, token.end_) + "' is not a number.", token);
-  decoded = value;
-  return true;
-}
-
-bool OurReader::decodeString(Token& token) {
-  String decoded_string;
-  if (!decodeString(token, decoded_string))
-    return false;
-  Value decoded(decoded_string);
-  currentValue().swapPayload(decoded);
-  currentValue().setOffsetStart(token.start_ - begin_);
-  currentValue().setOffsetLimit(token.end_ - begin_);
-  return true;
-}
-
-bool OurReader::decodeString(Token& token, String& decoded) {
-  decoded.reserve(static_cast<size_t>(token.end_ - token.start_ - 2));
-  Location current = token.start_ + 1; // skip '"'
-  Location end = token.end_ - 1;       // do not include '"'
-  while (current != end) {
-    Char c = *current++;
-    if (c == '"')
-      break;
-    else if (c == '\\') {
-      if (current == end)
-        return addError("Empty escape sequence in string", token, current);
-      Char escape = *current++;
-      switch (escape) {
-      case '"':
-        decoded += '"';
-        break;
-      case '/':
-        decoded += '/';
-        break;
-      case '\\':
-        decoded += '\\';
-        break;
-      case 'b':
-        decoded += '\b';
-        break;
-      case 'f':
-        decoded += '\f';
-        break;
-      case 'n':
-        decoded += '\n';
-        break;
-      case 'r':
-        decoded += '\r';
-        break;
-      case 't':
-        decoded += '\t';
-        break;
-      case 'u': {
-        unsigned int unicode;
-        if (!decodeUnicodeCodePoint(token, current, end, unicode))
-          return false;
-        decoded += codePointToUTF8(unicode);
-      } break;
-      default:
-        return addError("Bad escape sequence in string", token, current);
-      }
-    } else {
-      decoded += c;
-    }
-  }
-  return true;
-}
-
-bool OurReader::decodeUnicodeCodePoint(Token& token,
-                                       Location& current,
-                                       Location end,
-                                       unsigned int& unicode) {
-
-  if (!decodeUnicodeEscapeSequence(token, current, end, unicode))
-    return false;
-  if (unicode >= 0xD800 && unicode <= 0xDBFF) {
-    // surrogate pairs
-    if (end - current < 6)
-      return addError(
-          "additional six characters expected to parse unicode surrogate pair.",
-          token, current);
-    if (*(current++) == '\\' && *(current++) == 'u') {
-      unsigned int surrogatePair;
-      if (decodeUnicodeEscapeSequence(token, current, end, surrogatePair)) {
-        unicode = 0x10000 + ((unicode & 0x3FF) << 10) + (surrogatePair & 0x3FF);
-      } else
-        return false;
-    } else
-      return addError("expecting another \\u token to begin the second half of "
-                      "a unicode surrogate pair",
-                      token, current);
-  }
-  return true;
-}
-
-bool OurReader::decodeUnicodeEscapeSequence(Token& token,
-                                            Location& current,
-                                            Location end,
-                                            unsigned int& ret_unicode) {
-  if (end - current < 4)
-    return addError(
-        "Bad unicode escape sequence in string: four digits expected.", token,
-        current);
-  int unicode = 0;
-  for (int index = 0; index < 4; ++index) {
-    Char c = *current++;
-    unicode *= 16;
-    if (c >= '0' && c <= '9')
-      unicode += c - '0';
-    else if (c >= 'a' && c <= 'f')
-      unicode += c - 'a' + 10;
-    else if (c >= 'A' && c <= 'F')
-      unicode += c - 'A' + 10;
-    else
-      return addError(
-          "Bad unicode escape sequence in string: hexadecimal digit expected.",
-          token, current);
-  }
-  ret_unicode = static_cast<unsigned int>(unicode);
-  return true;
-}
-
-bool OurReader::addError(const String& message, Token& token, Location extra) {
-  ErrorInfo info;
-  info.token_ = token;
-  info.message_ = message;
-  info.extra_ = extra;
-  errors_.push_back(info);
-  return false;
-}
-
-bool OurReader::recoverFromError(TokenType skipUntilToken) {
-  size_t errorCount = errors_.size();
-  Token skip;
-  for (;;) {
-    if (!readToken(skip))
-      errors_.resize(errorCount); // discard errors caused by recovery
-    if (skip.type_ == skipUntilToken || skip.type_ == tokenEndOfStream)
-      break;
-  }
-  errors_.resize(errorCount);
-  return false;
-}
-
-bool OurReader::addErrorAndRecover(const String& message,
-                                   Token& token,
-                                   TokenType skipUntilToken) {
-  addError(message, token);
-  return recoverFromError(skipUntilToken);
-}
-
-Value& OurReader::currentValue() { return *(nodes_.top()); }
-
-OurReader::Char OurReader::getNextChar() {
-  if (current_ == end_)
-    return 0;
-  return *current_++;
-}
-
-void OurReader::getLocationLineAndColumn(Location location,
-                                         int& line,
-                                         int& column) const {
-  Location current = begin_;
-  Location lastLineStart = current;
-  line = 0;
-  while (current < location && current != end_) {
-    Char c = *current++;
-    if (c == '\r') {
-      if (*current == '\n')
-        ++current;
-      lastLineStart = current;
-      ++line;
-    } else if (c == '\n') {
-      lastLineStart = current;
-      ++line;
-    }
-  }
-  // column & line start at 1
-  column = int(location - lastLineStart) + 1;
-  ++line;
-}
-
-String OurReader::getLocationLineAndColumn(Location location) const {
-  int line, column;
-  getLocationLineAndColumn(location, line, column);
-  char buffer[18 + 16 + 16 + 1];
-  jsoncpp_snprintf(buffer, sizeof(buffer), "Line %d, Column %d", line, column);
-  return buffer;
-}
-
-String OurReader::getFormattedErrorMessages() const {
-  String formattedMessage;
-  for (const auto& error : errors_) {
-    formattedMessage +=
-        "* " + getLocationLineAndColumn(error.token_.start_) + "\n";
-    formattedMessage += "  " + error.message_ + "\n";
-    if (error.extra_)
-      formattedMessage +=
-          "See " + getLocationLineAndColumn(error.extra_) + " for detail.\n";
-  }
-  return formattedMessage;
-}
-
-std::vector<OurReader::StructuredError> OurReader::getStructuredErrors() const {
-  std::vector<OurReader::StructuredError> allErrors;
-  for (const auto& error : errors_) {
-    OurReader::StructuredError structured;
-    structured.offset_start = error.token_.start_ - begin_;
-    structured.offset_limit = error.token_.end_ - begin_;
-    structured.message = error.message_;
-    allErrors.push_back(structured);
-  }
-  return allErrors;
-}
-
-bool OurReader::pushError(const Value& value, const String& message) {
-  ptrdiff_t length = end_ - begin_;
-  if (value.getOffsetStart() > length || value.getOffsetLimit() > length)
-    return false;
-  Token token;
-  token.type_ = tokenError;
-  token.start_ = begin_ + value.getOffsetStart();
-  token.end_ = end_ + value.getOffsetLimit();
-  ErrorInfo info;
-  info.token_ = token;
-  info.message_ = message;
-  info.extra_ = nullptr;
-  errors_.push_back(info);
-  return true;
-}
-
-bool OurReader::pushError(const Value& value,
-                          const String& message,
-                          const Value& extra) {
-  ptrdiff_t length = end_ - begin_;
-  if (value.getOffsetStart() > length || value.getOffsetLimit() > length ||
-      extra.getOffsetLimit() > length)
-    return false;
-  Token token;
-  token.type_ = tokenError;
-  token.start_ = begin_ + value.getOffsetStart();
-  token.end_ = begin_ + value.getOffsetLimit();
-  ErrorInfo info;
-  info.token_ = token;
-  info.message_ = message;
-  info.extra_ = begin_ + extra.getOffsetStart();
-  errors_.push_back(info);
-  return true;
-}
-
-bool OurReader::good() const { return errors_.empty(); }
-
-class OurCharReader : public CharReader {
-  bool const collectComments_;
-  OurReader reader_;
-
-public:
-  OurCharReader(bool collectComments, OurFeatures const& features)
-      : collectComments_(collectComments), reader_(features) {}
-  bool parse(char const* beginDoc,
-             char const* endDoc,
-             Value* root,
-             String* errs) override {
-    bool ok = reader_.parse(beginDoc, endDoc, *root, collectComments_);
-    if (errs) {
-      *errs = reader_.getFormattedErrorMessages();
-    }
-    return ok;
-  }
-};
-
-CharReaderBuilder::CharReaderBuilder() { setDefaults(&settings_); }
-CharReaderBuilder::~CharReaderBuilder() = default;
-CharReader* CharReaderBuilder::newCharReader() const {
-  bool collectComments = settings_["collectComments"].asBool();
-  OurFeatures features = OurFeatures::all();
-  features.allowComments_ = settings_["allowComments"].asBool();
-  features.strictRoot_ = settings_["strictRoot"].asBool();
-  features.allowDroppedNullPlaceholders_ =
-      settings_["allowDroppedNullPlaceholders"].asBool();
-  features.allowNumericKeys_ = settings_["allowNumericKeys"].asBool();
-  features.allowSingleQuotes_ = settings_["allowSingleQuotes"].asBool();
-#if defined(JSON_HAS_INT64)
-  features.stackLimit_ = settings_["stackLimit"].asUInt64();
-#else
-  features.stackLimit_ = settings_["stackLimit"].asUInt();
-#endif
-  features.failIfExtra_ = settings_["failIfExtra"].asBool();
-  features.rejectDupKeys_ = settings_["rejectDupKeys"].asBool();
-  features.allowSpecialFloats_ = settings_["allowSpecialFloats"].asBool();
-  return new OurCharReader(collectComments, features);
-}
-static void getValidReaderKeys(std::set<String>* valid_keys) {
-  valid_keys->clear();
-  valid_keys->insert("collectComments");
-  valid_keys->insert("allowComments");
-  valid_keys->insert("strictRoot");
-  valid_keys->insert("allowDroppedNullPlaceholders");
-  valid_keys->insert("allowNumericKeys");
-  valid_keys->insert("allowSingleQuotes");
-  valid_keys->insert("stackLimit");
-  valid_keys->insert("failIfExtra");
-  valid_keys->insert("rejectDupKeys");
-  valid_keys->insert("allowSpecialFloats");
-}
-bool CharReaderBuilder::validate(Json::Value* invalid) const {
-  Json::Value my_invalid;
-  if (!invalid)
-    invalid = &my_invalid; // so we do not need to test for NULL
-  Json::Value& inv = *invalid;
-  std::set<String> valid_keys;
-  getValidReaderKeys(&valid_keys);
-  Value::Members keys = settings_.getMemberNames();
-  size_t n = keys.size();
-  for (size_t i = 0; i < n; ++i) {
-    String const& key = keys[i];
-    if (valid_keys.find(key) == valid_keys.end()) {
-      inv[key] = settings_[key];
-    }
-  }
-  return inv.empty();
-}
-Value& CharReaderBuilder::operator[](const String& key) {
-  return settings_[key];
-}
-// static
-void CharReaderBuilder::strictMode(Json::Value* settings) {
-  //! [CharReaderBuilderStrictMode]
-  (*settings)["allowComments"] = false;
-  (*settings)["strictRoot"] = true;
-  (*settings)["allowDroppedNullPlaceholders"] = false;
-  (*settings)["allowNumericKeys"] = false;
-  (*settings)["allowSingleQuotes"] = false;
-  (*settings)["stackLimit"] = 1000;
-  (*settings)["failIfExtra"] = true;
-  (*settings)["rejectDupKeys"] = true;
-  (*settings)["allowSpecialFloats"] = false;
-  //! [CharReaderBuilderStrictMode]
-}
-// static
-void CharReaderBuilder::setDefaults(Json::Value* settings) {
-  //! [CharReaderBuilderDefaults]
-  (*settings)["collectComments"] = true;
-  (*settings)["allowComments"] = true;
-  (*settings)["strictRoot"] = false;
-  (*settings)["allowDroppedNullPlaceholders"] = false;
-  (*settings)["allowNumericKeys"] = false;
-  (*settings)["allowSingleQuotes"] = false;
-  (*settings)["stackLimit"] = 1000;
-  (*settings)["failIfExtra"] = false;
-  (*settings)["rejectDupKeys"] = false;
-  (*settings)["allowSpecialFloats"] = false;
-  //! [CharReaderBuilderDefaults]
-}
-
-//////////////////////////////////
-// global functions
-
-bool parseFromStream(CharReader::Factory const& fact,
-                     IStream& sin,
-                     Value* root,
-                     String* errs) {
-  OStringStream ssin;
-  ssin << sin.rdbuf();
-  String doc = ssin.str();
-  char const* begin = doc.data();
-  char const* end = begin + doc.size();
-  // Note that we do not actually need a null-terminator.
-  CharReaderPtr const reader(fact.newCharReader());
-  return reader->parse(begin, end, root, errs);
-}
-
-IStream& operator>>(IStream& sin, Value& root) {
-  CharReaderBuilder b;
-  String errs;
-  bool ok = parseFromStream(b, sin, &root, &errs);
-  if (!ok) {
-    throwRuntimeError(errs);
-  }
-  return sin;
-}
-
-} // namespace Json
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: src/lib_json/json_reader.cpp
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: src/lib_json/json_valueiterator.inl
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-// included by json_value.cpp
-
-namespace Json {
-
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// class ValueIteratorBase
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-
-ValueIteratorBase::ValueIteratorBase() : current_() {}
-
-ValueIteratorBase::ValueIteratorBase(
-    const Value::ObjectValues::iterator& current)
-    : current_(current), isNull_(false) {}
-
-Value& ValueIteratorBase::deref() const { return current_->second; }
-
-void ValueIteratorBase::increment() { ++current_; }
-
-void ValueIteratorBase::decrement() { --current_; }
-
-ValueIteratorBase::difference_type
-ValueIteratorBase::computeDistance(const SelfType& other) const {
-#ifdef JSON_USE_CPPTL_SMALLMAP
-  return other.current_ - current_;
-#else
-  // Iterator for null value are initialized using the default
-  // constructor, which initialize current_ to the default
-  // std::map::iterator. As begin() and end() are two instance
-  // of the default std::map::iterator, they can not be compared.
-  // To allow this, we handle this comparison specifically.
-  if (isNull_ && other.isNull_) {
-    return 0;
-  }
-
-  // Usage of std::distance is not portable (does not compile with Sun Studio 12
-  // RogueWave STL,
-  // which is the one used by default).
-  // Using a portable hand-made version for non random iterator instead:
-  //   return difference_type( std::distance( current_, other.current_ ) );
-  difference_type myDistance = 0;
-  for (Value::ObjectValues::iterator it = current_; it != other.current_;
-       ++it) {
-    ++myDistance;
-  }
-  return myDistance;
-#endif
-}
-
-bool ValueIteratorBase::isEqual(const SelfType& other) const {
-  if (isNull_) {
-    return other.isNull_;
-  }
-  return current_ == other.current_;
-}
-
-void ValueIteratorBase::copy(const SelfType& other) {
-  current_ = other.current_;
-  isNull_ = other.isNull_;
-}
-
-Value ValueIteratorBase::key() const {
-  const Value::CZString czstring = (*current_).first;
-  if (czstring.data()) {
-    if (czstring.isStaticString())
-      return Value(StaticString(czstring.data()));
-    return Value(czstring.data(), czstring.data() + czstring.length());
-  }
-  return Value(czstring.index());
-}
-
-UInt ValueIteratorBase::index() const {
-  const Value::CZString czstring = (*current_).first;
-  if (!czstring.data())
-    return czstring.index();
-  return Value::UInt(-1);
-}
-
-String ValueIteratorBase::name() const {
-  char const* keey;
-  char const* end;
-  keey = memberName(&end);
-  if (!keey)
-    return String();
-  return String(keey, end);
-}
-
-char const* ValueIteratorBase::memberName() const {
-  const char* cname = (*current_).first.data();
-  return cname ? cname : "";
-}
-
-char const* ValueIteratorBase::memberName(char const** end) const {
-  const char* cname = (*current_).first.data();
-  if (!cname) {
-    *end = nullptr;
-    return nullptr;
-  }
-  *end = cname + (*current_).first.length();
-  return cname;
-}
-
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// class ValueConstIterator
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-
-ValueConstIterator::ValueConstIterator() = default;
-
-ValueConstIterator::ValueConstIterator(
-    const Value::ObjectValues::iterator& current)
-    : ValueIteratorBase(current) {}
-
-ValueConstIterator::ValueConstIterator(ValueIterator const& other)
-    : ValueIteratorBase(other) {}
-
-ValueConstIterator& ValueConstIterator::
-operator=(const ValueIteratorBase& other) {
-  copy(other);
-  return *this;
-}
-
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// class ValueIterator
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-
-ValueIterator::ValueIterator() = default;
-
-ValueIterator::ValueIterator(const Value::ObjectValues::iterator& current)
-    : ValueIteratorBase(current) {}
-
-ValueIterator::ValueIterator(const ValueConstIterator& other)
-    : ValueIteratorBase(other) {
-  throwRuntimeError("ConstIterator to Iterator should never be allowed.");
-}
-
-ValueIterator::ValueIterator(const ValueIterator& other) = default;
-
-ValueIterator& ValueIterator::operator=(const SelfType& other) {
-  copy(other);
-  return *this;
-}
-
-} // namespace Json
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: src/lib_json/json_valueiterator.inl
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: src/lib_json/json_value.cpp
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2011 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include <json/assertions.h>
-#include <json/value.h>
-#include <json/writer.h>
-#endif // if !defined(JSON_IS_AMALGAMATION)
-#include <cassert>
-#include <cmath>
-#include <cstring>
-#include <sstream>
-#include <utility>
-#ifdef JSON_USE_CPPTL
-#include <cpptl/conststring.h>
-#endif
-#include <algorithm> // min()
-#include <cstddef>   // size_t
-
-// Provide implementation equivalent of std::snprintf for older _MSC compilers
-#if defined(_MSC_VER) && _MSC_VER < 1900
-#include <stdarg.h>
-static int msvc_pre1900_c99_vsnprintf(char* outBuf,
-                                      size_t size,
-                                      const char* format,
-                                      va_list ap) {
-  int count = -1;
-  if (size != 0)
-    count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
-  if (count == -1)
-    count = _vscprintf(format, ap);
-  return count;
-}
-
-int JSON_API msvc_pre1900_c99_snprintf(char* outBuf,
-                                       size_t size,
-                                       const char* format,
-                                       ...) {
-  va_list ap;
-  va_start(ap, format);
-  const int count = msvc_pre1900_c99_vsnprintf(outBuf, size, format, ap);
-  va_end(ap);
-  return count;
-}
-#endif
-
-// Disable warning C4702 : unreachable code
-#if defined(_MSC_VER)
-#pragma warning(disable : 4702)
-#endif
-
-#define JSON_ASSERT_UNREACHABLE assert(false)
-
-namespace Json {
-
-// This is a walkaround to avoid the static initialization of Value::null.
-// kNull must be word-aligned to avoid crashing on ARM.  We use an alignment of
-// 8 (instead of 4) as a bit of future-proofing.
-#if defined(__ARMEL__)
-#define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
-#else
-#define ALIGNAS(byte_alignment)
-#endif
-// static const unsigned char ALIGNAS(8) kNull[sizeof(Value)] = { 0 };
-// const unsigned char& kNullRef = kNull[0];
-// const Value& Value::null = reinterpret_cast<const Value&>(kNullRef);
-// const Value& Value::nullRef = null;
-
-// static
-Value const& Value::nullSingleton() {
-  static Value const nullStatic;
-  return nullStatic;
-}
-
-// for backwards compatibility, we'll leave these global references around, but
-// DO NOT use them in JSONCPP library code any more!
-Value const& Value::null = Value::nullSingleton();
-Value const& Value::nullRef = Value::nullSingleton();
-
-const Int Value::minInt = Int(~(UInt(-1) / 2));
-const Int Value::maxInt = Int(UInt(-1) / 2);
-const UInt Value::maxUInt = UInt(-1);
-#if defined(JSON_HAS_INT64)
-const Int64 Value::minInt64 = Int64(~(UInt64(-1) / 2));
-const Int64 Value::maxInt64 = Int64(UInt64(-1) / 2);
-const UInt64 Value::maxUInt64 = UInt64(-1);
-// The constant is hard-coded because some compiler have trouble
-// converting Value::maxUInt64 to a double correctly (AIX/xlC).
-// Assumes that UInt64 is a 64 bits integer.
-static const double maxUInt64AsDouble = 18446744073709551615.0;
-#endif // defined(JSON_HAS_INT64)
-const LargestInt Value::minLargestInt = LargestInt(~(LargestUInt(-1) / 2));
-const LargestInt Value::maxLargestInt = LargestInt(LargestUInt(-1) / 2);
-const LargestUInt Value::maxLargestUInt = LargestUInt(-1);
-
-const UInt Value::defaultRealPrecision = 17;
-
-#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
-template <typename T, typename U>
-static inline bool InRange(double d, T min, U max) {
-  // The casts can lose precision, but we are looking only for
-  // an approximate range. Might fail on edge cases though. ~cdunn
-  // return d >= static_cast<double>(min) && d <= static_cast<double>(max);
-  return d >= min && d <= max;
-}
-#else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
-static inline double integerToDouble(Json::UInt64 value) {
-  return static_cast<double>(Int64(value / 2)) * 2.0 +
-         static_cast<double>(Int64(value & 1));
-}
-
-template <typename T> static inline double integerToDouble(T value) {
-  return static_cast<double>(value);
-}
-
-template <typename T, typename U>
-static inline bool InRange(double d, T min, U max) {
-  return d >= integerToDouble(min) && d <= integerToDouble(max);
-}
-#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
-
-/** Duplicates the specified string value.
- * @param value Pointer to the string to duplicate. Must be zero-terminated if
- *              length is "unknown".
- * @param length Length of the value. if equals to unknown, then it will be
- *               computed using strlen(value).
- * @return Pointer on the duplicate instance of string.
- */
-static inline char* duplicateStringValue(const char* value, size_t length) {
-  // Avoid an integer overflow in the call to malloc below by limiting length
-  // to a sane value.
-  if (length >= static_cast<size_t>(Value::maxInt))
-    length = Value::maxInt - 1;
-
-  char* newString = static_cast<char*>(malloc(length + 1));
-  if (newString == nullptr) {
-    throwRuntimeError("in Json::Value::duplicateStringValue(): "
-                      "Failed to allocate string value buffer");
-  }
-  memcpy(newString, value, length);
-  newString[length] = 0;
-  return newString;
-}
-
-/* Record the length as a prefix.
- */
-static inline char* duplicateAndPrefixStringValue(const char* value,
-                                                  unsigned int length) {
-  // Avoid an integer overflow in the call to malloc below by limiting length
-  // to a sane value.
-  JSON_ASSERT_MESSAGE(length <= static_cast<unsigned>(Value::maxInt) -
-                                    sizeof(unsigned) - 1U,
-                      "in Json::Value::duplicateAndPrefixStringValue(): "
-                      "length too big for prefixing");
-  unsigned actualLength = length + static_cast<unsigned>(sizeof(unsigned)) + 1U;
-  char* newString = static_cast<char*>(malloc(actualLength));
-  if (newString == nullptr) {
-    throwRuntimeError("in Json::Value::duplicateAndPrefixStringValue(): "
-                      "Failed to allocate string value buffer");
-  }
-  *reinterpret_cast<unsigned*>(newString) = length;
-  memcpy(newString + sizeof(unsigned), value, length);
-  newString[actualLength - 1U] =
-      0; // to avoid buffer over-run accidents by users later
-  return newString;
-}
-inline static void decodePrefixedString(bool isPrefixed,
-                                        char const* prefixed,
-                                        unsigned* length,
-                                        char const** value) {
-  if (!isPrefixed) {
-    *length = static_cast<unsigned>(strlen(prefixed));
-    *value = prefixed;
-  } else {
-    *length = *reinterpret_cast<unsigned const*>(prefixed);
-    *value = prefixed + sizeof(unsigned);
-  }
-}
-/** Free the string duplicated by
- * duplicateStringValue()/duplicateAndPrefixStringValue().
- */
-#if JSONCPP_USING_SECURE_MEMORY
-static inline void releasePrefixedStringValue(char* value) {
-  unsigned length = 0;
-  char const* valueDecoded;
-  decodePrefixedString(true, value, &length, &valueDecoded);
-  size_t const size = sizeof(unsigned) + length + 1U;
-  memset(value, 0, size);
-  free(value);
-}
-static inline void releaseStringValue(char* value, unsigned length) {
-  // length==0 => we allocated the strings memory
-  size_t size = (length == 0) ? strlen(value) : length;
-  memset(value, 0, size);
-  free(value);
-}
-#else  // !JSONCPP_USING_SECURE_MEMORY
-static inline void releasePrefixedStringValue(char* value) { free(value); }
-static inline void releaseStringValue(char* value, unsigned) { free(value); }
-#endif // JSONCPP_USING_SECURE_MEMORY
-
-} // namespace Json
-
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// ValueInternals...
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-#if !defined(JSON_IS_AMALGAMATION)
-
-#include "json_valueiterator.inl"
-#endif // if !defined(JSON_IS_AMALGAMATION)
-
-namespace Json {
-
-Exception::Exception(String msg) : msg_(std::move(msg)) {}
-Exception::~Exception() JSONCPP_NOEXCEPT {}
-char const* Exception::what() const JSONCPP_NOEXCEPT { return msg_.c_str(); }
-RuntimeError::RuntimeError(String const& msg) : Exception(msg) {}
-LogicError::LogicError(String const& msg) : Exception(msg) {}
-JSONCPP_NORETURN void throwRuntimeError(String const& msg) {
-  throw RuntimeError(msg);
-}
-JSONCPP_NORETURN void throwLogicError(String const& msg) {
-  throw LogicError(msg);
-}
-
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// class Value::CommentInfo
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-
-Value::CommentInfo::CommentInfo() = default;
-
-Value::CommentInfo::~CommentInfo() {
-  if (comment_)
-    releaseStringValue(comment_, 0u);
-}
-
-void Value::CommentInfo::setComment(const char* text, size_t len) {
-  if (comment_) {
-    releaseStringValue(comment_, 0u);
-    comment_ = nullptr;
-  }
-  JSON_ASSERT(text != nullptr);
-  JSON_ASSERT_MESSAGE(
-      text[0] == '\0' || text[0] == '/',
-      "in Json::Value::setComment(): Comments must start with /");
-  // It seems that /**/ style comments are acceptable as well.
-  comment_ = duplicateStringValue(text, len);
-}
-
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// class Value::CZString
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-
-// Notes: policy_ indicates if the string was allocated when
-// a string is stored.
-
-Value::CZString::CZString(ArrayIndex index) : cstr_(nullptr), index_(index) {}
-
-Value::CZString::CZString(char const* str,
-                          unsigned length,
-                          DuplicationPolicy allocate)
-    : cstr_(str) {
-  // allocate != duplicate
-  storage_.policy_ = allocate & 0x3;
-  storage_.length_ = length & 0x3FFFFFFF;
-}
-
-Value::CZString::CZString(const CZString& other) {
-  cstr_ = (other.storage_.policy_ != noDuplication && other.cstr_ != nullptr
-               ? duplicateStringValue(other.cstr_, other.storage_.length_)
-               : other.cstr_);
-  storage_.policy_ =
-      static_cast<unsigned>(
-          other.cstr_
-              ? (static_cast<DuplicationPolicy>(other.storage_.policy_) ==
-                         noDuplication
-                     ? noDuplication
-                     : duplicate)
-              : static_cast<DuplicationPolicy>(other.storage_.policy_)) &
-      3U;
-  storage_.length_ = other.storage_.length_;
-}
-
-#if JSON_HAS_RVALUE_REFERENCES
-Value::CZString::CZString(CZString&& other)
-    : cstr_(other.cstr_), index_(other.index_) {
-  other.cstr_ = nullptr;
-}
-#endif
-
-Value::CZString::~CZString() {
-  if (cstr_ && storage_.policy_ == duplicate) {
-    releaseStringValue(const_cast<char*>(cstr_),
-                       storage_.length_ + 1u); // +1 for null terminating
-                                               // character for sake of
-                                               // completeness but not actually
-                                               // necessary
-  }
-}
-
-void Value::CZString::swap(CZString& other) {
-  std::swap(cstr_, other.cstr_);
-  std::swap(index_, other.index_);
-}
-
-Value::CZString& Value::CZString::operator=(const CZString& other) {
-  cstr_ = other.cstr_;
-  index_ = other.index_;
-  return *this;
-}
-
-#if JSON_HAS_RVALUE_REFERENCES
-Value::CZString& Value::CZString::operator=(CZString&& other) {
-  cstr_ = other.cstr_;
-  index_ = other.index_;
-  other.cstr_ = nullptr;
-  return *this;
-}
-#endif
-
-bool Value::CZString::operator<(const CZString& other) const {
-  if (!cstr_)
-    return index_ < other.index_;
-  // return strcmp(cstr_, other.cstr_) < 0;
-  // Assume both are strings.
-  unsigned this_len = this->storage_.length_;
-  unsigned other_len = other.storage_.length_;
-  unsigned min_len = std::min<unsigned>(this_len, other_len);
-  JSON_ASSERT(this->cstr_ && other.cstr_);
-  int comp = memcmp(this->cstr_, other.cstr_, min_len);
-  if (comp < 0)
-    return true;
-  if (comp > 0)
-    return false;
-  return (this_len < other_len);
-}
-
-bool Value::CZString::operator==(const CZString& other) const {
-  if (!cstr_)
-    return index_ == other.index_;
-  // return strcmp(cstr_, other.cstr_) == 0;
-  // Assume both are strings.
-  unsigned this_len = this->storage_.length_;
-  unsigned other_len = other.storage_.length_;
-  if (this_len != other_len)
-    return false;
-  JSON_ASSERT(this->cstr_ && other.cstr_);
-  int comp = memcmp(this->cstr_, other.cstr_, this_len);
-  return comp == 0;
-}
-
-ArrayIndex Value::CZString::index() const { return index_; }
-
-// const char* Value::CZString::c_str() const { return cstr_; }
-const char* Value::CZString::data() const { return cstr_; }
-unsigned Value::CZString::length() const { return storage_.length_; }
-bool Value::CZString::isStaticString() const {
-  return storage_.policy_ == noDuplication;
-}
-
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// class Value::Value
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-// //////////////////////////////////////////////////////////////////
-
-/*! \internal Default constructor initialization must be equivalent to:
- * memset( this, 0, sizeof(Value) )
- * This optimization is used in ValueInternalMap fast allocator.
- */
-Value::Value(ValueType type) {
-  static char const emptyString[] = "";
-  initBasic(type);
-  switch (type) {
-  case nullValue:
-    break;
-  case intValue:
-  case uintValue:
-    value_.int_ = 0;
-    break;
-  case realValue:
-    value_.real_ = 0.0;
-    break;
-  case stringValue:
-    // allocated_ == false, so this is safe.
-    value_.string_ = const_cast<char*>(static_cast<char const*>(emptyString));
-    break;
-  case arrayValue:
-  case objectValue:
-    value_.map_ = new ObjectValues();
-    break;
-  case booleanValue:
-    value_.bool_ = false;
-    break;
-  default:
-    JSON_ASSERT_UNREACHABLE;
-  }
-}
-
-Value::Value(Int value) {
-  initBasic(intValue);
-  value_.int_ = value;
-}
-
-Value::Value(UInt value) {
-  initBasic(uintValue);
-  value_.uint_ = value;
-}
-#if defined(JSON_HAS_INT64)
-Value::Value(Int64 value) {
-  initBasic(intValue);
-  value_.int_ = value;
-}
-Value::Value(UInt64 value) {
-  initBasic(uintValue);
-  value_.uint_ = value;
-}
-#endif // defined(JSON_HAS_INT64)
-
-Value::Value(double value) {
-  initBasic(realValue);
-  value_.real_ = value;
-}
-
-Value::Value(const char* value) {
-  initBasic(stringValue, true);
-  JSON_ASSERT_MESSAGE(value != nullptr,
-                      "Null Value Passed to Value Constructor");
-  value_.string_ = duplicateAndPrefixStringValue(
-      value, static_cast<unsigned>(strlen(value)));
-}
-
-Value::Value(const char* begin, const char* end) {
-  initBasic(stringValue, true);
-  value_.string_ =
-      duplicateAndPrefixStringValue(begin, static_cast<unsigned>(end - begin));
-}
-
-Value::Value(const String& value) {
-  initBasic(stringValue, true);
-  value_.string_ = duplicateAndPrefixStringValue(
-      value.data(), static_cast<unsigned>(value.length()));
-}
-
-Value::Value(const StaticString& value) {
-  initBasic(stringValue);
-  value_.string_ = const_cast<char*>(value.c_str());
-}
-
-#ifdef JSON_USE_CPPTL
-Value::Value(const CppTL::ConstString& value) {
-  initBasic(stringValue, true);
-  value_.string_ = duplicateAndPrefixStringValue(
-      value, static_cast<unsigned>(value.length()));
-}
-#endif
-
-Value::Value(bool value) {
-  initBasic(booleanValue);
-  value_.bool_ = value;
-}
-
-Value::Value(const Value& other) {
-  dupPayload(other);
-  dupMeta(other);
-}
-
-Value::Value(Value&& other) {
-  initBasic(nullValue);
-  swap(other);
-}
-
-Value::~Value() {
-  releasePayload();
-  delete[] comments_;
-  value_.uint_ = 0;
-}
-
-Value& Value::operator=(const Value& other) {
-  Value(other).swap(*this);
-  return *this;
-}
-
-Value& Value::operator=(Value&& other) {
-  other.swap(*this);
-  return *this;
-}
-
-void Value::swapPayload(Value& other) {
-  std::swap(bits_, other.bits_);
-  std::swap(value_, other.value_);
-}
-
-void Value::copyPayload(const Value& other) {
-  releasePayload();
-  dupPayload(other);
-}
-
-void Value::swap(Value& other) {
-  swapPayload(other);
-  std::swap(comments_, other.comments_);
-  std::swap(start_, other.start_);
-  std::swap(limit_, other.limit_);
-}
-
-void Value::copy(const Value& other) {
-  copyPayload(other);
-  delete[] comments_;
-  dupMeta(other);
-}
-
-ValueType Value::type() const {
-  return static_cast<ValueType>(bits_.value_type_);
-}
-
-int Value::compare(const Value& other) const {
-  if (*this < other)
-    return -1;
-  if (*this > other)
-    return 1;
-  return 0;
-}
-
-bool Value::operator<(const Value& other) const {
-  int typeDelta = type() - other.type();
-  if (typeDelta)
-    return typeDelta < 0 ? true : false;
-  switch (type()) {
-  case nullValue:
-    return false;
-  case intValue:
-    return value_.int_ < other.value_.int_;
-  case uintValue:
-    return value_.uint_ < other.value_.uint_;
-  case realValue:
-    return value_.real_ < other.value_.real_;
-  case booleanValue:
-    return value_.bool_ < other.value_.bool_;
-  case stringValue: {
-    if ((value_.string_ == nullptr) || (other.value_.string_ == nullptr)) {
-      if (other.value_.string_)
-        return true;
-      else
-        return false;
-    }
-    unsigned this_len;
-    unsigned other_len;
-    char const* this_str;
-    char const* other_str;
-    decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,
-                         &this_str);
-    decodePrefixedString(other.isAllocated(), other.value_.string_, &other_len,
-                         &other_str);
-    unsigned min_len = std::min<unsigned>(this_len, other_len);
-    JSON_ASSERT(this_str && other_str);
-    int comp = memcmp(this_str, other_str, min_len);
-    if (comp < 0)
-      return true;
-    if (comp > 0)
-      return false;
-    return (this_len < other_len);
-  }
-  case arrayValue:
-  case objectValue: {
-    int delta = int(value_.map_->size() - other.value_.map_->size());
-    if (delta)
-      return delta < 0;
-    return (*value_.map_) < (*other.value_.map_);
-  }
-  default:
-    JSON_ASSERT_UNREACHABLE;
-  }
-  return false; // unreachable
-}
-
-bool Value::operator<=(const Value& other) const { return !(other < *this); }
-
-bool Value::operator>=(const Value& other) const { return !(*this < other); }
-
-bool Value::operator>(const Value& other) const { return other < *this; }
-
-bool Value::operator==(const Value& other) const {
-  if (type() != other.type())
-    return false;
-  switch (type()) {
-  case nullValue:
-    return true;
-  case intValue:
-    return value_.int_ == other.value_.int_;
-  case uintValue:
-    return value_.uint_ == other.value_.uint_;
-  case realValue:
-    return value_.real_ == other.value_.real_;
-  case booleanValue:
-    return value_.bool_ == other.value_.bool_;
-  case stringValue: {
-    if ((value_.string_ == nullptr) || (other.value_.string_ == nullptr)) {
-      return (value_.string_ == other.value_.string_);
-    }
-    unsigned this_len;
-    unsigned other_len;
-    char const* this_str;
-    char const* other_str;
-    decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,
-                         &this_str);
-    decodePrefixedString(other.isAllocated(), other.value_.string_, &other_len,
-                         &other_str);
-    if (this_len != other_len)
-      return false;
-    JSON_ASSERT(this_str && other_str);
-    int comp = memcmp(this_str, other_str, this_len);
-    return comp == 0;
-  }
-  case arrayValue:
-  case objectValue:
-    return value_.map_->size() == other.value_.map_->size() &&
-           (*value_.map_) == (*other.value_.map_);
-  default:
-    JSON_ASSERT_UNREACHABLE;
-  }
-  return false; // unreachable
-}
-
-bool Value::operator!=(const Value& other) const { return !(*this == other); }
-
-const char* Value::asCString() const {
-  JSON_ASSERT_MESSAGE(type() == stringValue,
-                      "in Json::Value::asCString(): requires stringValue");
-  if (value_.string_ == nullptr)
-    return nullptr;
-  unsigned this_len;
-  char const* this_str;
-  decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,
-                       &this_str);
-  return this_str;
-}
-
-#if JSONCPP_USING_SECURE_MEMORY
-unsigned Value::getCStringLength() const {
-  JSON_ASSERT_MESSAGE(type() == stringValue,
-                      "in Json::Value::asCString(): requires stringValue");
-  if (value_.string_ == 0)
-    return 0;
-  unsigned this_len;
-  char const* this_str;
-  decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,
-                       &this_str);
-  return this_len;
-}
-#endif
-
-bool Value::getString(char const** begin, char const** end) const {
-  if (type() != stringValue)
-    return false;
-  if (value_.string_ == nullptr)
-    return false;
-  unsigned length;
-  decodePrefixedString(this->isAllocated(), this->value_.string_, &length,
-                       begin);
-  *end = *begin + length;
-  return true;
-}
-
-String Value::asString() const {
-  switch (type()) {
-  case nullValue:
-    return "";
-  case stringValue: {
-    if (value_.string_ == nullptr)
-      return "";
-    unsigned this_len;
-    char const* this_str;
-    decodePrefixedString(this->isAllocated(), this->value_.string_, &this_len,
-                         &this_str);
-    return String(this_str, this_len);
-  }
-  case booleanValue:
-    return value_.bool_ ? "true" : "false";
-  case intValue:
-    return valueToString(value_.int_);
-  case uintValue:
-    return valueToString(value_.uint_);
-  case realValue:
-    return valueToString(value_.real_);
-  default:
-    JSON_FAIL_MESSAGE("Type is not convertible to string");
-  }
-}
-
-#ifdef JSON_USE_CPPTL
-CppTL::ConstString Value::asConstString() const {
-  unsigned len;
-  char const* str;
-  decodePrefixedString(isAllocated(), value_.string_, &len, &str);
-  return CppTL::ConstString(str, len);
-}
-#endif
-
-Value::Int Value::asInt() const {
-  switch (type()) {
-  case intValue:
-    JSON_ASSERT_MESSAGE(isInt(), "LargestInt out of Int range");
-    return Int(value_.int_);
-  case uintValue:
-    JSON_ASSERT_MESSAGE(isInt(), "LargestUInt out of Int range");
-    return Int(value_.uint_);
-  case realValue:
-    JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt, maxInt),
-                        "double out of Int range");
-    return Int(value_.real_);
-  case nullValue:
-    return 0;
-  case booleanValue:
-    return value_.bool_ ? 1 : 0;
-  default:
-    break;
-  }
-  JSON_FAIL_MESSAGE("Value is not convertible to Int.");
-}
-
-Value::UInt Value::asUInt() const {
-  switch (type()) {
-  case intValue:
-    JSON_ASSERT_MESSAGE(isUInt(), "LargestInt out of UInt range");
-    return UInt(value_.int_);
-  case uintValue:
-    JSON_ASSERT_MESSAGE(isUInt(), "LargestUInt out of UInt range");
-    return UInt(value_.uint_);
-  case realValue:
-    JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt),
-                        "double out of UInt range");
-    return UInt(value_.real_);
-  case nullValue:
-    return 0;
-  case booleanValue:
-    return value_.bool_ ? 1 : 0;
-  default:
-    break;
-  }
-  JSON_FAIL_MESSAGE("Value is not convertible to UInt.");
-}
-
-#if defined(JSON_HAS_INT64)
-
-Value::Int64 Value::asInt64() const {
-  switch (type()) {
-  case intValue:
-    return Int64(value_.int_);
-  case uintValue:
-    JSON_ASSERT_MESSAGE(isInt64(), "LargestUInt out of Int64 range");
-    return Int64(value_.uint_);
-  case realValue:
-    JSON_ASSERT_MESSAGE(InRange(value_.real_, minInt64, maxInt64),
-                        "double out of Int64 range");
-    return Int64(value_.real_);
-  case nullValue:
-    return 0;
-  case booleanValue:
-    return value_.bool_ ? 1 : 0;
-  default:
-    break;
-  }
-  JSON_FAIL_MESSAGE("Value is not convertible to Int64.");
-}
-
-Value::UInt64 Value::asUInt64() const {
-  switch (type()) {
-  case intValue:
-    JSON_ASSERT_MESSAGE(isUInt64(), "LargestInt out of UInt64 range");
-    return UInt64(value_.int_);
-  case uintValue:
-    return UInt64(value_.uint_);
-  case realValue:
-    JSON_ASSERT_MESSAGE(InRange(value_.real_, 0, maxUInt64),
-                        "double out of UInt64 range");
-    return UInt64(value_.real_);
-  case nullValue:
-    return 0;
-  case booleanValue:
-    return value_.bool_ ? 1 : 0;
-  default:
-    break;
-  }
-  JSON_FAIL_MESSAGE("Value is not convertible to UInt64.");
-}
-#endif // if defined(JSON_HAS_INT64)
-
-LargestInt Value::asLargestInt() const {
-#if defined(JSON_NO_INT64)
-  return asInt();
-#else
-  return asInt64();
-#endif
-}
-
-LargestUInt Value::asLargestUInt() const {
-#if defined(JSON_NO_INT64)
-  return asUInt();
-#else
-  return asUInt64();
-#endif
-}
-
-double Value::asDouble() const {
-  switch (type()) {
-  case intValue:
-    return static_cast<double>(value_.int_);
-  case uintValue:
-#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
-    return static_cast<double>(value_.uint_);
-#else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
-    return integerToDouble(value_.uint_);
-#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
-  case realValue:
-    return value_.real_;
-  case nullValue:
-    return 0.0;
-  case booleanValue:
-    return value_.bool_ ? 1.0 : 0.0;
-  default:
-    break;
-  }
-  JSON_FAIL_MESSAGE("Value is not convertible to double.");
-}
-
-float Value::asFloat() const {
-  switch (type()) {
-  case intValue:
-    return static_cast<float>(value_.int_);
-  case uintValue:
-#if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
-    return static_cast<float>(value_.uint_);
-#else  // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
-    // This can fail (silently?) if the value is bigger than MAX_FLOAT.
-    return static_cast<float>(integerToDouble(value_.uint_));
-#endif // if !defined(JSON_USE_INT64_DOUBLE_CONVERSION)
-  case realValue:
-    return static_cast<float>(value_.real_);
-  case nullValue:
-    return 0.0;
-  case booleanValue:
-    return value_.bool_ ? 1.0f : 0.0f;
-  default:
-    break;
-  }
-  JSON_FAIL_MESSAGE("Value is not convertible to float.");
-}
-
-bool Value::asBool() const {
-  switch (type()) {
-  case booleanValue:
-    return value_.bool_;
-  case nullValue:
-    return false;
-  case intValue:
-    return value_.int_ ? true : false;
-  case uintValue:
-    return value_.uint_ ? true : false;
-  case realValue:
-    // This is kind of strange. Not recommended.
-    return (value_.real_ != 0.0) ? true : false;
-  default:
-    break;
-  }
-  JSON_FAIL_MESSAGE("Value is not convertible to bool.");
-}
-
-bool Value::isConvertibleTo(ValueType other) const {
-  switch (other) {
-  case nullValue:
-    return (isNumeric() && asDouble() == 0.0) ||
-           (type() == booleanValue && value_.bool_ == false) ||
-           (type() == stringValue && asString().empty()) ||
-           (type() == arrayValue && value_.map_->empty()) ||
-           (type() == objectValue && value_.map_->empty()) ||
-           type() == nullValue;
-  case intValue:
-    return isInt() ||
-           (type() == realValue && InRange(value_.real_, minInt, maxInt)) ||
-           type() == booleanValue || type() == nullValue;
-  case uintValue:
-    return isUInt() ||
-           (type() == realValue && InRange(value_.real_, 0, maxUInt)) ||
-           type() == booleanValue || type() == nullValue;
-  case realValue:
-    return isNumeric() || type() == booleanValue || type() == nullValue;
-  case booleanValue:
-    return isNumeric() || type() == booleanValue || type() == nullValue;
-  case stringValue:
-    return isNumeric() || type() == booleanValue || type() == stringValue ||
-           type() == nullValue;
-  case arrayValue:
-    return type() == arrayValue || type() == nullValue;
-  case objectValue:
-    return type() == objectValue || type() == nullValue;
-  }
-  JSON_ASSERT_UNREACHABLE;
-  return false;
-}
-
-/// Number of values in array or object
-ArrayIndex Value::size() const {
-  switch (type()) {
-  case nullValue:
-  case intValue:
-  case uintValue:
-  case realValue:
-  case booleanValue:
-  case stringValue:
-    return 0;
-  case arrayValue: // size of the array is highest index + 1
-    if (!value_.map_->empty()) {
-      ObjectValues::const_iterator itLast = value_.map_->end();
-      --itLast;
-      return (*itLast).first.index() + 1;
-    }
-    return 0;
-  case objectValue:
-    return ArrayIndex(value_.map_->size());
-  }
-  JSON_ASSERT_UNREACHABLE;
-  return 0; // unreachable;
-}
-
-bool Value::empty() const {
-  if (isNull() || isArray() || isObject())
-    return size() == 0u;
-  else
-    return false;
-}
-
-Value::operator bool() const { return !isNull(); }
-
-void Value::clear() {
-  JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue ||
-                          type() == objectValue,
-                      "in Json::Value::clear(): requires complex value");
-  start_ = 0;
-  limit_ = 0;
-  switch (type()) {
-  case arrayValue:
-  case objectValue:
-    value_.map_->clear();
-    break;
-  default:
-    break;
-  }
-}
-
-void Value::resize(ArrayIndex newSize) {
-  JSON_ASSERT_MESSAGE(type() == nullValue || type() == arrayValue,
-                      "in Json::Value::resize(): requires arrayValue");
-  if (type() == nullValue)
-    *this = Value(arrayValue);
-  ArrayIndex oldSize = size();
-  if (newSize == 0)
-    clear();
-  else if (newSize > oldSize)
-    this->operator[](newSize - 1);
-  else {
-    for (ArrayIndex index = newSize; index < oldSize; ++index) {
-      value_.map_->erase(index);
-    }
-    JSON_ASSERT(size() == newSize);
-  }
-}
-
-Value& Value::operator[](ArrayIndex index) {
-  JSON_ASSERT_MESSAGE(
-      type() == nullValue || type() == arrayValue,
-      "in Json::Value::operator[](ArrayIndex): requires arrayValue");
-  if (type() == nullValue)
-    *this = Value(arrayValue);
-  CZString key(index);
-  auto it = value_.map_->lower_bound(key);
-  if (it != value_.map_->end() && (*it).first == key)
-    return (*it).second;
-
-  ObjectValues::value_type defaultValue(key, nullSingleton());
-  it = value_.map_->insert(it, defaultValue);
-  return (*it).second;
-}
-
-Value& Value::operator[](int index) {
-  JSON_ASSERT_MESSAGE(
-      index >= 0,
-      "in Json::Value::operator[](int index): index cannot be negative");
-  return (*this)[ArrayIndex(index)];
-}
-
-const Value& Value::operator[](ArrayIndex index) const {
-  JSON_ASSERT_MESSAGE(
-      type() == nullValue || type() == arrayValue,
-      "in Json::Value::operator[](ArrayIndex)const: requires arrayValue");
-  if (type() == nullValue)
-    return nullSingleton();
-  CZString key(index);
-  ObjectValues::const_iterator it = value_.map_->find(key);
-  if (it == value_.map_->end())
-    return nullSingleton();
-  return (*it).second;
-}
-
-const Value& Value::operator[](int index) const {
-  JSON_ASSERT_MESSAGE(
-      index >= 0,
-      "in Json::Value::operator[](int index) const: index cannot be negative");
-  return (*this)[ArrayIndex(index)];
-}
-
-void Value::initBasic(ValueType type, bool allocated) {
-  setType(type);
-  setIsAllocated(allocated);
-  comments_ = nullptr;
-  start_ = 0;
-  limit_ = 0;
-}
-
-void Value::dupPayload(const Value& other) {
-  setType(other.type());
-  setIsAllocated(false);
-  switch (type()) {
-  case nullValue:
-  case intValue:
-  case uintValue:
-  case realValue:
-  case booleanValue:
-    value_ = other.value_;
-    break;
-  case stringValue:
-    if (other.value_.string_ && other.isAllocated()) {
-      unsigned len;
-      char const* str;
-      decodePrefixedString(other.isAllocated(), other.value_.string_, &len,
-                           &str);
-      value_.string_ = duplicateAndPrefixStringValue(str, len);
-      setIsAllocated(true);
-    } else {
-      value_.string_ = other.value_.string_;
-    }
-    break;
-  case arrayValue:
-  case objectValue:
-    value_.map_ = new ObjectValues(*other.value_.map_);
-    break;
-  default:
-    JSON_ASSERT_UNREACHABLE;
-  }
-}
-
-void Value::releasePayload() {
-  switch (type()) {
-  case nullValue:
-  case intValue:
-  case uintValue:
-  case realValue:
-  case booleanValue:
-    break;
-  case stringValue:
-    if (isAllocated())
-      releasePrefixedStringValue(value_.string_);
-    break;
-  case arrayValue:
-  case objectValue:
-    delete value_.map_;
-    break;
-  default:
-    JSON_ASSERT_UNREACHABLE;
-  }
-}
-
-void Value::dupMeta(const Value& other) {
-  if (other.comments_) {
-    comments_ = new CommentInfo[numberOfCommentPlacement];
-    for (int comment = 0; comment < numberOfCommentPlacement; ++comment) {
-      const CommentInfo& otherComment = other.comments_[comment];
-      if (otherComment.comment_)
-        comments_[comment].setComment(otherComment.comment_,
-                                      strlen(otherComment.comment_));
-    }
-  } else {
-    comments_ = nullptr;
-  }
-  start_ = other.start_;
-  limit_ = other.limit_;
-}
-
-// Access an object value by name, create a null member if it does not exist.
-// @pre Type of '*this' is object or null.
-// @param key is null-terminated.
-Value& Value::resolveReference(const char* key) {
-  JSON_ASSERT_MESSAGE(
-      type() == nullValue || type() == objectValue,
-      "in Json::Value::resolveReference(): requires objectValue");
-  if (type() == nullValue)
-    *this = Value(objectValue);
-  CZString actualKey(key, static_cast<unsigned>(strlen(key)),
-                     CZString::noDuplication); // NOTE!
-  auto it = value_.map_->lower_bound(actualKey);
-  if (it != value_.map_->end() && (*it).first == actualKey)
-    return (*it).second;
-
-  ObjectValues::value_type defaultValue(actualKey, nullSingleton());
-  it = value_.map_->insert(it, defaultValue);
-  Value& value = (*it).second;
-  return value;
-}
-
-// @param key is not null-terminated.
-Value& Value::resolveReference(char const* key, char const* end) {
-  JSON_ASSERT_MESSAGE(
-      type() == nullValue || type() == objectValue,
-      "in Json::Value::resolveReference(key, end): requires objectValue");
-  if (type() == nullValue)
-    *this = Value(objectValue);
-  CZString actualKey(key, static_cast<unsigned>(end - key),
-                     CZString::duplicateOnCopy);
-  auto it = value_.map_->lower_bound(actualKey);
-  if (it != value_.map_->end() && (*it).first == actualKey)
-    return (*it).second;
-
-  ObjectValues::value_type defaultValue(actualKey, nullSingleton());
-  it = value_.map_->insert(it, defaultValue);
-  Value& value = (*it).second;
-  return value;
-}
-
-Value Value::get(ArrayIndex index, const Value& defaultValue) const {
-  const Value* value = &((*this)[index]);
-  return value == &nullSingleton() ? defaultValue : *value;
-}
-
-bool Value::isValidIndex(ArrayIndex index) const { return index < size(); }
-
-Value const* Value::find(char const* begin, char const* end) const {
-  JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,
-                      "in Json::Value::find(key, end, found): requires "
-                      "objectValue or nullValue");
-  if (type() == nullValue)
-    return nullptr;
-  CZString actualKey(begin, static_cast<unsigned>(end - begin),
-                     CZString::noDuplication);
-  ObjectValues::const_iterator it = value_.map_->find(actualKey);
-  if (it == value_.map_->end())
-    return nullptr;
-  return &(*it).second;
-}
-const Value& Value::operator[](const char* key) const {
-  Value const* found = find(key, key + strlen(key));
-  if (!found)
-    return nullSingleton();
-  return *found;
-}
-Value const& Value::operator[](const String& key) const {
-  Value const* found = find(key.data(), key.data() + key.length());
-  if (!found)
-    return nullSingleton();
-  return *found;
-}
-
-Value& Value::operator[](const char* key) {
-  return resolveReference(key, key + strlen(key));
-}
-
-Value& Value::operator[](const String& key) {
-  return resolveReference(key.data(), key.data() + key.length());
-}
-
-Value& Value::operator[](const StaticString& key) {
-  return resolveReference(key.c_str());
-}
-
-#ifdef JSON_USE_CPPTL
-Value& Value::operator[](const CppTL::ConstString& key) {
-  return resolveReference(key.c_str(), key.end_c_str());
-}
-Value const& Value::operator[](CppTL::ConstString const& key) const {
-  Value const* found = find(key.c_str(), key.end_c_str());
-  if (!found)
-    return nullSingleton();
-  return *found;
-}
-#endif
-
-Value& Value::append(const Value& value) { return (*this)[size()] = value; }
-
-#if JSON_HAS_RVALUE_REFERENCES
-Value& Value::append(Value&& value) {
-  return (*this)[size()] = std::move(value);
-}
-#endif
-
-Value Value::get(char const* begin,
-                 char const* end,
-                 Value const& defaultValue) const {
-  Value const* found = find(begin, end);
-  return !found ? defaultValue : *found;
-}
-Value Value::get(char const* key, Value const& defaultValue) const {
-  return get(key, key + strlen(key), defaultValue);
-}
-Value Value::get(String const& key, Value const& defaultValue) const {
-  return get(key.data(), key.data() + key.length(), defaultValue);
-}
-
-bool Value::removeMember(const char* begin, const char* end, Value* removed) {
-  if (type() != objectValue) {
-    return false;
-  }
-  CZString actualKey(begin, static_cast<unsigned>(end - begin),
-                     CZString::noDuplication);
-  auto it = value_.map_->find(actualKey);
-  if (it == value_.map_->end())
-    return false;
-  if (removed)
-#if JSON_HAS_RVALUE_REFERENCES
-    *removed = std::move(it->second);
-#else
-    *removed = it->second;
-#endif
-  value_.map_->erase(it);
-  return true;
-}
-bool Value::removeMember(const char* key, Value* removed) {
-  return removeMember(key, key + strlen(key), removed);
-}
-bool Value::removeMember(String const& key, Value* removed) {
-  return removeMember(key.data(), key.data() + key.length(), removed);
-}
-void Value::removeMember(const char* key) {
-  JSON_ASSERT_MESSAGE(type() == nullValue || type() == objectValue,
-                      "in Json::Value::removeMember(): requires objectValue");
-  if (type() == nullValue)
-    return;
-
-  CZString actualKey(key, unsigned(strlen(key)), CZString::noDuplication);
-  value_.map_->erase(actualKey);
-}
-void Value::removeMember(const String& key) { removeMember(key.c_str()); }
-
-bool Value::removeIndex(ArrayIndex index, Value* removed) {
-  if (type() != arrayValue) {
-    return false;
-  }
-  CZString key(index);
-  auto it = value_.map_->find(key);
-  if (it == value_.map_->end()) {
-    return false;
-  }
-  if (removed)
-    *removed = it->second;
-  ArrayIndex oldSize = size();
-  // shift left all items left, into the place of the "removed"
-  for (ArrayIndex i = index; i < (oldSize - 1); ++i) {
-    CZString keey(i);
-    (*value_.map_)[keey] = (*this)[i + 1];
-  }
-  // erase the last one ("leftover")
-  CZString keyLast(oldSize - 1);
-  auto itLast = value_.map_->find(keyLast);
-  value_.map_->erase(itLast);
-  return true;
-}
-
-#ifdef JSON_USE_CPPTL
-Value Value::get(const CppTL::ConstString& key,
-                 const Value& defaultValue) const {
-  return get(key.c_str(), key.end_c_str(), defaultValue);
-}
-#endif
-
-bool Value::isMember(char const* begin, char const* end) const {
-  Value const* value = find(begin, end);
-  return nullptr != value;
-}
-bool Value::isMember(char const* key) const {
-  return isMember(key, key + strlen(key));
-}
-bool Value::isMember(String const& key) const {
-  return isMember(key.data(), key.data() + key.length());
-}
-
-#ifdef JSON_USE_CPPTL
-bool Value::isMember(const CppTL::ConstString& key) const {
-  return isMember(key.c_str(), key.end_c_str());
-}
-#endif
-
-Value::Members Value::getMemberNames() const {
-  JSON_ASSERT_MESSAGE(
-      type() == nullValue || type() == objectValue,
-      "in Json::Value::getMemberNames(), value must be objectValue");
-  if (type() == nullValue)
-    return Value::Members();
-  Members members;
-  members.reserve(value_.map_->size());
-  ObjectValues::const_iterator it = value_.map_->begin();
-  ObjectValues::const_iterator itEnd = value_.map_->end();
-  for (; it != itEnd; ++it) {
-    members.push_back(String((*it).first.data(), (*it).first.length()));
-  }
-  return members;
-}
-//
-//# ifdef JSON_USE_CPPTL
-// EnumMemberNames
-// Value::enumMemberNames() const
-//{
-//   if ( type() == objectValue )
-//   {
-//      return CppTL::Enum::any(  CppTL::Enum::transform(
-//         CppTL::Enum::keys( *(value_.map_), CppTL::Type<const CZString &>() ),
-//         MemberNamesTransform() ) );
-//   }
-//   return EnumMemberNames();
-//}
-//
-//
-// EnumValues
-// Value::enumValues() const
-//{
-//   if ( type() == objectValue  ||  type() == arrayValue )
-//      return CppTL::Enum::anyValues( *(value_.map_),
-//                                     CppTL::Type<const Value &>() );
-//   return EnumValues();
-//}
-//
-//# endif
-
-static bool IsIntegral(double d) {
-  double integral_part;
-  return modf(d, &integral_part) == 0.0;
-}
-
-bool Value::isNull() const { return type() == nullValue; }
-
-bool Value::isBool() const { return type() == booleanValue; }
-
-bool Value::isInt() const {
-  switch (type()) {
-  case intValue:
-#if defined(JSON_HAS_INT64)
-    return value_.int_ >= minInt && value_.int_ <= maxInt;
-#else
-    return true;
-#endif
-  case uintValue:
-    return value_.uint_ <= UInt(maxInt);
-  case realValue:
-    return value_.real_ >= minInt && value_.real_ <= maxInt &&
-           IsIntegral(value_.real_);
-  default:
-    break;
-  }
-  return false;
-}
-
-bool Value::isUInt() const {
-  switch (type()) {
-  case intValue:
-#if defined(JSON_HAS_INT64)
-    return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt);
-#else
-    return value_.int_ >= 0;
-#endif
-  case uintValue:
-#if defined(JSON_HAS_INT64)
-    return value_.uint_ <= maxUInt;
-#else
-    return true;
-#endif
-  case realValue:
-    return value_.real_ >= 0 && value_.real_ <= maxUInt &&
-           IsIntegral(value_.real_);
-  default:
-    break;
-  }
-  return false;
-}
-
-bool Value::isInt64() const {
-#if defined(JSON_HAS_INT64)
-  switch (type()) {
-  case intValue:
-    return true;
-  case uintValue:
-    return value_.uint_ <= UInt64(maxInt64);
-  case realValue:
-    // Note that maxInt64 (= 2^63 - 1) is not exactly representable as a
-    // double, so double(maxInt64) will be rounded up to 2^63. Therefore we
-    // require the value to be strictly less than the limit.
-    return value_.real_ >= double(minInt64) &&
-           value_.real_ < double(maxInt64) && IsIntegral(value_.real_);
-  default:
-    break;
-  }
-#endif // JSON_HAS_INT64
-  return false;
-}
-
-bool Value::isUInt64() const {
-#if defined(JSON_HAS_INT64)
-  switch (type()) {
-  case intValue:
-    return value_.int_ >= 0;
-  case uintValue:
-    return true;
-  case realValue:
-    // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
-    // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
-    // require the value to be strictly less than the limit.
-    return value_.real_ >= 0 && value_.real_ < maxUInt64AsDouble &&
-           IsIntegral(value_.real_);
-  default:
-    break;
-  }
-#endif // JSON_HAS_INT64
-  return false;
-}
-
-bool Value::isIntegral() const {
-  switch (type()) {
-  case intValue:
-  case uintValue:
-    return true;
-  case realValue:
-#if defined(JSON_HAS_INT64)
-    // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
-    // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
-    // require the value to be strictly less than the limit.
-    return value_.real_ >= double(minInt64) &&
-           value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_);
-#else
-    return value_.real_ >= minInt && value_.real_ <= maxUInt &&
-           IsIntegral(value_.real_);
-#endif // JSON_HAS_INT64
-  default:
-    break;
-  }
-  return false;
-}
-
-bool Value::isDouble() const {
-  return type() == intValue || type() == uintValue || type() == realValue;
-}
-
-bool Value::isNumeric() const { return isDouble(); }
-
-bool Value::isString() const { return type() == stringValue; }
-
-bool Value::isArray() const { return type() == arrayValue; }
-
-bool Value::isObject() const { return type() == objectValue; }
-
-void Value::setComment(const char* comment,
-                       size_t len,
-                       CommentPlacement placement) {
-  if (!comments_)
-    comments_ = new CommentInfo[numberOfCommentPlacement];
-  if ((len > 0) && (comment[len - 1] == '\n')) {
-    // Always discard trailing newline, to aid indentation.
-    len -= 1;
-  }
-  comments_[placement].setComment(comment, len);
-}
-
-void Value::setComment(const char* comment, CommentPlacement placement) {
-  setComment(comment, strlen(comment), placement);
-}
-
-void Value::setComment(const String& comment, CommentPlacement placement) {
-  setComment(comment.c_str(), comment.length(), placement);
-}
-
-bool Value::hasComment(CommentPlacement placement) const {
-  return comments_ != nullptr && comments_[placement].comment_ != nullptr;
-}
-
-String Value::getComment(CommentPlacement placement) const {
-  if (hasComment(placement))
-    return comments_[placement].comment_;
-  return "";
-}
-
-void Value::setOffsetStart(ptrdiff_t start) { start_ = start; }
-
-void Value::setOffsetLimit(ptrdiff_t limit) { limit_ = limit; }
-
-ptrdiff_t Value::getOffsetStart() const { return start_; }
-
-ptrdiff_t Value::getOffsetLimit() const { return limit_; }
-
-String Value::toStyledString() const {
-  StreamWriterBuilder builder;
-
-  String out = this->hasComment(commentBefore) ? "\n" : "";
-  out += Json::writeString(builder, *this);
-  out += '\n';
-
-  return out;
-}
-
-Value::const_iterator Value::begin() const {
-  switch (type()) {
-  case arrayValue:
-  case objectValue:
-    if (value_.map_)
-      return const_iterator(value_.map_->begin());
-    break;
-  default:
-    break;
-  }
-  return {};
-}
-
-Value::const_iterator Value::end() const {
-  switch (type()) {
-  case arrayValue:
-  case objectValue:
-    if (value_.map_)
-      return const_iterator(value_.map_->end());
-    break;
-  default:
-    break;
-  }
-  return {};
-}
-
-Value::iterator Value::begin() {
-  switch (type()) {
-  case arrayValue:
-  case objectValue:
-    if (value_.map_)
-      return iterator(value_.map_->begin());
-    break;
-  default:
-    break;
-  }
-  return iterator();
-}
-
-Value::iterator Value::end() {
-  switch (type()) {
-  case arrayValue:
-  case objectValue:
-    if (value_.map_)
-      return iterator(value_.map_->end());
-    break;
-  default:
-    break;
-  }
-  return iterator();
-}
-
-// class PathArgument
-// //////////////////////////////////////////////////////////////////
-
-PathArgument::PathArgument() : key_() {}
-
-PathArgument::PathArgument(ArrayIndex index)
-    : key_(), index_(index), kind_(kindIndex) {}
-
-PathArgument::PathArgument(const char* key)
-    : key_(key), index_(), kind_(kindKey) {}
-
-PathArgument::PathArgument(const String& key)
-    : key_(key.c_str()), index_(), kind_(kindKey) {}
-
-// class Path
-// //////////////////////////////////////////////////////////////////
-
-Path::Path(const String& path,
-           const PathArgument& a1,
-           const PathArgument& a2,
-           const PathArgument& a3,
-           const PathArgument& a4,
-           const PathArgument& a5) {
-  InArgs in;
-  in.reserve(5);
-  in.push_back(&a1);
-  in.push_back(&a2);
-  in.push_back(&a3);
-  in.push_back(&a4);
-  in.push_back(&a5);
-  makePath(path, in);
-}
-
-void Path::makePath(const String& path, const InArgs& in) {
-  const char* current = path.c_str();
-  const char* end = current + path.length();
-  auto itInArg = in.begin();
-  while (current != end) {
-    if (*current == '[') {
-      ++current;
-      if (*current == '%')
-        addPathInArg(path, in, itInArg, PathArgument::kindIndex);
-      else {
-        ArrayIndex index = 0;
-        for (; current != end && *current >= '0' && *current <= '9'; ++current)
-          index = index * 10 + ArrayIndex(*current - '0');
-        args_.push_back(index);
-      }
-      if (current == end || *++current != ']')
-        invalidPath(path, int(current - path.c_str()));
-    } else if (*current == '%') {
-      addPathInArg(path, in, itInArg, PathArgument::kindKey);
-      ++current;
-    } else if (*current == '.' || *current == ']') {
-      ++current;
-    } else {
-      const char* beginName = current;
-      while (current != end && !strchr("[.", *current))
-        ++current;
-      args_.push_back(String(beginName, current));
-    }
-  }
-}
-
-void Path::addPathInArg(const String& /*path*/,
-                        const InArgs& in,
-                        InArgs::const_iterator& itInArg,
-                        PathArgument::Kind kind) {
-  if (itInArg == in.end()) {
-    // Error: missing argument %d
-  } else if ((*itInArg)->kind_ != kind) {
-    // Error: bad argument type
-  } else {
-    args_.push_back(**itInArg++);
-  }
-}
-
-void Path::invalidPath(const String& /*path*/, int /*location*/) {
-  // Error: invalid path.
-}
-
-const Value& Path::resolve(const Value& root) const {
-  const Value* node = &root;
-  for (const auto& arg : args_) {
-    if (arg.kind_ == PathArgument::kindIndex) {
-      if (!node->isArray() || !node->isValidIndex(arg.index_)) {
-        // Error: unable to resolve path (array value expected at position...
-        return Value::null;
-      }
-      node = &((*node)[arg.index_]);
-    } else if (arg.kind_ == PathArgument::kindKey) {
-      if (!node->isObject()) {
-        // Error: unable to resolve path (object value expected at position...)
-        return Value::null;
-      }
-      node = &((*node)[arg.key_]);
-      if (node == &Value::nullSingleton()) {
-        // Error: unable to resolve path (object has no member named '' at
-        // position...)
-        return Value::null;
-      }
-    }
-  }
-  return *node;
-}
-
-Value Path::resolve(const Value& root, const Value& defaultValue) const {
-  const Value* node = &root;
-  for (const auto& arg : args_) {
-    if (arg.kind_ == PathArgument::kindIndex) {
-      if (!node->isArray() || !node->isValidIndex(arg.index_))
-        return defaultValue;
-      node = &((*node)[arg.index_]);
-    } else if (arg.kind_ == PathArgument::kindKey) {
-      if (!node->isObject())
-        return defaultValue;
-      node = &((*node)[arg.key_]);
-      if (node == &Value::nullSingleton())
-        return defaultValue;
-    }
-  }
-  return *node;
-}
-
-Value& Path::make(Value& root) const {
-  Value* node = &root;
-  for (const auto& arg : args_) {
-    if (arg.kind_ == PathArgument::kindIndex) {
-      if (!node->isArray()) {
-        // Error: node is not an array at position ...
-      }
-      node = &((*node)[arg.index_]);
-    } else if (arg.kind_ == PathArgument::kindKey) {
-      if (!node->isObject()) {
-        // Error: node is not an object at position...
-      }
-      node = &((*node)[arg.key_]);
-    }
-  }
-  return *node;
-}
-
-} // namespace Json
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: src/lib_json/json_value.cpp
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
-
-// //////////////////////////////////////////////////////////////////////
-// Beginning of content of file: src/lib_json/json_writer.cpp
-// //////////////////////////////////////////////////////////////////////
-
-// Copyright 2011 Baptiste Lepilleur and The JsonCpp Authors
-// Distributed under MIT license, or public domain if desired and
-// recognized in your jurisdiction.
-// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
-
-#if !defined(JSON_IS_AMALGAMATION)
-#include "json_tool.h"
-#include <json/writer.h>
-#endif // if !defined(JSON_IS_AMALGAMATION)
-#include <cassert>
-#include <cstring>
-#include <iomanip>
-#include <memory>
-#include <set>
-#include <sstream>
-#include <utility>
-
-#if __cplusplus >= 201103L
-#include <cmath>
-#include <cstdio>
-
-#if !defined(isnan)
-#define isnan std::isnan
-#endif
-
-#if !defined(isfinite)
-#define isfinite std::isfinite
-#endif
-
-#else
-#include <cmath>
-#include <cstdio>
-
-#if defined(_MSC_VER)
-#if !defined(isnan)
-#include <float.h>
-#define isnan _isnan
-#endif
-
-#if !defined(isfinite)
-#include <float.h>
-#define isfinite _finite
-#endif
-
-#if !defined(_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES)
-#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
-#endif //_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES
-
-#endif //_MSC_VER
-
-#if defined(__sun) && defined(__SVR4) // Solaris
-#if !defined(isfinite)
-#include <ieeefp.h>
-#define isfinite finite
-#endif
-#endif
-
-#if defined(__hpux)
-#if !defined(isfinite)
-#if defined(__ia64) && !defined(finite)
-#define isfinite(x)                                                            \
-  ((sizeof(x) == sizeof(float) ? _Isfinitef(x) : _IsFinite(x)))
-#endif
-#endif
-#endif
-
-#if !defined(isnan)
-// IEEE standard states that NaN values will not compare to themselves
-#define isnan(x) (x != x)
-#endif
-
-#if !defined(__APPLE__)
-#if !defined(isfinite)
-#define isfinite finite
-#endif
-#endif
-#endif
-
-#if defined(_MSC_VER)
-// Disable warning about strdup being deprecated.
-#pragma warning(disable : 4996)
-#endif
-
-namespace Json {
-
-#if __cplusplus >= 201103L || (defined(_CPPLIB_VER) && _CPPLIB_VER >= 520)
-typedef std::unique_ptr<StreamWriter> StreamWriterPtr;
-#else
-typedef std::unique_ptr<StreamWriter> StreamWriterPtr;
-#endif
-
-String valueToString(LargestInt value) {
-  UIntToStringBuffer buffer;
-  char* current = buffer + sizeof(buffer);
-  if (value == Value::minLargestInt) {
-    uintToString(LargestUInt(Value::maxLargestInt) + 1, current);
-    *--current = '-';
-  } else if (value < 0) {
-    uintToString(LargestUInt(-value), current);
-    *--current = '-';
-  } else {
-    uintToString(LargestUInt(value), current);
-  }
-  assert(current >= buffer);
-  return current;
-}
-
-String valueToString(LargestUInt value) {
-  UIntToStringBuffer buffer;
-  char* current = buffer + sizeof(buffer);
-  uintToString(value, current);
-  assert(current >= buffer);
-  return current;
-}
-
-#if defined(JSON_HAS_INT64)
-
-String valueToString(Int value) { return valueToString(LargestInt(value)); }
-
-String valueToString(UInt value) { return valueToString(LargestUInt(value)); }
-
-#endif // # if defined(JSON_HAS_INT64)
-
-namespace {
-String valueToString(double value,
-                     bool useSpecialFloats,
-                     unsigned int precision,
-                     PrecisionType precisionType) {
-  // Print into the buffer. We need not request the alternative representation
-  // that always has a decimal point because JSON doesn't distinguish the
-  // concepts of reals and integers.
-  if (!isfinite(value)) {
-    static const char* const reps[2][3] = {{"NaN", "-Infinity", "Infinity"},
-                                           {"null", "-1e+9999", "1e+9999"}};
-    return reps[useSpecialFloats ? 0 : 1]
-               [isnan(value) ? 0 : (value < 0) ? 1 : 2];
-  }
-
-  String buffer(size_t(36), '\0');
-  while (true) {
-    int len = jsoncpp_snprintf(
-        &*buffer.begin(), buffer.size(),
-        (precisionType == PrecisionType::significantDigits) ? "%.*g" : "%.*f",
-        precision, value);
-    assert(len >= 0);
-    auto wouldPrint = static_cast<size_t>(len);
-    if (wouldPrint >= buffer.size()) {
-      buffer.resize(wouldPrint + 1);
-      continue;
-    }
-    buffer.resize(wouldPrint);
-    break;
-  }
-
-  buffer.erase(fixNumericLocale(buffer.begin(), buffer.end()), buffer.end());
-
-  // strip the zero padding from the right
-  if (precisionType == PrecisionType::decimalPlaces) {
-    buffer.erase(fixZerosInTheEnd(buffer.begin(), buffer.end()), buffer.end());
-  }
-
-  // try to ensure we preserve the fact that this was given to us as a double on
-  // input
-  if (buffer.find('.') == buffer.npos && buffer.find('e') == buffer.npos) {
-    buffer += ".0";
-  }
-  return buffer;
-}
-} // namespace
-
-String valueToString(double value,
-                     unsigned int precision,
-                     PrecisionType precisionType) {
-  return valueToString(value, false, precision, precisionType);
-}
-
-String valueToString(bool value) { return value ? "true" : "false"; }
-
-static bool isAnyCharRequiredQuoting(char const* s, size_t n) {
-  assert(s || !n);
-
-  char const* const end = s + n;
-  for (char const* cur = s; cur < end; ++cur) {
-    if (*cur == '\\' || *cur == '\"' || *cur < ' ' ||
-        static_cast<unsigned char>(*cur) < 0x80)
-      return true;
-  }
-  return false;
-}
-
-static unsigned int utf8ToCodepoint(const char*& s, const char* e) {
-  const unsigned int REPLACEMENT_CHARACTER = 0xFFFD;
-
-  unsigned int firstByte = static_cast<unsigned char>(*s);
-
-  if (firstByte < 0x80)
-    return firstByte;
-
-  if (firstByte < 0xE0) {
-    if (e - s < 2)
-      return REPLACEMENT_CHARACTER;
-
-    unsigned int calculated =
-        ((firstByte & 0x1F) << 6) | (static_cast<unsigned int>(s[1]) & 0x3F);
-    s += 1;
-    // oversized encoded characters are invalid
-    return calculated < 0x80 ? REPLACEMENT_CHARACTER : calculated;
-  }
-
-  if (firstByte < 0xF0) {
-    if (e - s < 3)
-      return REPLACEMENT_CHARACTER;
-
-    unsigned int calculated = ((firstByte & 0x0F) << 12) |
-                              ((static_cast<unsigned int>(s[1]) & 0x3F) << 6) |
-                              (static_cast<unsigned int>(s[2]) & 0x3F);
-    s += 2;
-    // surrogates aren't valid codepoints itself
-    // shouldn't be UTF-8 encoded
-    if (calculated >= 0xD800 && calculated <= 0xDFFF)
-      return REPLACEMENT_CHARACTER;
-    // oversized encoded characters are invalid
-    return calculated < 0x800 ? REPLACEMENT_CHARACTER : calculated;
-  }
-
-  if (firstByte < 0xF8) {
-    if (e - s < 4)
-      return REPLACEMENT_CHARACTER;
-
-    unsigned int calculated = ((firstByte & 0x07) << 18) |
-                              ((static_cast<unsigned int>(s[1]) & 0x3F) << 12) |
-                              ((static_cast<unsigned int>(s[2]) & 0x3F) << 6) |
-                              (static_cast<unsigned int>(s[3]) & 0x3F);
-    s += 3;
-    // oversized encoded characters are invalid
-    return calculated < 0x10000 ? REPLACEMENT_CHARACTER : calculated;
-  }
-
-  return REPLACEMENT_CHARACTER;
-}
-
-static const char hex2[] = "000102030405060708090a0b0c0d0e0f"
-                           "101112131415161718191a1b1c1d1e1f"
-                           "202122232425262728292a2b2c2d2e2f"
-                           "303132333435363738393a3b3c3d3e3f"
-                           "404142434445464748494a4b4c4d4e4f"
-                           "505152535455565758595a5b5c5d5e5f"
-                           "606162636465666768696a6b6c6d6e6f"
-                           "707172737475767778797a7b7c7d7e7f"
-                           "808182838485868788898a8b8c8d8e8f"
-                           "909192939495969798999a9b9c9d9e9f"
-                           "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
-                           "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
-                           "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
-                           "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf"
-                           "e0e1e2e3e4e5e6e7e8e9eaebecedeeef"
-                           "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
-
-static String toHex16Bit(unsigned int x) {
-  const unsigned int hi = (x >> 8) & 0xff;
-  const unsigned int lo = x & 0xff;
-  String result(4, ' ');
-  result[0] = hex2[2 * hi];
-  result[1] = hex2[2 * hi + 1];
-  result[2] = hex2[2 * lo];
-  result[3] = hex2[2 * lo + 1];
-  return result;
-}
-
-static String valueToQuotedStringN(const char* value, unsigned length) {
-  if (value == nullptr)
-    return "";
-
-  if (!isAnyCharRequiredQuoting(value, length))
-    return String("\"") + value + "\"";
-  // We have to walk value and escape any special characters.
-  // Appending to String is not efficient, but this should be rare.
-  // (Note: forward slashes are *not* rare, but I am not escaping them.)
-  String::size_type maxsize = length * 2 + 3; // allescaped+quotes+NULL
-  String result;
-  result.reserve(maxsize); // to avoid lots of mallocs
-  result += "\"";
-  char const* end = value + length;
-  for (const char* c = value; c != end; ++c) {
-    switch (*c) {
-    case '\"':
-      result += "\\\"";
-      break;
-    case '\\':
-      result += "\\\\";
-      break;
-    case '\b':
-      result += "\\b";
-      break;
-    case '\f':
-      result += "\\f";
-      break;
-    case '\n':
-      result += "\\n";
-      break;
-    case '\r':
-      result += "\\r";
-      break;
-    case '\t':
-      result += "\\t";
-      break;
-    // case '/':
-    // Even though \/ is considered a legal escape in JSON, a bare
-    // slash is also legal, so I see no reason to escape it.
-    // (I hope I am not misunderstanding something.)
-    // blep notes: actually escaping \/ may be useful in javascript to avoid </
-    // sequence.
-    // Should add a flag to allow this compatibility mode and prevent this
-    // sequence from occurring.
-    default: {
-      unsigned int cp = utf8ToCodepoint(c, end);
-      // don't escape non-control characters
-      // (short escape sequence are applied above)
-      if (cp < 0x80 && cp >= 0x20)
-        result += static_cast<char>(cp);
-      else if (cp < 0x10000) { // codepoint is in Basic Multilingual Plane
-        result += "\\u";
-        result += toHex16Bit(cp);
-      } else { // codepoint is not in Basic Multilingual Plane
-               // convert to surrogate pair first
-        cp -= 0x10000;
-        result += "\\u";
-        result += toHex16Bit((cp >> 10) + 0xD800);
-        result += "\\u";
-        result += toHex16Bit((cp & 0x3FF) + 0xDC00);
-      }
-    } break;
-    }
-  }
-  result += "\"";
-  return result;
-}
-
-String valueToQuotedString(const char* value) {
-  return valueToQuotedStringN(value, static_cast<unsigned int>(strlen(value)));
-}
-
-// Class Writer
-// //////////////////////////////////////////////////////////////////
-Writer::~Writer() = default;
-
-// Class FastWriter
-// //////////////////////////////////////////////////////////////////
-
-FastWriter::FastWriter()
-
-    = default;
-
-void FastWriter::enableYAMLCompatibility() { yamlCompatibilityEnabled_ = true; }
-
-void FastWriter::dropNullPlaceholders() { dropNullPlaceholders_ = true; }
-
-void FastWriter::omitEndingLineFeed() { omitEndingLineFeed_ = true; }
-
-String FastWriter::write(const Value& root) {
-  document_.clear();
-  writeValue(root);
-  if (!omitEndingLineFeed_)
-    document_ += '\n';
-  return document_;
-}
-
-void FastWriter::writeValue(const Value& value) {
-  switch (value.type()) {
-  case nullValue:
-    if (!dropNullPlaceholders_)
-      document_ += "null";
-    break;
-  case intValue:
-    document_ += valueToString(value.asLargestInt());
-    break;
-  case uintValue:
-    document_ += valueToString(value.asLargestUInt());
-    break;
-  case realValue:
-    document_ += valueToString(value.asDouble());
-    break;
-  case stringValue: {
-    // Is NULL possible for value.string_? No.
-    char const* str;
-    char const* end;
-    bool ok = value.getString(&str, &end);
-    if (ok)
-      document_ += valueToQuotedStringN(str, static_cast<unsigned>(end - str));
-    break;
-  }
-  case booleanValue:
-    document_ += valueToString(value.asBool());
-    break;
-  case arrayValue: {
-    document_ += '[';
-    ArrayIndex size = value.size();
-    for (ArrayIndex index = 0; index < size; ++index) {
-      if (index > 0)
-        document_ += ',';
-      writeValue(value[index]);
-    }
-    document_ += ']';
-  } break;
-  case objectValue: {
-    Value::Members members(value.getMemberNames());
-    document_ += '{';
-    for (auto it = members.begin(); it != members.end(); ++it) {
-      const String& name = *it;
-      if (it != members.begin())
-        document_ += ',';
-      document_ += valueToQuotedStringN(name.data(),
-                                        static_cast<unsigned>(name.length()));
-      document_ += yamlCompatibilityEnabled_ ? ": " : ":";
-      writeValue(value[name]);
-    }
-    document_ += '}';
-  } break;
-  }
-}
-
-// Class StyledWriter
-// //////////////////////////////////////////////////////////////////
-
-StyledWriter::StyledWriter() = default;
-
-String StyledWriter::write(const Value& root) {
-  document_.clear();
-  addChildValues_ = false;
-  indentString_.clear();
-  writeCommentBeforeValue(root);
-  writeValue(root);
-  writeCommentAfterValueOnSameLine(root);
-  document_ += '\n';
-  return document_;
-}
-
-void StyledWriter::writeValue(const Value& value) {
-  switch (value.type()) {
-  case nullValue:
-    pushValue("null");
-    break;
-  case intValue:
-    pushValue(valueToString(value.asLargestInt()));
-    break;
-  case uintValue:
-    pushValue(valueToString(value.asLargestUInt()));
-    break;
-  case realValue:
-    pushValue(valueToString(value.asDouble()));
-    break;
-  case stringValue: {
-    // Is NULL possible for value.string_? No.
-    char const* str;
-    char const* end;
-    bool ok = value.getString(&str, &end);
-    if (ok)
-      pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str)));
-    else
-      pushValue("");
-    break;
-  }
-  case booleanValue:
-    pushValue(valueToString(value.asBool()));
-    break;
-  case arrayValue:
-    writeArrayValue(value);
-    break;
-  case objectValue: {
-    Value::Members members(value.getMemberNames());
-    if (members.empty())
-      pushValue("{}");
-    else {
-      writeWithIndent("{");
-      indent();
-      auto it = members.begin();
-      for (;;) {
-        const String& name = *it;
-        const Value& childValue = value[name];
-        writeCommentBeforeValue(childValue);
-        writeWithIndent(valueToQuotedString(name.c_str()));
-        document_ += " : ";
-        writeValue(childValue);
-        if (++it == members.end()) {
-          writeCommentAfterValueOnSameLine(childValue);
-          break;
-        }
-        document_ += ',';
-        writeCommentAfterValueOnSameLine(childValue);
-      }
-      unindent();
-      writeWithIndent("}");
-    }
-  } break;
-  }
-}
-
-void StyledWriter::writeArrayValue(const Value& value) {
-  unsigned size = value.size();
-  if (size == 0)
-    pushValue("[]");
-  else {
-    bool isArrayMultiLine = isMultilineArray(value);
-    if (isArrayMultiLine) {
-      writeWithIndent("[");
-      indent();
-      bool hasChildValue = !childValues_.empty();
-      unsigned index = 0;
-      for (;;) {
-        const Value& childValue = value[index];
-        writeCommentBeforeValue(childValue);
-        if (hasChildValue)
-          writeWithIndent(childValues_[index]);
-        else {
-          writeIndent();
-          writeValue(childValue);
-        }
-        if (++index == size) {
-          writeCommentAfterValueOnSameLine(childValue);
-          break;
-        }
-        document_ += ',';
-        writeCommentAfterValueOnSameLine(childValue);
-      }
-      unindent();
-      writeWithIndent("]");
-    } else // output on a single line
-    {
-      assert(childValues_.size() == size);
-      document_ += "[ ";
-      for (unsigned index = 0; index < size; ++index) {
-        if (index > 0)
-          document_ += ", ";
-        document_ += childValues_[index];
-      }
-      document_ += " ]";
-    }
-  }
-}
-
-bool StyledWriter::isMultilineArray(const Value& value) {
-  ArrayIndex const size = value.size();
-  bool isMultiLine = size * 3 >= rightMargin_;
-  childValues_.clear();
-  for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
-    const Value& childValue = value[index];
-    isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
-                   !childValue.empty());
-  }
-  if (!isMultiLine) // check if line length > max line length
-  {
-    childValues_.reserve(size);
-    addChildValues_ = true;
-    ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
-    for (ArrayIndex index = 0; index < size; ++index) {
-      if (hasCommentForValue(value[index])) {
-        isMultiLine = true;
-      }
-      writeValue(value[index]);
-      lineLength += static_cast<ArrayIndex>(childValues_[index].length());
-    }
-    addChildValues_ = false;
-    isMultiLine = isMultiLine || lineLength >= rightMargin_;
-  }
-  return isMultiLine;
-}
-
-void StyledWriter::pushValue(const String& value) {
-  if (addChildValues_)
-    childValues_.push_back(value);
-  else
-    document_ += value;
-}
-
-void StyledWriter::writeIndent() {
-  if (!document_.empty()) {
-    char last = document_[document_.length() - 1];
-    if (last == ' ') // already indented
-      return;
-    if (last != '\n') // Comments may add new-line
-      document_ += '\n';
-  }
-  document_ += indentString_;
-}
-
-void StyledWriter::writeWithIndent(const String& value) {
-  writeIndent();
-  document_ += value;
-}
-
-void StyledWriter::indent() { indentString_ += String(indentSize_, ' '); }
-
-void StyledWriter::unindent() {
-  assert(indentString_.size() >= indentSize_);
-  indentString_.resize(indentString_.size() - indentSize_);
-}
-
-void StyledWriter::writeCommentBeforeValue(const Value& root) {
-  if (!root.hasComment(commentBefore))
-    return;
-
-  document_ += '\n';
-  writeIndent();
-  const String& comment = root.getComment(commentBefore);
-  String::const_iterator iter = comment.begin();
-  while (iter != comment.end()) {
-    document_ += *iter;
-    if (*iter == '\n' && ((iter + 1) != comment.end() && *(iter + 1) == '/'))
-      writeIndent();
-    ++iter;
-  }
-
-  // Comments are stripped of trailing newlines, so add one here
-  document_ += '\n';
-}
-
-void StyledWriter::writeCommentAfterValueOnSameLine(const Value& root) {
-  if (root.hasComment(commentAfterOnSameLine))
-    document_ += " " + root.getComment(commentAfterOnSameLine);
-
-  if (root.hasComment(commentAfter)) {
-    document_ += '\n';
-    document_ += root.getComment(commentAfter);
-    document_ += '\n';
-  }
-}
-
-bool StyledWriter::hasCommentForValue(const Value& value) {
-  return value.hasComment(commentBefore) ||
-         value.hasComment(commentAfterOnSameLine) ||
-         value.hasComment(commentAfter);
-}
-
-// Class StyledStreamWriter
-// //////////////////////////////////////////////////////////////////
-
-StyledStreamWriter::StyledStreamWriter(String indentation)
-    : document_(nullptr), indentation_(std::move(indentation)),
-      addChildValues_(), indented_(false) {}
-
-void StyledStreamWriter::write(OStream& out, const Value& root) {
-  document_ = &out;
-  addChildValues_ = false;
-  indentString_.clear();
-  indented_ = true;
-  writeCommentBeforeValue(root);
-  if (!indented_)
-    writeIndent();
-  indented_ = true;
-  writeValue(root);
-  writeCommentAfterValueOnSameLine(root);
-  *document_ << "\n";
-  document_ = nullptr; // Forget the stream, for safety.
-}
-
-void StyledStreamWriter::writeValue(const Value& value) {
-  switch (value.type()) {
-  case nullValue:
-    pushValue("null");
-    break;
-  case intValue:
-    pushValue(valueToString(value.asLargestInt()));
-    break;
-  case uintValue:
-    pushValue(valueToString(value.asLargestUInt()));
-    break;
-  case realValue:
-    pushValue(valueToString(value.asDouble()));
-    break;
-  case stringValue: {
-    // Is NULL possible for value.string_? No.
-    char const* str;
-    char const* end;
-    bool ok = value.getString(&str, &end);
-    if (ok)
-      pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str)));
-    else
-      pushValue("");
-    break;
-  }
-  case booleanValue:
-    pushValue(valueToString(value.asBool()));
-    break;
-  case arrayValue:
-    writeArrayValue(value);
-    break;
-  case objectValue: {
-    Value::Members members(value.getMemberNames());
-    if (members.empty())
-      pushValue("{}");
-    else {
-      writeWithIndent("{");
-      indent();
-      auto it = members.begin();
-      for (;;) {
-        const String& name = *it;
-        const Value& childValue = value[name];
-        writeCommentBeforeValue(childValue);
-        writeWithIndent(valueToQuotedString(name.c_str()));
-        *document_ << " : ";
-        writeValue(childValue);
-        if (++it == members.end()) {
-          writeCommentAfterValueOnSameLine(childValue);
-          break;
-        }
-        *document_ << ",";
-        writeCommentAfterValueOnSameLine(childValue);
-      }
-      unindent();
-      writeWithIndent("}");
-    }
-  } break;
-  }
-}
-
-void StyledStreamWriter::writeArrayValue(const Value& value) {
-  unsigned size = value.size();
-  if (size == 0)
-    pushValue("[]");
-  else {
-    bool isArrayMultiLine = isMultilineArray(value);
-    if (isArrayMultiLine) {
-      writeWithIndent("[");
-      indent();
-      bool hasChildValue = !childValues_.empty();
-      unsigned index = 0;
-      for (;;) {
-        const Value& childValue = value[index];
-        writeCommentBeforeValue(childValue);
-        if (hasChildValue)
-          writeWithIndent(childValues_[index]);
-        else {
-          if (!indented_)
-            writeIndent();
-          indented_ = true;
-          writeValue(childValue);
-          indented_ = false;
-        }
-        if (++index == size) {
-          writeCommentAfterValueOnSameLine(childValue);
-          break;
-        }
-        *document_ << ",";
-        writeCommentAfterValueOnSameLine(childValue);
-      }
-      unindent();
-      writeWithIndent("]");
-    } else // output on a single line
-    {
-      assert(childValues_.size() == size);
-      *document_ << "[ ";
-      for (unsigned index = 0; index < size; ++index) {
-        if (index > 0)
-          *document_ << ", ";
-        *document_ << childValues_[index];
-      }
-      *document_ << " ]";
-    }
-  }
-}
-
-bool StyledStreamWriter::isMultilineArray(const Value& value) {
-  ArrayIndex const size = value.size();
-  bool isMultiLine = size * 3 >= rightMargin_;
-  childValues_.clear();
-  for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
-    const Value& childValue = value[index];
-    isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
-                   !childValue.empty());
-  }
-  if (!isMultiLine) // check if line length > max line length
-  {
-    childValues_.reserve(size);
-    addChildValues_ = true;
-    ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
-    for (ArrayIndex index = 0; index < size; ++index) {
-      if (hasCommentForValue(value[index])) {
-        isMultiLine = true;
-      }
-      writeValue(value[index]);
-      lineLength += static_cast<ArrayIndex>(childValues_[index].length());
-    }
-    addChildValues_ = false;
-    isMultiLine = isMultiLine || lineLength >= rightMargin_;
-  }
-  return isMultiLine;
-}
-
-void StyledStreamWriter::pushValue(const String& value) {
-  if (addChildValues_)
-    childValues_.push_back(value);
-  else
-    *document_ << value;
-}
-
-void StyledStreamWriter::writeIndent() {
-  // blep intended this to look at the so-far-written string
-  // to determine whether we are already indented, but
-  // with a stream we cannot do that. So we rely on some saved state.
-  // The caller checks indented_.
-  *document_ << '\n' << indentString_;
-}
-
-void StyledStreamWriter::writeWithIndent(const String& value) {
-  if (!indented_)
-    writeIndent();
-  *document_ << value;
-  indented_ = false;
-}
-
-void StyledStreamWriter::indent() { indentString_ += indentation_; }
-
-void StyledStreamWriter::unindent() {
-  assert(indentString_.size() >= indentation_.size());
-  indentString_.resize(indentString_.size() - indentation_.size());
-}
-
-void StyledStreamWriter::writeCommentBeforeValue(const Value& root) {
-  if (!root.hasComment(commentBefore))
-    return;
-
-  if (!indented_)
-    writeIndent();
-  const String& comment = root.getComment(commentBefore);
-  String::const_iterator iter = comment.begin();
-  while (iter != comment.end()) {
-    *document_ << *iter;
-    if (*iter == '\n' && ((iter + 1) != comment.end() && *(iter + 1) == '/'))
-      // writeIndent();  // would include newline
-      *document_ << indentString_;
-    ++iter;
-  }
-  indented_ = false;
-}
-
-void StyledStreamWriter::writeCommentAfterValueOnSameLine(const Value& root) {
-  if (root.hasComment(commentAfterOnSameLine))
-    *document_ << ' ' << root.getComment(commentAfterOnSameLine);
-
-  if (root.hasComment(commentAfter)) {
-    writeIndent();
-    *document_ << root.getComment(commentAfter);
-  }
-  indented_ = false;
-}
-
-bool StyledStreamWriter::hasCommentForValue(const Value& value) {
-  return value.hasComment(commentBefore) ||
-         value.hasComment(commentAfterOnSameLine) ||
-         value.hasComment(commentAfter);
-}
-
-//////////////////////////
-// BuiltStyledStreamWriter
-
-/// Scoped enums are not available until C++11.
-struct CommentStyle {
-  /// Decide whether to write comments.
-  enum Enum {
-    None, ///< Drop all comments.
-    Most, ///< Recover odd behavior of previous versions (not implemented yet).
-    All   ///< Keep all comments.
-  };
-};
-
-struct BuiltStyledStreamWriter : public StreamWriter {
-  BuiltStyledStreamWriter(String indentation,
-                          CommentStyle::Enum cs,
-                          String colonSymbol,
-                          String nullSymbol,
-                          String endingLineFeedSymbol,
-                          bool useSpecialFloats,
-                          unsigned int precision,
-                          PrecisionType precisionType);
-  int write(Value const& root, OStream* sout) override;
-
-private:
-  void writeValue(Value const& value);
-  void writeArrayValue(Value const& value);
-  bool isMultilineArray(Value const& value);
-  void pushValue(String const& value);
-  void writeIndent();
-  void writeWithIndent(String const& value);
-  void indent();
-  void unindent();
-  void writeCommentBeforeValue(Value const& root);
-  void writeCommentAfterValueOnSameLine(Value const& root);
-  static bool hasCommentForValue(const Value& value);
-
-  typedef std::vector<String> ChildValues;
-
-  ChildValues childValues_;
-  String indentString_;
-  unsigned int rightMargin_;
-  String indentation_;
-  CommentStyle::Enum cs_;
-  String colonSymbol_;
-  String nullSymbol_;
-  String endingLineFeedSymbol_;
-  bool addChildValues_ : 1;
-  bool indented_ : 1;
-  bool useSpecialFloats_ : 1;
-  unsigned int precision_;
-  PrecisionType precisionType_;
-};
-BuiltStyledStreamWriter::BuiltStyledStreamWriter(String indentation,
-                                                 CommentStyle::Enum cs,
-                                                 String colonSymbol,
-                                                 String nullSymbol,
-                                                 String endingLineFeedSymbol,
-                                                 bool useSpecialFloats,
-                                                 unsigned int precision,
-                                                 PrecisionType precisionType)
-    : rightMargin_(74), indentation_(std::move(indentation)), cs_(cs),
-      colonSymbol_(std::move(colonSymbol)), nullSymbol_(std::move(nullSymbol)),
-      endingLineFeedSymbol_(std::move(endingLineFeedSymbol)),
-      addChildValues_(false), indented_(false),
-      useSpecialFloats_(useSpecialFloats), precision_(precision),
-      precisionType_(precisionType) {}
-int BuiltStyledStreamWriter::write(Value const& root, OStream* sout) {
-  sout_ = sout;
-  addChildValues_ = false;
-  indented_ = true;
-  indentString_.clear();
-  writeCommentBeforeValue(root);
-  if (!indented_)
-    writeIndent();
-  indented_ = true;
-  writeValue(root);
-  writeCommentAfterValueOnSameLine(root);
-  *sout_ << endingLineFeedSymbol_;
-  sout_ = nullptr;
-  return 0;
-}
-void BuiltStyledStreamWriter::writeValue(Value const& value) {
-  switch (value.type()) {
-  case nullValue:
-    pushValue(nullSymbol_);
-    break;
-  case intValue:
-    pushValue(valueToString(value.asLargestInt()));
-    break;
-  case uintValue:
-    pushValue(valueToString(value.asLargestUInt()));
-    break;
-  case realValue:
-    pushValue(valueToString(value.asDouble(), useSpecialFloats_, precision_,
-                            precisionType_));
-    break;
-  case stringValue: {
-    // Is NULL is possible for value.string_? No.
-    char const* str;
-    char const* end;
-    bool ok = value.getString(&str, &end);
-    if (ok)
-      pushValue(valueToQuotedStringN(str, static_cast<unsigned>(end - str)));
-    else
-      pushValue("");
-    break;
-  }
-  case booleanValue:
-    pushValue(valueToString(value.asBool()));
-    break;
-  case arrayValue:
-    writeArrayValue(value);
-    break;
-  case objectValue: {
-    Value::Members members(value.getMemberNames());
-    if (members.empty())
-      pushValue("{}");
-    else {
-      writeWithIndent("{");
-      indent();
-      auto it = members.begin();
-      for (;;) {
-        String const& name = *it;
-        Value const& childValue = value[name];
-        writeCommentBeforeValue(childValue);
-        writeWithIndent(valueToQuotedStringN(
-            name.data(), static_cast<unsigned>(name.length())));
-        *sout_ << colonSymbol_;
-        writeValue(childValue);
-        if (++it == members.end()) {
-          writeCommentAfterValueOnSameLine(childValue);
-          break;
-        }
-        *sout_ << ",";
-        writeCommentAfterValueOnSameLine(childValue);
-      }
-      unindent();
-      writeWithIndent("}");
-    }
-  } break;
-  }
-}
-
-void BuiltStyledStreamWriter::writeArrayValue(Value const& value) {
-  unsigned size = value.size();
-  if (size == 0)
-    pushValue("[]");
-  else {
-    bool isMultiLine = (cs_ == CommentStyle::All) || isMultilineArray(value);
-    if (isMultiLine) {
-      writeWithIndent("[");
-      indent();
-      bool hasChildValue = !childValues_.empty();
-      unsigned index = 0;
-      for (;;) {
-        Value const& childValue = value[index];
-        writeCommentBeforeValue(childValue);
-        if (hasChildValue)
-          writeWithIndent(childValues_[index]);
-        else {
-          if (!indented_)
-            writeIndent();
-          indented_ = true;
-          writeValue(childValue);
-          indented_ = false;
-        }
-        if (++index == size) {
-          writeCommentAfterValueOnSameLine(childValue);
-          break;
-        }
-        *sout_ << ",";
-        writeCommentAfterValueOnSameLine(childValue);
-      }
-      unindent();
-      writeWithIndent("]");
-    } else // output on a single line
-    {
-      assert(childValues_.size() == size);
-      *sout_ << "[";
-      if (!indentation_.empty())
-        *sout_ << " ";
-      for (unsigned index = 0; index < size; ++index) {
-        if (index > 0)
-          *sout_ << ((!indentation_.empty()) ? ", " : ",");
-        *sout_ << childValues_[index];
-      }
-      if (!indentation_.empty())
-        *sout_ << " ";
-      *sout_ << "]";
-    }
-  }
-}
-
-bool BuiltStyledStreamWriter::isMultilineArray(Value const& value) {
-  ArrayIndex const size = value.size();
-  bool isMultiLine = size * 3 >= rightMargin_;
-  childValues_.clear();
-  for (ArrayIndex index = 0; index < size && !isMultiLine; ++index) {
-    Value const& childValue = value[index];
-    isMultiLine = ((childValue.isArray() || childValue.isObject()) &&
-                   !childValue.empty());
-  }
-  if (!isMultiLine) // check if line length > max line length
-  {
-    childValues_.reserve(size);
-    addChildValues_ = true;
-    ArrayIndex lineLength = 4 + (size - 1) * 2; // '[ ' + ', '*n + ' ]'
-    for (ArrayIndex index = 0; index < size; ++index) {
-      if (hasCommentForValue(value[index])) {
-        isMultiLine = true;
-      }
-      writeValue(value[index]);
-      lineLength += static_cast<ArrayIndex>(childValues_[index].length());
-    }
-    addChildValues_ = false;
-    isMultiLine = isMultiLine || lineLength >= rightMargin_;
-  }
-  return isMultiLine;
-}
-
-void BuiltStyledStreamWriter::pushValue(String const& value) {
-  if (addChildValues_)
-    childValues_.push_back(value);
-  else
-    *sout_ << value;
-}
-
-void BuiltStyledStreamWriter::writeIndent() {
-  // blep intended this to look at the so-far-written string
-  // to determine whether we are already indented, but
-  // with a stream we cannot do that. So we rely on some saved state.
-  // The caller checks indented_.
-
-  if (!indentation_.empty()) {
-    // In this case, drop newlines too.
-    *sout_ << '\n' << indentString_;
-  }
-}
-
-void BuiltStyledStreamWriter::writeWithIndent(String const& value) {
-  if (!indented_)
-    writeIndent();
-  *sout_ << value;
-  indented_ = false;
-}
-
-void BuiltStyledStreamWriter::indent() { indentString_ += indentation_; }
-
-void BuiltStyledStreamWriter::unindent() {
-  assert(indentString_.size() >= indentation_.size());
-  indentString_.resize(indentString_.size() - indentation_.size());
-}
-
-void BuiltStyledStreamWriter::writeCommentBeforeValue(Value const& root) {
-  if (cs_ == CommentStyle::None)
-    return;
-  if (!root.hasComment(commentBefore))
-    return;
-
-  if (!indented_)
-    writeIndent();
-  const String& comment = root.getComment(commentBefore);
-  String::const_iterator iter = comment.begin();
-  while (iter != comment.end()) {
-    *sout_ << *iter;
-    if (*iter == '\n' && ((iter + 1) != comment.end() && *(iter + 1) == '/'))
-      // writeIndent();  // would write extra newline
-      *sout_ << indentString_;
-    ++iter;
-  }
-  indented_ = false;
-}
-
-void BuiltStyledStreamWriter::writeCommentAfterValueOnSameLine(
-    Value const& root) {
-  if (cs_ == CommentStyle::None)
-    return;
-  if (root.hasComment(commentAfterOnSameLine))
-    *sout_ << " " + root.getComment(commentAfterOnSameLine);
-
-  if (root.hasComment(commentAfter)) {
-    writeIndent();
-    *sout_ << root.getComment(commentAfter);
-  }
-}
-
-// static
-bool BuiltStyledStreamWriter::hasCommentForValue(const Value& value) {
-  return value.hasComment(commentBefore) ||
-         value.hasComment(commentAfterOnSameLine) ||
-         value.hasComment(commentAfter);
-}
-
-///////////////
-// StreamWriter
-
-StreamWriter::StreamWriter() : sout_(nullptr) {}
-StreamWriter::~StreamWriter() = default;
-StreamWriter::Factory::~Factory() = default;
-StreamWriterBuilder::StreamWriterBuilder() { setDefaults(&settings_); }
-StreamWriterBuilder::~StreamWriterBuilder() = default;
-StreamWriter* StreamWriterBuilder::newStreamWriter() const {
-  String indentation = settings_["indentation"].asString();
-  String cs_str = settings_["commentStyle"].asString();
-  String pt_str = settings_["precisionType"].asString();
-  bool eyc = settings_["enableYAMLCompatibility"].asBool();
-  bool dnp = settings_["dropNullPlaceholders"].asBool();
-  bool usf = settings_["useSpecialFloats"].asBool();
-  unsigned int pre = settings_["precision"].asUInt();
-  CommentStyle::Enum cs = CommentStyle::All;
-  if (cs_str == "All") {
-    cs = CommentStyle::All;
-  } else if (cs_str == "None") {
-    cs = CommentStyle::None;
-  } else {
-    throwRuntimeError("commentStyle must be 'All' or 'None'");
-  }
-  PrecisionType precisionType(significantDigits);
-  if (pt_str == "significant") {
-    precisionType = PrecisionType::significantDigits;
-  } else if (pt_str == "decimal") {
-    precisionType = PrecisionType::decimalPlaces;
-  } else {
-    throwRuntimeError("precisionType must be 'significant' or 'decimal'");
-  }
-  String colonSymbol = " : ";
-  if (eyc) {
-    colonSymbol = ": ";
-  } else if (indentation.empty()) {
-    colonSymbol = ":";
-  }
-  String nullSymbol = "null";
-  if (dnp) {
-    nullSymbol.clear();
-  }
-  if (pre > 17)
-    pre = 17;
-  String endingLineFeedSymbol;
-  return new BuiltStyledStreamWriter(indentation, cs, colonSymbol, nullSymbol,
-                                     endingLineFeedSymbol, usf, pre,
-                                     precisionType);
-}
-static void getValidWriterKeys(std::set<String>* valid_keys) {
-  valid_keys->clear();
-  valid_keys->insert("indentation");
-  valid_keys->insert("commentStyle");
-  valid_keys->insert("enableYAMLCompatibility");
-  valid_keys->insert("dropNullPlaceholders");
-  valid_keys->insert("useSpecialFloats");
-  valid_keys->insert("precision");
-  valid_keys->insert("precisionType");
-}
-bool StreamWriterBuilder::validate(Json::Value* invalid) const {
-  Json::Value my_invalid;
-  if (!invalid)
-    invalid = &my_invalid; // so we do not need to test for NULL
-  Json::Value& inv = *invalid;
-  std::set<String> valid_keys;
-  getValidWriterKeys(&valid_keys);
-  Value::Members keys = settings_.getMemberNames();
-  size_t n = keys.size();
-  for (size_t i = 0; i < n; ++i) {
-    String const& key = keys[i];
-    if (valid_keys.find(key) == valid_keys.end()) {
-      inv[key] = settings_[key];
-    }
-  }
-  return inv.empty();
-}
-Value& StreamWriterBuilder::operator[](const String& key) {
-  return settings_[key];
-}
-// static
-void StreamWriterBuilder::setDefaults(Json::Value* settings) {
-  //! [StreamWriterBuilderDefaults]
-  (*settings)["commentStyle"] = "All";
-  (*settings)["indentation"] = "\t";
-  (*settings)["enableYAMLCompatibility"] = false;
-  (*settings)["dropNullPlaceholders"] = false;
-  (*settings)["useSpecialFloats"] = false;
-  (*settings)["precision"] = 17;
-  (*settings)["precisionType"] = "significant";
-  //! [StreamWriterBuilderDefaults]
-}
-
-String writeString(StreamWriter::Factory const& factory, Value const& root) {
-  OStringStream sout;
-  StreamWriterPtr const writer(factory.newStreamWriter());
-  writer->write(root, &sout);
-  return sout.str();
-}
-
-OStream& operator<<(OStream& sout, Value const& root) {
-  StreamWriterBuilder builder;
-  StreamWriterPtr const writer(builder.newStreamWriter());
-  writer->write(root, &sout);
-  return sout;
-}
-
-} // namespace Json
-
-// //////////////////////////////////////////////////////////////////////
-// End of content of file: src/lib_json/json_writer.cpp
-// //////////////////////////////////////////////////////////////////////
-
-
-
-
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/main.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,207 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include <iostream>
-#include <sstream>
-#include <emscripten/emscripten.h>
-#include "TestStoneCodeGen_generated.hpp"
-
-using std::stringstream;
-
-int main()
-{
-    std::cout << "Hello world from testWasmIntegrated! (this is sent from C++)" << std::endl;
-    try
-    {
-    const char* jsonData = R"bgo({"definition":
-    {
-      "val" : [ "berk", 42 ],
-      "zozo" : { "23": "zloutch", "lalala": 42}
-    }
-    })bgo";
-    std::string strValue(jsonData);
-    
-    Json::Value readValue;
-
-    Json::CharReaderBuilder builder;
-    Json::CharReader* reader = builder.newCharReader();
-
-    StoneSmartPtr<Json::CharReader> ptr(reader);
-
-    std::string errors;
-
-    bool ok = reader->parse(
-      strValue.c_str(),
-      strValue.c_str() + strValue.size(),
-      &readValue,
-      &errors
-    );
-    if (!ok)
-    {
-      std::stringstream ss;
-      ss << "Jsoncpp parsing error: " << errors;
-      throw std::runtime_error(ss.str());
-    }
-    std::cout << "Json parsing OK" << std::endl;
-    std::cout << readValue  << std::endl;
-    }
-    catch(std::exception& e)
-    {
-      std::cout << "Json parsing THROW" << std::endl;
-      std::cout << "e.what() = " << e.what() << std::endl;
-    }
-}
-
-extern "C" void SendMessageFromCppJS(const char* message);
-extern "C" void SendFreeTextFromCppJS(const char* message);
-
-#define HANDLE_MESSAGE(Type,value) \
-  stringstream ss; \
-  ss << "Received an instance of:\n" #Type "\n. Here's the dump:\n"; \
-  TestStoneCodeGen::StoneDumpValue(ss, value, 0); \
-  SendFreeTextFromCppJS(ss.str().c_str()); \
-  return true;
-
-#define ECHO_MESSAGE(Type,value) \
-  stringstream ss; \
-  ss << "Received an instance of:\n" #Type "\n. Here's the dump:\n"; \
-  TestStoneCodeGen::StoneDumpValue(ss, value, 0); \
-  SendFreeTextFromCppJS(ss.str().c_str()); \
-  std::string serializedInCpp = StoneSerialize(value); \
-  SendMessageFromCppJS(serializedInCpp.c_str()); \
-  return true;
-
-class MyHandler : public TestStoneCodeGen::IHandler
-{
-  public:
-    virtual bool Handle(const TestStoneCodeGen::A& value) override
-    {
-      HANDLE_MESSAGE(TestStoneCodeGen::A,value)
-    }
-    virtual bool Handle(const TestStoneCodeGen::B& value) override
-    {
-      HANDLE_MESSAGE(TestStoneCodeGen::B,value)
-    }
-
-    virtual bool Handle(const TestStoneCodeGen::Message1& value) override
-    {
-      HANDLE_MESSAGE(TestStoneCodeGen::Message1,value)
-    }
-
-    virtual bool Handle(const TestStoneCodeGen::Message2& value) override
-    {
-      HANDLE_MESSAGE(TestStoneCodeGen::Message2,value)
-    }
-
-    virtual bool Handle(const TestStoneCodeGen::C& value) override
-    {
-      HANDLE_MESSAGE(TestStoneCodeGen::C,value)
-    }
-};
-
-class MyEchoHandler : public TestStoneCodeGen::IHandler
-{
-  public:
-    virtual bool Handle(const TestStoneCodeGen::A& value) override
-    {
-      ECHO_MESSAGE(TestStoneCodeGen::A,value)
-    }
-    virtual bool Handle(const TestStoneCodeGen::B& value) override
-    {
-      ECHO_MESSAGE(TestStoneCodeGen::B,value)
-    }
-
-    virtual bool Handle(const TestStoneCodeGen::Message1& value) override
-    {
-      ECHO_MESSAGE(TestStoneCodeGen::Message1,value)
-    }
-
-    virtual bool Handle(const TestStoneCodeGen::Message2& value) override
-    {
-      ECHO_MESSAGE(TestStoneCodeGen::Message2,value)
-    }
-
-    virtual bool Handle(const TestStoneCodeGen::C& value) override
-    {
-      ECHO_MESSAGE(TestStoneCodeGen::C,value)
-    }
-};
-
-extern "C" void EMSCRIPTEN_KEEPALIVE SendMessageToCpp(const char* message)
-{
-    MyHandler handler;
-    try
-    {
-      bool handled = TestStoneCodeGen::StoneDispatchToHandler(message,&handler);
-      if(!handled)
-      {
-        SendFreeTextFromCppJS("This message is valid JSON, but was not handled!");  
-      }
-    }
-    catch(std::exception& e)
-    {
-      stringstream ss;
-      ss << "Error while parsing message: " << e.what() << "\n";
-      SendFreeTextFromCppJS(ss.str().c_str());  
-    }
-}
-
-extern "C" void EMSCRIPTEN_KEEPALIVE SendMessageToCppForEcho(const char* message)
-{
-    MyEchoHandler echoHandler;
-    try
-    {
-      bool handled = TestStoneCodeGen::StoneDispatchToHandler(message,&echoHandler);
-      if(!handled)
-      {
-        SendFreeTextFromCppJS("This message is valid JSON, but was not handled by the echo handler!");  
-      }
-    }
-    catch(std::exception& e)
-    {
-      stringstream ss;
-      ss << "Error while parsing message: " << e.what() << "\n";
-      SendFreeTextFromCppJS(ss.str().c_str());  
-    }
-}
-
-void EMSCRIPTEN_KEEPALIVE StartWasmApplication(const char* baseUri)
-{
-    printf("Hello! (this is sent from C++)\n");
-
-//     // recreate a command line from uri arguments and parse it
-//     boost::program_options::variables_map parameters;
-//     boost::program_options::options_description options;
-//     application->DeclareStartupOptions(options);
-//     startupParametersBuilder.GetStartupParameters(parameters, options);
-
-//     context.reset(new OrthancStone::StoneApplicationContext(broker));
-//     context->SetOrthancBaseUrl(baseUri);
-//     printf("Base URL to Orthanc API: [%s]\n", baseUri);
-//     context->SetWebService(OrthancStone::WasmWebService::GetInstance());
-//     context->SetDelayedCallExecutor(OrthancStone::WasmDelayedCallExecutor::GetInstance());
-//     application->Initialize(context.get(), statusBar_, parameters);
-//     application->InitializeWasm();
-
-// //    viewport->SetSize(width_, height_);
-//     printf("StartWasmApplication - completed\n");
-    SendFreeTextFromCppJS("Hello world from C++!");
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/serve.py	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-# -*- coding: utf-8 -*-
-# tested on python 3.4 ,python of lower version  has different module organization.
-# from https://gist.github.com/HaiyangXu/ec88cbdce3cdbac7b8d5
-import http.server
-from http.server import HTTPServer, BaseHTTPRequestHandler
-import socketserver
-
-PORT = 8080
-
-Handler = http.server.SimpleHTTPRequestHandler
-
-Handler.extensions_map = {
-  '.manifest': 'text/cache-manifest',
-  '.html': 'text/html',
-  '.png': 'image/png',
-  '.jpg': 'image/jpg',
-  '.svg': 'image/svg+xml',
-  '.wasm': 'application/wasm',
-  '.css': 'text/css',
-  '.js': 'application/x-javascript',
-  '': 'application/octet-stream',  # Default
-}
-
-httpd = socketserver.TCPServer(("", PORT), Handler)
-
-print("serving at port", PORT)
-httpd.serve_forever()
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/styles.css	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-.TestWasm-grid-container {
-    display: grid;
-    grid-template-columns: 0.55fr 0.55fr 0.55fr 0.55fr 0.6fr 1.1fr 1.1fr;
-    grid-template-rows: 1.1fr 0.9fr 0.2fr 0.3fr 0.1fr 0.3fr 0.1fr;
-    grid-template-areas: 
-        "SerializedInput SerializedInput SerializedInput SerializedInput ButtonContainer CppOutput CppOutput" 
-        "SerializedInput SerializedInput SerializedInput SerializedInput ButtonContainer CppOutput CppOutput" 
-        ". . . . . . ." 
-        "Test1 Test2 Test3 Test4 . . ." 
-        ". . . . . . ." 
-        "Test5 Test6 Test7 Test8 . . ."
-        "TestTsCppTs . . . . . ." 
-        ". . . . . . ." 
-        ;
-    height: 480px;
-  }
-
-  .TestWasm-ButtonContainer {
-    display: grid;
-    grid-template-columns: 0.2fr 0.8fr 0.2fr;
-    grid-template-rows: 0.2fr 0.5fr 0.2fr 0.5fr 0.2fr 0.5fr 0.2fr;
-    grid-template-areas: 
-        ". . ."
-        ". TriggerButton ." 
-        ". . ."
-        ". ClearButton ." 
-        ". . ."
-        ". ShowSchemaButton ." 
-        ". . ."
-        ;
-  }
-
-  .TestWasm-TriggerButton { grid-area: TriggerButton; }
-  
-  .TestWasm-ClearButton { grid-area: ClearButton; }
-  
-  .TestWasm-ShowSchemaButton { grid-area: ShowSchemaButton; }
-
-
-.TestWasm-SerializedInput { grid-area: SerializedInput; }
-
-.TestWasm-CppOutput { grid-area: CppOutput; }
-
-.TestWasm-ButtonContainer { grid-area: ButtonContainer; }
-
-.TestWasm-Test1 { grid-area: Test1; }
-
-.TestWasm-Test2 { grid-area: Test2; }
-
-.TestWasm-Test3 { grid-area: Test3; }
-
-.TestWasm-Test4 { grid-area: Test4; }
-
-.TestWasm-Test5 { grid-area: Test5; }
-
-.TestWasm-Test6 { grid-area: Test6; }
-
-.TestWasm-Test7 { grid-area: Test7; }
-
-.TestWasm-Test8 { grid-area: Test8; }
-
-.TestWasm-ts-cpp-ts { grid-area: TestTsCppTs; }
-
-.TestWasm-button {
-    width:80px;
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/testWasmIntegrated.html	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-<!doctype html>
-
-<html lang="us">
-  <head>
-    <meta charset="utf-8" />
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-
-    <title>Javascript to WASM message passing</title>
-    <link href="styles.css" rel="stylesheet" />
-    <!-- <link href="styles2.css" rel="stylesheet" /> -->
-    <!-- 
-    <link href="testwasm_bootstrap.css" rel="stylesheet" /> 
-    -->
-    <body>
-    <div class="TestWasm-grid-container">
-        <textarea id="TestWasm-SerializedInput" class="TestWasm-SerializedInput">Serialized data should be put here.</textarea>
-        <textarea id="TestWasm-CppOutput" class="TestWasm-CppOutput">Free text and messages from C++ will appear here.</textarea>
-        <div class="TestWasm-ButtonContainer">
-          <div class="TestWasm-TriggerButton">
-            <button class="TestWasm-button" tool-selector="Trigger">Send message</button>
-          </div>
-          <div class="TestWasm-ClearButton">
-            <button class="TestWasm-button" tool-selector="Clear">Clear</button>
-          </div>
-          <div class="TestWasm-ShowSchemaButton">
-            <button class="TestWasm-button" tool-selector="ShowSchema">Show schema</button>
-          </div>
-           <!-- <button class="TestWasm-button TestWasm-hvcenter" tool-selector="Trigger">Send message</button>
-            <button class="TestWasm-button TestWasm-hvcenter" tool-selector="Clear">Clear</button>
-            <button class="TestWasm-button TestWasm-hvcenter" tool-selector="Show schema">Show schema</button> -->
-        </div>
-        
-        <div class="TestWasm-Test1">
-          <button class="TestWasm-button" tool-selector="Test CppHandler message2">Test CppHandler message2</button>
-        </div>
-        <div class="TestWasm-Test2">
-          <button class="TestWasm-button" tool-selector="Test 2">Test 2</button>
-        </div>
-        <div class="TestWasm-Test3">
-          <button class="TestWasm-button" tool-selector="Test 3">Test 3</button>
-        </div>
-        <div class="TestWasm-Test4">
-          <button class="TestWasm-button" tool-selector="Test 4">Test 4</button>
-        </div>
-        <div class="TestWasm-Test5">
-          <button class="TestWasm-button" tool-selector="Test 5">Test 5</button>
-        </div>
-        <div class="TestWasm-Test6">
-          <button class="TestWasm-button" tool-selector="Test 6">Test 6</button>
-        </div>
-        <div class="TestWasm-Test7">
-          <button class="TestWasm-button" tool-selector="Test 7">Test 7</button>
-        </div>
-        <div class="TestWasm-Test8">
-          <button class="TestWasm-button" tool-selector="Test 8">Test 8</button>
-        </div>
-        <div class="TestWasm-ts-cpp-ts">
-          <button class="TestWasm-button" tool-selector="Test-ts-cpp-ts">Test ts-cpp-ts</button>
-        </div>
-  
-        <!-- <button class="TestWasm-button" class="TestWasm-Test1" tool-selector="Test 1">Test 1</button>
-        <button class="TestWasm-button" class="TestWasm-Test2" tool-selector="Test 2">Test 2</button>
-        <button class="TestWasm-button" class="TestWasm-Test3" tool-selector="Test 3">Test 3</button>
-        <button class="TestWasm-button" class="TestWasm-Test4" tool-selector="Test 4">Test 4</button> -->
-
-
-
-        <!-- <div class="Trigger"></div>
-        <div class="Test1"></div>
-        <div class="Test2"></div>
-        <div class="Test3"></div>
-        <div class="Test4"></div> -->
-      </div>
-
-  <!-- <div id="toolbox" style="height: 50px">
-    <button tool-selector="line-measure" class="tool-selector">line</button>
-  </div> -->
-  <script type="text/javascript" src="testWasmIntegratedCpp.js"></script>
-  <script type="text/javascript" src="testWasmIntegratedApp.js"></script>
-</body>
-
-</html>
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/testWasmIntegrated/testWasmIntegrated.ts	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +0,0 @@
-var SendMessageToCpp: Function = null;
-export var TestWasmIntegratedModule : any;
-
-import * as TestStoneCodeGen from './build-wasm/TestStoneCodeGen_generated'
-
-/*
-+--------------------------------------------------+
-|  install emscripten handlers                     |
-+--------------------------------------------------+
-*/
-
-// (<any> window).Module = {
-//   preRun: [ 
-//     function() {
-//     console.log('Loading the Stone Framework using WebAssembly');
-//     }
-//   ],
-//   postRun: [ 
-//     function()  {
-//     // This function is called by ".js" wrapper once the ".wasm"
-//     // WebAssembly module has been loaded and compiled by the
-//     // browser
-//     console.log('WebAssembly is ready');
-//     // window.SendMessageToCpp = (<any> window).Module.cwrap('SendMessageToCpp', 'string', ['string']);
-//     // window.SendFreeTextToCpp = (<any> window).Module.cwrap('SendFreeTextToCpp', 'string', ['string']);
-//     }
-//   ],
-//   print: function(text : string) {
-//     console.log(text);
-//   },
-//   printErr: function(text : string) {
-//     console.error(text);
-//   },
-//   totalDependencies: 0
-// };
-
-/*
-+--------------------------------------------------+
-|  install handlers                                |
-+--------------------------------------------------+
-*/
-document.querySelectorAll(".TestWasm-button").forEach((e) => {
-  (e as HTMLButtonElement).addEventListener("click", () => {
-    ButtonClick(e.attributes["tool-selector"].value);
-  });
-});
-
-/*
-+--------------------------------------------------+
-|  define stock messages                           |
-+--------------------------------------------------+
-*/
-let schemaText: string = null;
-fetch("testTestStoneCodeGen.yaml").then(function(res) {return res.text();}).then(function(text) {schemaText = text;});
-
-let stockSerializedMessages = new Map<string,string>();
-stockSerializedMessages["Test CppHandler message2"] = null;
-fetch("cppHandler_test_Message2.json").then(function(res) {return res.text();}).then(function(text) {stockSerializedMessages["Test CppHandler message2"] = text;});
-
-stockSerializedMessages["Test 2"] = ` {
-  "type" : "TestStoneCodeGen.Message1",
-  "value" : {
-    "memberInt32" : -987,
-    "memberString" : "Salomé",
-    "memberEnumMonth" : "March",
-    "memberBool" : true,
-    "memberFloat32" : 0.1,
-    "memberFloat64" : -0.2,
-    "extraMember" : "don't care"
-  }
-}`;
-stockSerializedMessages["Test 3"] = "Test 3 stock message sdfsfsdfsdf";
-stockSerializedMessages["Test 4"] = "Test 4 stock message 355345345";
-stockSerializedMessages["Test 5"] = "Test 5 stock message 34535";
-stockSerializedMessages["Test 6"] = "Test 6 stock message xcvcxvx";
-stockSerializedMessages["Test 7"] = "Test 7 stock message fgwqewqdgg";
-stockSerializedMessages["Test 8"] = "Test 8 stock message fgfsdfsdgg";
-
-/*
-+--------------------------------------------------+
-|  define handler                                  |
-+--------------------------------------------------+
-*/
-
-function setSerializedInputValue(text: string) {
-  let e : HTMLTextAreaElement = document.getElementById('TestWasm-SerializedInput') as HTMLTextAreaElement;
-  e.value = text;
-}
-
-function getSerializedInputValue(): string {
-  let e : HTMLTextAreaElement = document.getElementById('TestWasm-SerializedInput') as HTMLTextAreaElement;
-  return e.value;
-}
-
-function setCppOutputValue(text: string) {
-  let e : HTMLTextAreaElement = document.getElementById('TestWasm-CppOutput') as HTMLTextAreaElement;
-  e.value = text;
-}
-
-function getCppOutputValue(): string {
-  let e : HTMLTextAreaElement = document.getElementById('TestWasm-CppOutput') as HTMLTextAreaElement;
-  return e.value;
-}
-
-function SendFreeTextFromCpp(txt: string):string
-{
-  setCppOutputValue(getCppOutputValue() + "\n" + txt);
-  return "";
-}
-(<any> window).SendFreeTextFromCpp = SendFreeTextFromCpp;
-
-var referenceMessages = Array<any>();
-
-function testTsCppTs() {
-  var r = new TestStoneCodeGen.Message2();
-  r.memberEnumMovieType = TestStoneCodeGen.MovieType.RomCom;
-  r.memberStringWithDefault = "overriden";
-  r.memberMapEnumFloat[TestStoneCodeGen.CrispType.CreamAndChives] = 0.5;
-  r.memberString = "reference-messsage2-test1";
-
-  referenceMessages[r.memberString] = r;
-  var strMsg2 = r.StoneSerialize();
-  let SendMessageToCppForEchoLocal = (<any> window).Module.cwrap('SendMessageToCppForEcho', 'string', ['string']);
-  SendMessageToCppForEchoLocal(strMsg2);
-}
-
-class MyEchoHandler implements TestStoneCodeGen.IHandler
-{
-  public HandleMessage2(value:  TestStoneCodeGen.Message2): boolean
-  {
-    if (value.memberString in referenceMessages) {
-      let r = referenceMessages[value.memberString];
-      let equals = (value.memberStringWithDefault == r.memberStringWithDefault);
-      if (TestStoneCodeGen.CrispType.CreamAndChives in r.memberMapEnumFloat) {
-        equals == equals && r.memberMapEnumFloat[TestStoneCodeGen.CrispType.CreamAndChives] == value.memberMapEnumFloat[TestStoneCodeGen.CrispType.CreamAndChives];
-      }
-      // TODO continue comparison
-
-      if (equals) {
-        console.log("objects are equals after round trip");
-        return true;
-      }
-    }
-    console.log("problem after round trip");
-    return true;
-  }
-}
-
-function SendMessageFromCpp(txt: string):string
-{
-  setCppOutputValue(getCppOutputValue() + "\n" + txt);
-  TestStoneCodeGen.StoneDispatchToHandler(txt, new MyEchoHandler());
-  return "";
-}
-(<any> window).SendMessageFromCpp = SendMessageFromCpp;
-
-
-
-function ButtonClick(buttonName: string) {
-  if (buttonName.startsWith('Test ')) {
-    setSerializedInputValue(stockSerializedMessages[buttonName]);
-  }
-  else if (buttonName == "Test-ts-cpp-ts") {
-    testTsCppTs();
-  }
-  else if(buttonName == 'Trigger')
-  {
-    let serializedInputValue:string = getSerializedInputValue();
-
-    let SendMessageToCppLocal = (<any> window).Module.cwrap('SendMessageToCpp', 'string', ['string']);
-    SendMessageToCppLocal(serializedInputValue);
-  }
-  else if(buttonName == 'Clear')
-  {
-    setCppOutputValue("");
-  }
-  else if(buttonName == 'ShowSchema')
-  {
-    setCppOutputValue(schemaText);
-  }
-  else
-  {
-    throw new Error("Internal error!");
-  }
-}
-
-
-
-// this method is called "from the C++ code" when the StoneApplication is updated.
-// it can be used to update the UI of the application
-function UpdateWebApplicationWithString(statusUpdateMessageString: string) {
-  console.log("updating web application (string): ", statusUpdateMessageString);
-  let statusUpdateMessage = JSON.parse(statusUpdateMessageString);
-
-  if ("event" in statusUpdateMessage)
-  {
-    let eventName = statusUpdateMessage["event"];
-    if (eventName == "appStatusUpdated")
-    {
-      //ui.onAppStatusUpdated(statusUpdateMessage["data"]);
-    }
-  }
-}
-
-
-function UpdateWebApplicationWithSerializedMessage(statusUpdateMessageString: string) {
-  console.log("updating web application (serialized message): ", statusUpdateMessageString);
-  console.log("<not supported!>");
-}
- 
\ No newline at end of file
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/test_data/test2.yaml	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-enum EnumMonth0:
-  - January
-  - February
-  - Month
-
-struct Message1:
-  a: int32
-  b: string
-  c: EnumMonth0
-  d: bool
-
-struct Message2:
-  toto: string
-  tata: vector<Message1>
-  tutu: vector<string>
-  titi: map<string, string>
-  lulu: map<string, Message1>
--- a/OrthancStone/Resources/Graveyard/Deprecated/Resources/CodeGeneration/test_data/testTestStoneCodeGen.yaml	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-#
-#        1         2         3         4         5         6         7         8
-# 345678901234567890123456789012345678901234567890123456789012345678901234567890
-#
-rootName: TestStoneCodeGen
-
-struct B:
-  __handler: cpp
-
-  someAs: vector<A>
-  someInts: vector<int32>
-
-struct C:
-  __handler: cpp
-
-  someBs: vector<B>
-  ddd:    vector<string>
-
-struct A:
-  __handler: cpp
-
-  someStrings: vector<string>
-  someInts2: vector<int32>
-  movies: vector<MovieType>
-
-struct Message1:
-  __handler: cpp
-
-  memberInt32: int32
-  memberString: string
-  memberEnumMonth: EnumMonth0
-  memberBool: bool
-  memberFloat32: float32
-  memberFloat64: float64
-
-struct Message2:
-  __handler: [cpp, ts]
-
-  memberString: string
-  memberStringWithDefault: string = "my-default-value"
-  memberVectorOfMessage1: vector<Message1>
-  memberVectorOfString: vector<string>
-  memberMapStringString: map<string, string>
-  memberMapStringStruct: map<string, Message1>
-  memberMapEnumFloat: map<CrispType, float32>
-  memberEnumMovieType: MovieType
-  memberJson: json
-
-enum MovieType:
-  - RomCom
-  - Horror
-  - ScienceFiction
-  - Vegetables
-
-enum CrispType:
-  - SaltAndPepper
-  - CreamAndChives
-  - Paprika
-  - Barbecue
-
-enum EnumMonth0:
-  - January
-  - February
-  - March
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/MultiPlatform/BasicScene/BasicScene.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,275 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "BasicScene.h"
-
-// From Stone
-#include "Framework/Scene2D/Scene2D.h"
-#include "Framework/Scene2D/ColorTextureSceneLayer.h"
-#include "Framework/Scene2D/PolylineSceneLayer.h"
-#include "Framework/Scene2D/TextSceneLayer.h"
-
-#include "Framework/Scene2D/PanSceneTracker.h"
-#include "Framework/Scene2D/ZoomSceneTracker.h"
-#include "Framework/Scene2D/RotateSceneTracker.h"
-
-#include "Framework/Scene2D/CairoCompositor.h"
-
-// From Orthanc framework
-#include <Core/Images/Image.h>
-#include <Core/Images/ImageProcessing.h>
-#include <Core/Images/PngWriter.h>
-
-using namespace OrthancStone;
-
-const unsigned int BASIC_SCENE_FONT_SIZE = 32;
-const int BASIC_SCENE_LAYER_POSITION = 150;
-
-void PrepareScene(Scene2D& scene)
-{
-  //Scene2D& scene(*controller->GetScene());
-  // Texture of 2x2 size
-  {
-    Orthanc::Image i(Orthanc::PixelFormat_RGB24, 2, 2, false);
-
-    uint8_t *p = reinterpret_cast<uint8_t*>(i.GetRow(0));
-    p[0] = 255;
-    p[1] = 0;
-    p[2] = 0;
-
-    p[3] = 0;
-    p[4] = 255;
-    p[5] = 0;
-
-    p = reinterpret_cast<uint8_t*>(i.GetRow(1));
-    p[0] = 0;
-    p[1] = 0;
-    p[2] = 255;
-
-    p[3] = 255;
-    p[4] = 0;
-    p[5] = 0;
-
-    scene.SetLayer(12, new ColorTextureSceneLayer(i));
-
-    std::unique_ptr<ColorTextureSceneLayer> l(new ColorTextureSceneLayer(i));
-    l->SetOrigin(-3, 2);
-    l->SetPixelSpacing(1.5, 1);
-    l->SetAngle(20.0 / 180.0 * 3.14);
-    scene.SetLayer(14, l.release());
-  }
-
-  // Texture of 1x1 size
-  {
-    Orthanc::Image i(Orthanc::PixelFormat_RGB24, 1, 1, false);
-
-    uint8_t *p = reinterpret_cast<uint8_t*>(i.GetRow(0));
-    p[0] = 255;
-    p[1] = 0;
-    p[2] = 0;
-
-    std::unique_ptr<ColorTextureSceneLayer> l(new ColorTextureSceneLayer(i));
-    l->SetOrigin(-2, 1);
-    l->SetAngle(20.0 / 180.0 * 3.14);
-    scene.SetLayer(13, l.release());
-  }
-
-  // Some lines
-  {
-    std::unique_ptr<PolylineSceneLayer> layer(new PolylineSceneLayer);
-
-    layer->SetThickness(1);
-
-    PolylineSceneLayer::Chain chain;
-    chain.push_back(ScenePoint2D(0 - 0.5, 0 - 0.5));
-    chain.push_back(ScenePoint2D(0 - 0.5, 2 - 0.5));
-    chain.push_back(ScenePoint2D(2 - 0.5, 2 - 0.5));
-    chain.push_back(ScenePoint2D(2 - 0.5, 0 - 0.5));
-    layer->AddChain(chain, true, 255, 0, 0);
-
-    chain.clear();
-    chain.push_back(ScenePoint2D(-5, -5));
-    chain.push_back(ScenePoint2D(5, -5));
-    chain.push_back(ScenePoint2D(5, 5));
-    chain.push_back(ScenePoint2D(-5, 5));
-    layer->AddChain(chain, true, 0, 255, 0);
-
-    double dy = 1.01;
-    chain.clear();
-    chain.push_back(ScenePoint2D(-4, -4));
-    chain.push_back(ScenePoint2D(4, -4 + dy));
-    chain.push_back(ScenePoint2D(-4, -4 + 2.0 * dy));
-    chain.push_back(ScenePoint2D(4, 2));
-    layer->AddChain(chain, false, 0, 0, 255);
-
-    //    layer->SetColor(0,255, 255);
-    scene.SetLayer(50, layer.release());
-  }
-
-  // Some text
-  {
-    std::unique_ptr<TextSceneLayer> layer(new TextSceneLayer);
-    layer->SetText("Hello");
-    scene.SetLayer(100, layer.release());
-  }
-}
-
-#if ORTHANC_SANDBOXED == 0
-void TakeScreenshot(const std::string& target,
-                    const OrthancStone::Scene2D& scene,
-                    unsigned int canvasWidth,
-                    unsigned int canvasHeight)
-{
-  using namespace OrthancStone;
-  // Take a screenshot, then save it as PNG file
-  CairoCompositor compositor(scene, canvasWidth, canvasHeight);
-  compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, BASIC_SCENE_FONT_SIZE, Orthanc::Encoding_Latin1);
-  compositor.Refresh();
-
-  Orthanc::ImageAccessor canvas;
-  compositor.GetCanvas().GetReadOnlyAccessor(canvas);
-
-  Orthanc::Image png(Orthanc::PixelFormat_RGB24, canvas.GetWidth(), canvas.GetHeight(), false);
-  Orthanc::ImageProcessing::Convert(png, canvas);
-
-  Orthanc::PngWriter writer;
-  writer.WriteToFile(target, png);
-}
-#endif
-
-void ShowCursorInfo(Scene2D& scene, const PointerEvent& pointerEvent)
-{
-  ScenePoint2D p = pointerEvent.GetMainPosition().Apply(scene.GetCanvasToSceneTransform());
-
-  char buf[64];
-  sprintf(buf, "(%0.02f,%0.02f)", p.GetX(), p.GetY());
-
-  if (scene.HasLayer(BASIC_SCENE_LAYER_POSITION))
-  {
-    TextSceneLayer& layer =
-        dynamic_cast<TextSceneLayer&>(scene.GetLayer(BASIC_SCENE_LAYER_POSITION));
-    layer.SetText(buf);
-    layer.SetPosition(p.GetX(), p.GetY());
-  }
-  else
-  {
-    std::unique_ptr<TextSceneLayer>
-        layer(new TextSceneLayer);
-    layer->SetColor(0, 255, 0);
-    layer->SetText(buf);
-    layer->SetBorder(20);
-    layer->SetAnchor(BitmapAnchor_BottomCenter);
-    layer->SetPosition(p.GetX(), p.GetY());
-    scene.SetLayer(BASIC_SCENE_LAYER_POSITION, layer.release());
-  }
-}
-
-
-
-bool BasicScene2DInteractor::OnMouseEvent(const GuiAdapterMouseEvent& event, const PointerEvent& pointerEvent)
-{
-  if (currentTracker_.get() != NULL)
-  {
-    switch (event.type)
-    {
-    case GUIADAPTER_EVENT_MOUSEUP:
-    {
-      currentTracker_->PointerUp(pointerEvent);
-      if (!currentTracker_->IsAlive())
-      {
-        currentTracker_.reset();
-      }
-    };break;
-    case GUIADAPTER_EVENT_MOUSEMOVE:
-    {
-      currentTracker_->PointerMove(pointerEvent);
-    };break;
-    default:
-      return false;
-    }
-    return true;
-  }
-  else if (event.type == GUIADAPTER_EVENT_MOUSEDOWN)
-  {
-    if (event.button == GUIADAPTER_MOUSEBUTTON_LEFT)
-    {
-      currentTracker_.reset(new RotateSceneTracker(viewportController_, pointerEvent));
-    }
-    else if (event.button == GUIADAPTER_MOUSEBUTTON_MIDDLE)
-    {
-      currentTracker_.reset(new PanSceneTracker(viewportController_, pointerEvent));
-    }
-    else if (event.button == GUIADAPTER_MOUSEBUTTON_RIGHT)
-    {
-      currentTracker_.reset(new ZoomSceneTracker(viewportController_, pointerEvent, viewportController_->GetViewport().GetCanvasHeight()));
-    }
-  }
-  else if (event.type == GUIADAPTER_EVENT_MOUSEMOVE)
-  {
-    if (showCursorInfo_)
-    {
-      Scene2D& scene(viewportController_->GetScene());
-      ShowCursorInfo(scene, pointerEvent);
-    }
-    return true;
-  }
-  return false;
-}
-
-bool BasicScene2DInteractor::OnKeyboardEvent(const GuiAdapterKeyboardEvent& guiEvent)
-{
-  if (guiEvent.type == GUIADAPTER_EVENT_KEYDOWN)
-  {
-    switch (guiEvent.sym[0])
-    {
-    case 's':
-    {
-      //viewportController_->FitContent(viewportController_->GetViewport().GetCanvasWidth(), viewportController_->GetViewport().GetCanvasHeight());
-      viewportController_->FitContent();
-      return true;
-    };
-#if ORTHANC_SANDBOXED == 0
-    case 'c':
-    {
-      Scene2D& scene(viewportController_->GetScene());
-      TakeScreenshot("screenshot.png", scene, viewportController_->GetViewport().GetCanvasWidth(), viewportController_->GetViewport().GetCanvasHeight());
-      return true;
-    }
-#endif
-    case 'd':
-    {
-      showCursorInfo_ = !showCursorInfo_;
-      if (!showCursorInfo_)
-      {
-        Scene2D& scene(viewportController_->GetScene());
-        scene.DeleteLayer(BASIC_SCENE_LAYER_POSITION);
-      }
-
-      return true;
-    }
-    }
-  }
-  return false;
-}
-
-bool BasicScene2DInteractor::OnWheelEvent(const GuiAdapterWheelEvent& guiEvent)
-{
-  return false;
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/MultiPlatform/BasicScene/BasicScene.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#pragma once
-
-#include <boost/shared_ptr.hpp>
-#include "Framework/Scene2DViewport/ViewportController.h"
-#include "Framework/Scene2D/Scene2D.h"
-
-extern const unsigned int BASIC_SCENE_FONT_SIZE;
-extern const int BASIC_SCENE_LAYER_POSITION;
-
-extern void PrepareScene(OrthancStone::Scene2D& scene);
-extern void TakeScreenshot(const std::string& target,
-                           const OrthancStone::Scene2D& scene,
-                           unsigned int canvasWidth,
-                           unsigned int canvasHeight);
-
-
-#include "Applications/Generic/Scene2DInteractor.h"
-#include "Framework/Scene2DViewport/IFlexiblePointerTracker.h"
-
-
-class BasicScene2DInteractor : public OrthancStone::Scene2DInteractor
-{
-  boost::shared_ptr<OrthancStone::IFlexiblePointerTracker>  currentTracker_;
-  bool                                                      showCursorInfo_;
-public:
-  BasicScene2DInteractor(boost::shared_ptr<OrthancStone::ViewportController> viewportController) :
-    Scene2DInteractor(viewportController),
-    showCursorInfo_(false)
-  {}
-
-  virtual bool OnMouseEvent(const OrthancStone::GuiAdapterMouseEvent& event, const OrthancStone::PointerEvent& pointerEvent) override;
-  virtual bool OnKeyboardEvent(const OrthancStone::GuiAdapterKeyboardEvent& guiEvent) override;
-  virtual bool OnWheelEvent(const OrthancStone::GuiAdapterWheelEvent& guiEvent) override;
-};
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/MultiPlatform/BasicScene/mainQt.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#define GLEW_STATIC 1
-// From Stone
-#include "../../Framework/OpenGL/OpenGLIncludes.h"
-#include "../../Applications/Sdl/SdlWindow.h"
-#include "../../Framework/Scene2D/CairoCompositor.h"
-#include "../../Framework/Scene2D/ColorTextureSceneLayer.h"
-#include "../../Framework/Scene2D/OpenGLCompositor.h"
-#include "../../Framework/Scene2D/PanSceneTracker.h"
-#include "../../Framework/Scene2D/RotateSceneTracker.h"
-#include "../../Framework/Scene2D/Scene2D.h"
-#include "../../Framework/Scene2D/ZoomSceneTracker.h"
-#include "../../Framework/Scene2DViewport/ViewportController.h"
-#include "../../Framework/Scene2DViewport/UndoStack.h"
-
-#include "../../Framework/StoneInitialization.h"
-#include "../../Framework/Messages/MessageBroker.h"
-
-// From Orthanc framework
-#include <Core/Logging.h>
-#include <Core/OrthancException.h>
-#include <Core/Images/Image.h>
-#include <Core/Images/ImageProcessing.h>
-#include <Core/Images/PngWriter.h>
-
-#include <boost/make_shared.hpp>
-#include <boost/ref.hpp>
-#include "EmbeddedResources.h"
-
-#include <stdio.h>
-#include <QDebug>
-#include <QWindow>
-
-#include "BasicScene.h"
-
-
-using namespace OrthancStone;
-
-
-
-static void GLAPIENTRY OpenGLMessageCallback(GLenum source,
-                                             GLenum type,
-                                             GLuint id,
-                                             GLenum severity,
-                                             GLsizei length,
-                                             const GLchar* message,
-                                             const void* userParam )
-{
-  if (severity != GL_DEBUG_SEVERITY_NOTIFICATION)
-  {
-    fprintf(stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n",
-            ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ),
-            type, severity, message );
-  }
-}
-
-extern void InitGL();
-
-#include <QApplication>
-#include "BasicSceneWindow.h"
-
-int main(int argc, char* argv[])
-{
-  QApplication a(argc, argv);
-
-  OrthancStone::Samples::BasicSceneWindow window;
-  window.show();
-  window.GetOpenGlWidget().Init();
-
-  MessageBroker broker;
-  boost::shared_ptr<UndoStack> undoStack(new UndoStack);
-  boost::shared_ptr<ViewportController> controller = boost::make_shared<ViewportController>(undoStack, boost::ref(broker), window.GetOpenGlWidget());
-  PrepareScene(controller->GetScene());
-
-  window.GetOpenGlWidget().GetCompositor().SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT,
-                     BASIC_SCENE_FONT_SIZE, Orthanc::Encoding_Latin1);
-
-  boost::shared_ptr<OrthancStone::Scene2DInteractor> interactor(new BasicScene2DInteractor(controller));
-  window.GetOpenGlWidget().SetInteractor(interactor);
-
-  controller->FitContent();
-
-  return a.exec();
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/MultiPlatform/BasicScene/mainSdl.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,199 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-// From Stone
-#include "Framework/Viewport/SdlViewport.h"
-#include "Framework/Scene2D/OpenGLCompositor.h"
-#include "Framework/Scene2DViewport/UndoStack.h"
-#include "Framework/StoneInitialization.h"
-#include "Framework/Messages/MessageBroker.h"
-
-// From Orthanc framework
-#include <Core/Logging.h>
-#include <Core/OrthancException.h>
-
-#include <boost/make_shared.hpp>
-#include <boost/ref.hpp>
-
-#include <SDL.h>
-#include <stdio.h>
-
-
-#include "BasicScene.h"
-
-using namespace OrthancStone;
-
-boost::shared_ptr<BasicScene2DInteractor> interactor;
-
-void HandleApplicationEvent(boost::shared_ptr<OrthancStone::ViewportController> controller,
-                            const SDL_Event& event)
-{
-  using namespace OrthancStone;
-  Scene2D& scene(controller->GetScene());
-  if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP || event.type == SDL_MOUSEMOTION)
-  {
-    // TODO: this code is copy/pasted from GuiAdapter::Run() -> find the right place
-    int scancodeCount = 0;
-    const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount);
-    bool ctrlPressed(false);
-    bool shiftPressed(false);
-    bool altPressed(false);
-
-    if (SDL_SCANCODE_LCTRL < scancodeCount && keyboardState[SDL_SCANCODE_LCTRL])
-      ctrlPressed = true;
-    if (SDL_SCANCODE_RCTRL < scancodeCount && keyboardState[SDL_SCANCODE_RCTRL])
-      ctrlPressed = true;
-    if (SDL_SCANCODE_LSHIFT < scancodeCount && keyboardState[SDL_SCANCODE_LSHIFT])
-      shiftPressed = true;
-    if (SDL_SCANCODE_RSHIFT < scancodeCount && keyboardState[SDL_SCANCODE_RSHIFT])
-      shiftPressed = true;
-    if (SDL_SCANCODE_LALT < scancodeCount && keyboardState[SDL_SCANCODE_LALT])
-      altPressed = true;
-
-    GuiAdapterMouseEvent guiEvent;
-    ConvertFromPlatform(guiEvent, ctrlPressed, shiftPressed, altPressed, event);
-    PointerEvent pointerEvent;
-    pointerEvent.AddPosition(controller->GetViewport().GetPixelCenterCoordinates(event.button.x, event.button.y));
-
-    interactor->OnMouseEvent(guiEvent, pointerEvent);
-    return;
-  }
-  else if ((event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) && event.key.repeat == 0  /* Ignore key bounce */)
-  {
-    GuiAdapterKeyboardEvent guiEvent;
-    ConvertFromPlatform(guiEvent, event);
-
-    interactor->OnKeyboardEvent(guiEvent);
-  }
-
-}
-
-
-static void GLAPIENTRY
-OpenGLMessageCallback(GLenum source,
-                      GLenum type,
-                      GLuint id,
-                      GLenum severity,
-                      GLsizei length,
-                      const GLchar* message,
-                      const void* userParam )
-{
-  if (severity != GL_DEBUG_SEVERITY_NOTIFICATION)
-  {
-    fprintf(stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n",
-            ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ),
-            type, severity, message );
-  }
-}
-
-
-void Run(boost::shared_ptr<OrthancStone::ViewportController> controller)
-{
-  SdlViewport& sdlViewport = dynamic_cast<SdlViewport&>(controller->GetViewport());
-
-  glEnable(GL_DEBUG_OUTPUT);
-  glDebugMessageCallback(OpenGLMessageCallback, 0);
-
-  controller->GetViewport().GetCompositor().SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT,
-                     BASIC_SCENE_FONT_SIZE, Orthanc::Encoding_Latin1);
-
-  controller->GetViewport().Refresh();
-  controller->FitContent();
-
-
-  bool stop = false;
-  while (!stop)
-  {
-    controller->GetViewport().Refresh();
-
-    SDL_Event event;
-    while (!stop &&
-           SDL_PollEvent(&event))
-    {
-      if (event.type == SDL_QUIT)
-      {
-        stop = true;
-        break;
-      }
-      else if (event.type == SDL_WINDOWEVENT &&
-               event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
-      {
-        sdlViewport.UpdateSize(event.window.data1, event.window.data2);
-      }
-      else if (event.type == SDL_KEYDOWN &&
-               event.key.repeat == 0 /* Ignore key bounce */)
-      {
-        switch (event.key.keysym.sym)
-        {
-          case SDLK_f:
-            sdlViewport.GetWindow().ToggleMaximize();
-            break;
-              
-          case SDLK_q:
-            stop = true;
-            break;
-
-          default:
-            break;
-        }
-      }
-      
-      HandleApplicationEvent(controller, event);
-    }
-
-    SDL_Delay(1);
-  }
-  interactor.reset();
-}
-
-
-
-
-/**
- * IMPORTANT: The full arguments to "main()" are needed for SDL on
- * Windows. Otherwise, one gets the linking error "undefined reference
- * to `SDL_main'". https://wiki.libsdl.org/FAQWindows
- **/
-int main(int argc, char* argv[])
-{
-  using namespace OrthancStone;
-  StoneInitialize();
-  Orthanc::Logging::EnableInfoLevel(true);
-
-  try
-  {
-    SdlOpenGLViewport viewport("Hello", 1024, 768);
-    MessageBroker broker;
-    boost::shared_ptr<UndoStack> undoStack(new UndoStack);
-    boost::shared_ptr<ViewportController> controller = boost::make_shared<ViewportController>(undoStack, boost::ref(broker), boost::ref(viewport));
-    interactor.reset(new BasicScene2DInteractor(controller));
-    PrepareScene(controller->GetScene());
-    Run(controller);
-  }
-  catch (Orthanc::OrthancException& e)
-  {
-    LOG(ERROR) << "EXCEPTION: " << e.What();
-  }
-
-  StoneFinalize();
-
-  return 0;
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/Qt/BasicSceneWindow.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "../../Framework/OpenGL/OpenGLIncludes.h"
-#include "BasicSceneWindow.h"
-
-/**
- * Don't use "ui_MainWindow.h" instead of <ui_MainWindow.h> below, as
- * this makes CMake unable to detect when the UI file changes.
- **/
-#include <ui_BasicSceneWindow.h>
-#include "../../Applications/Samples/SampleApplicationBase.h"
-
-namespace OrthancStone
-{
-  namespace Samples
-  {
-
-    BasicSceneWindow::BasicSceneWindow(
-      QWidget *parent) :
-      ui_(new Ui::BasicSceneWindow)
-    {
-      ui_->setupUi(this);
-    }
-
-    BasicSceneWindow::~BasicSceneWindow()
-    {
-      delete ui_;
-    }
-
-    QStoneOpenGlWidget& BasicSceneWindow::GetOpenGlWidget()
-    {
-      return *(ui_->centralWidget);
-    }
-
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/Qt/BasicSceneWindow.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-#include <QMainWindow>
-#include <QStoneOpenGlWidget.h>
-// #include "../../Qt/QCairoWidget.h"
-// #include "../../Qt/QStoneMainWindow.h"
-
-namespace Ui 
-{
-  class BasicSceneWindow;
-}
-
-namespace OrthancStone
-{
-  namespace Samples
-  {
-
-    //class SampleSingleCanvasApplicationBase;
-
-    class BasicSceneWindow : public QMainWindow
-    {
-      Q_OBJECT
-
-    private:
-      Ui::BasicSceneWindow*   ui_;
-      //SampleSingleCanvasApplicationBase&  stoneSampleApplication_;
-
-    public:
-      explicit BasicSceneWindow(QWidget *parent = 0);
-      ~BasicSceneWindow();
-
-      QStoneOpenGlWidget& GetOpenGlWidget();
-    };
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/Qt/BasicSceneWindow.ui	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>BasicSceneWindow</class>
- <widget class="QMainWindow" name="BasicSceneWindow">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>903</width>
-    <height>634</height>
-   </rect>
-  </property>
-  <property name="minimumSize">
-   <size>
-    <width>500</width>
-    <height>300</height>
-   </size>
-  </property>
-  <property name="baseSize">
-   <size>
-    <width>500</width>
-    <height>300</height>
-   </size>
-  </property>
-  <property name="windowTitle">
-   <string>Stone of Orthanc</string>
-  </property>
-  <property name="layoutDirection">
-   <enum>Qt::LeftToRight</enum>
-  </property>
-  <widget class="QWidget" name="mainWidget">
-   <property name="sizePolicy">
-    <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-     <horstretch>0</horstretch>
-     <verstretch>0</verstretch>
-    </sizepolicy>
-   </property>
-   <property name="layoutDirection">
-    <enum>Qt::LeftToRight</enum>
-   </property>
-   <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0">
-    <property name="sizeConstraint">
-     <enum>QLayout::SetDefaultConstraint</enum>
-    </property>
-    <item>
-     <widget class="OrthancStone::QStoneOpenGlWidget" name="centralWidget" native="true">
-      <property name="minimumSize">
-       <size>
-        <width>0</width>
-        <height>500</height>
-       </size>
-      </property>
-     </widget>
-    </item>
-   </layout>
-  </widget>
-  <widget class="QMenuBar" name="menubar">
-   <property name="geometry">
-    <rect>
-     <x>0</x>
-     <y>0</y>
-     <width>903</width>
-     <height>21</height>
-    </rect>
-   </property>
-   <widget class="QMenu" name="menuTest">
-    <property name="title">
-     <string>Test</string>
-    </property>
-   </widget>
-   <addaction name="menuTest"/>
-  </widget>
-  <widget class="QStatusBar" name="statusbar"/>
- </widget>
- <customwidgets>
-  <customwidget>
-   <class>QStoneOpenGlWidget</class>
-   <extends>QWidget</extends>
-   <header location="global">QStoneOpenGlWidget.h</header>
-  </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/Qt/CMakeLists.txt	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-cmake_minimum_required(VERSION 2.8.3)
-
-#####################################################################
-## Configuration of the Orthanc framework
-#####################################################################
-
-# This CMake file defines the "ORTHANC_STONE_VERSION" macro, so it
-# must be the first inclusion
-include(${CMAKE_SOURCE_DIR}/../../Resources/CMake/Version.cmake)
-
-if (ORTHANC_STONE_VERSION STREQUAL "mainline")
-  set(ORTHANC_FRAMEWORK_VERSION "mainline")
-  set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "hg")
-else()
-  set(ORTHANC_FRAMEWORK_VERSION "1.5.7")
-  set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "web")
-endif()
-
-set(ORTHANC_FRAMEWORK_SOURCE "${ORTHANC_FRAMEWORK_DEFAULT_SOURCE}" CACHE STRING "Source of the Orthanc source code (can be \"hg\", \"archive\", \"web\" or \"path\")")
-set(ORTHANC_FRAMEWORK_ARCHIVE "" CACHE STRING "Path to the Orthanc archive, if ORTHANC_FRAMEWORK_SOURCE is \"archive\"")
-set(ORTHANC_FRAMEWORK_ROOT "" CACHE STRING "Path to the Orthanc source directory, if ORTHANC_FRAMEWORK_SOURCE is \"path\"")
-
-
-#####################################################################
-## Configuration of the Stone framework
-#####################################################################
-
-include(${CMAKE_SOURCE_DIR}/../../Resources/CMake/OrthancStoneParameters.cmake)
-include(${ORTHANC_ROOT}/Resources/CMake/DownloadPackage.cmake)
-
-DownloadPackage(
-  "a24b8136b8f3bb93f166baf97d9328de"
-  "http://orthanc.osimis.io/ThirdPartyDownloads/ubuntu-font-family-0.83.zip"
-  "${CMAKE_BINARY_DIR}/ubuntu-font-family-0.83")
-
-set(ORTHANC_STONE_APPLICATION_RESOURCES
-  UBUNTU_FONT  ${CMAKE_BINARY_DIR}/ubuntu-font-family-0.83/Ubuntu-R.ttf
-  )
-
-SET(ENABLE_GOOGLE_TEST OFF)
-SET(ENABLE_LOCALE ON)
-SET(ENABLE_QT ON)
-SET(ENABLE_SDL OFF)
-SET(ENABLE_WEB_CLIENT ON)
-SET(ORTHANC_SANDBOXED OFF)
-LIST(APPEND ORTHANC_BOOST_COMPONENTS program_options)
-
-include(${CMAKE_SOURCE_DIR}/../../Resources/CMake/OrthancStoneConfiguration.cmake)
-
-add_definitions(
-  -DORTHANC_ENABLE_LOGGING_PLUGIN=0
-  )
-#####################################################################
-## Build the samples
-#####################################################################
-
-add_library(OrthancStone STATIC
-  ${ORTHANC_STONE_SOURCES}
-  )
-
-list(APPEND BASIC_SCENE_APPLICATIONS_SOURCES
-  BasicSceneWindow.cpp
-  )
-
-ORTHANC_QT_WRAP_UI(BASIC_SCENE_APPLICATIONS_SOURCES
-  BasicSceneWindow.ui
-  )
-
-ORTHANC_QT_WRAP_CPP(BASIC_SCENE_APPLICATIONS_SOURCES
-  BasicSceneWindow.h
-  QStoneOpenGlWidget.h
-  )
-
-add_executable(MpBasicScene
-  ${CMAKE_CURRENT_LIST_DIR}/../MultiPlatform/BasicScene/BasicScene.h
-  ${CMAKE_CURRENT_LIST_DIR}/../MultiPlatform/BasicScene/BasicScene.cpp
-  ${CMAKE_CURRENT_LIST_DIR}/../MultiPlatform/BasicScene/mainQt.cpp
-  QStoneOpenGlWidget.cpp
-  ${BASIC_SCENE_APPLICATIONS_SOURCES}
-  )
-
-target_include_directories(MpBasicScene PUBLIC ${CMAKE_SOURCE_DIR} ${ORTHANC_STONE_ROOT})
-target_link_libraries(MpBasicScene OrthancStone)
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/Qt/QStoneOpenGlWidget.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,192 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "../../Framework/OpenGL/OpenGLIncludes.h"
-#include "QStoneOpenGlWidget.h"
-
-#include <QMouseEvent>
-
-using namespace OrthancStone;
-
-void QStoneOpenGlWidget::initializeGL()
-{
-  glewInit();
-}
-
-void QStoneOpenGlWidget::MakeCurrent()
-{
-  this->makeCurrent();
-}
-
-void QStoneOpenGlWidget::resizeGL(int w, int h)
-{
-
-}
-
-void QStoneOpenGlWidget::paintGL()
-{
-  if (compositor_)
-  {
-    compositor_->Refresh();
-  }
-  doneCurrent();
-}
-
-void ConvertFromPlatform(
-    OrthancStone::GuiAdapterMouseEvent& guiEvent,
-    PointerEvent& pointerEvent,
-    const QMouseEvent& qtEvent,
-    const IViewport& viewport)
-{
-  guiEvent.targetX = qtEvent.x();
-  guiEvent.targetY = qtEvent.y();
-  pointerEvent.AddPosition(viewport.GetPixelCenterCoordinates(guiEvent.targetX, guiEvent.targetY));
-
-  switch (qtEvent.button())
-  {
-  case Qt::LeftButton: guiEvent.button = OrthancStone::GUIADAPTER_MOUSEBUTTON_LEFT; break;
-  case Qt::MiddleButton: guiEvent.button = OrthancStone::GUIADAPTER_MOUSEBUTTON_MIDDLE; break;
-  case Qt::RightButton: guiEvent.button = OrthancStone::GUIADAPTER_MOUSEBUTTON_RIGHT; break;
-  default:
-    guiEvent.button = OrthancStone::GUIADAPTER_MOUSEBUTTON_LEFT;
-  }
-
-  if (qtEvent.modifiers().testFlag(Qt::ShiftModifier))
-  {
-    guiEvent.shiftKey = true;
-  }
-  if (qtEvent.modifiers().testFlag(Qt::ControlModifier))
-  {
-    guiEvent.ctrlKey = true;
-  }
-  if (qtEvent.modifiers().testFlag(Qt::AltModifier))
-  {
-    guiEvent.altKey = true;
-  }
-}
-
-void QStoneOpenGlWidget::mouseEvent(QMouseEvent* qtEvent, OrthancStone::GuiAdapterHidEventType guiEventType)
-{
-  OrthancStone::GuiAdapterMouseEvent guiEvent;
-  PointerEvent pointerEvent;
-  ConvertFromPlatform(guiEvent, pointerEvent, *qtEvent, *this);
-  guiEvent.type = guiEventType;
-
-  if (sceneInteractor_.get() != NULL && compositor_.get() != NULL)
-  {
-    sceneInteractor_->OnMouseEvent(guiEvent, pointerEvent);
-  }
-
-  // force redraw of the OpenGL widget
-  update();
-}
-
-void QStoneOpenGlWidget::mousePressEvent(QMouseEvent* qtEvent)
-{
-  mouseEvent(qtEvent, GUIADAPTER_EVENT_MOUSEDOWN);
-}
-
-void QStoneOpenGlWidget::mouseMoveEvent(QMouseEvent* qtEvent)
-{
-  mouseEvent(qtEvent, GUIADAPTER_EVENT_MOUSEMOVE);
-}
-
-void QStoneOpenGlWidget::mouseReleaseEvent(QMouseEvent* qtEvent)
-{
-  mouseEvent(qtEvent, GUIADAPTER_EVENT_MOUSEUP);
-}
-
-void ConvertFromPlatform(
-    OrthancStone::GuiAdapterKeyboardEvent& guiEvent,
-    const QKeyEvent& qtEvent)
-{
-  if (qtEvent.text().length() > 0)
-  {
-    guiEvent.sym[0] = qtEvent.text()[0].cell();
-  }
-  else
-  {
-    guiEvent.sym[0] = 0;
-  }
-  guiEvent.sym[1] = 0;
-
-  if (qtEvent.modifiers().testFlag(Qt::ShiftModifier))
-  {
-    guiEvent.shiftKey = true;
-  }
-  if (qtEvent.modifiers().testFlag(Qt::ControlModifier))
-  {
-    guiEvent.ctrlKey = true;
-  }
-  if (qtEvent.modifiers().testFlag(Qt::AltModifier))
-  {
-    guiEvent.altKey = true;
-  }
-
-}
-
-
-bool QStoneOpenGlWidget::keyEvent(QKeyEvent* qtEvent, OrthancStone::GuiAdapterHidEventType guiEventType)
-{
-  bool handled = false;
-  OrthancStone::GuiAdapterKeyboardEvent guiEvent;
-  ConvertFromPlatform(guiEvent, *qtEvent);
-  guiEvent.type = guiEventType;
-
-  if (sceneInteractor_.get() != NULL && compositor_.get() != NULL)
-  {
-    handled = sceneInteractor_->OnKeyboardEvent(guiEvent);
-
-    if (handled)
-    {
-      // force redraw of the OpenGL widget
-      update();
-    }
-  }
-  return handled;
-}
-
-void QStoneOpenGlWidget::keyPressEvent(QKeyEvent *qtEvent)
-{
-  bool handled = keyEvent(qtEvent, GUIADAPTER_EVENT_KEYDOWN);
-  if (!handled)
-  {
-    QOpenGLWidget::keyPressEvent(qtEvent);
-  }
-}
-
-void QStoneOpenGlWidget::keyReleaseEvent(QKeyEvent *qtEvent)
-{
-  bool handled = keyEvent(qtEvent, GUIADAPTER_EVENT_KEYUP);
-  if (!handled)
-  {
-    QOpenGLWidget::keyPressEvent(qtEvent);
-  }
-}
-
-void QStoneOpenGlWidget::wheelEvent(QWheelEvent *qtEvent)
-{
-  OrthancStone::GuiAdapterWheelEvent guiEvent;
-  throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
-
-  // force redraw of the OpenGL widget
-  update();
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/Qt/QStoneOpenGlWidget.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-#include "../../Framework/OpenGL/OpenGLIncludes.h"
-#include <QOpenGLWidget>
-#include <QOpenGLFunctions>
-#include <QOpenGLContext>
-
-#include <boost/shared_ptr.hpp>
-#include "../../Framework/OpenGL/IOpenGLContext.h"
-#include "../../Framework/Scene2D/OpenGLCompositor.h"
-#include "../../Framework/Viewport/ViewportBase.h"
-#include "../../Applications/Generic/Scene2DInteractor.h"
-
-namespace OrthancStone
-{
-  class QStoneOpenGlWidget :
-      public QOpenGLWidget,
-      public OpenGL::IOpenGLContext,
-      public ViewportBase
-  {
-    std::unique_ptr<OrthancStone::OpenGLCompositor> compositor_;
-    boost::shared_ptr<Scene2DInteractor> sceneInteractor_;
-    QOpenGLContext                        openGlContext_;
-
-  public:
-    QStoneOpenGlWidget(QWidget *parent) :
-      QOpenGLWidget(parent),
-      ViewportBase("QtStoneOpenGlWidget")  // TODO: we shall be able to define a name but construction time is too early !
-    {
-      setFocusPolicy(Qt::StrongFocus);  // to enable keyPressEvent
-      setMouseTracking(true);           // to enable mouseMoveEvent event when no button is pressed
-    }
-
-    void Init()
-    {
-      QSurfaceFormat requestedFormat;
-      requestedFormat.setVersion( 2, 0 );
-      openGlContext_.setFormat( requestedFormat );
-      openGlContext_.create();
-      openGlContext_.makeCurrent(context()->surface());
-
-      compositor_.reset(new OpenGLCompositor(*this, GetScene()));
-    }
-
-  protected:
-
-    //**** QWidget overrides
-    void initializeGL() override;
-    void resizeGL(int w, int h) override;
-    void paintGL() override;
-
-    void mousePressEvent(QMouseEvent* event) override;
-    void mouseMoveEvent(QMouseEvent* event) override;
-    void mouseReleaseEvent(QMouseEvent* event) override;
-    void keyPressEvent(QKeyEvent* event) override;
-    void keyReleaseEvent(QKeyEvent *event) override;
-    void wheelEvent(QWheelEvent* event) override;
-
-    //**** IOpenGLContext overrides
-
-    virtual void MakeCurrent() override;
-    virtual void SwapBuffer() override {}
-
-    virtual unsigned int GetCanvasWidth() const override
-    {
-      return this->width();
-    }
-
-    virtual unsigned int GetCanvasHeight() const override
-    {
-      return this->height();
-    }
-
-  public:
-
-    void SetInteractor(boost::shared_ptr<Scene2DInteractor> sceneInteractor)
-    {
-      sceneInteractor_ = sceneInteractor;
-    }
-
-    virtual ICompositor& GetCompositor()
-    {
-      return *compositor_;
-    }
-
-  protected:
-    void mouseEvent(QMouseEvent* qtEvent, OrthancStone::GuiAdapterHidEventType guiEventType);
-    bool keyEvent(QKeyEvent* qtEvent, OrthancStone::GuiAdapterHidEventType guiEventType);
-
-  };
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/Qt/Scene2DInteractor.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "Scene2DInteractor.h"
-
-#include "../../Framework/Scene2D/PanSceneTracker.h"
-#include "../../Framework/Scene2D/ZoomSceneTracker.h"
-#include "../../Framework/Scene2D/RotateSceneTracker.h"
-
-
-namespace OrthancStone
-{
-
-}
-
-using namespace OrthancStone;
-
-
-bool BasicScene2DInteractor::OnMouseEvent(const GuiAdapterMouseEvent& event, const PointerEvent& pointerEvent)
-{
-  if (currentTracker_.get() != NULL)
-  {
-    switch (event.type)
-    {
-    case GUIADAPTER_EVENT_MOUSEUP:
-    {
-      currentTracker_->PointerUp(pointerEvent);
-      if (!currentTracker_->IsAlive())
-      {
-        currentTracker_.reset();
-      }
-    };break;
-    case GUIADAPTER_EVENT_MOUSEMOVE:
-    {
-      currentTracker_->PointerMove(pointerEvent);
-    };break;
-    }
-    return true;
-  }
-  else
-  {
-    if (event.button == GUIADAPTER_MOUSEBUTTON_LEFT)
-    {
-      currentTracker_.reset(new RotateSceneTracker(viewportController_, pointerEvent));
-    }
-    else if (event.button == GUIADAPTER_MOUSEBUTTON_MIDDLE)
-    {
-      currentTracker_.reset(new PanSceneTracker(viewportController_, pointerEvent));
-    }
-    else if (event.button == GUIADAPTER_MOUSEBUTTON_RIGHT && compositor_.get() != NULL)
-    {
-      currentTracker_.reset(new ZoomSceneTracker(viewportController_, pointerEvent, compositor_->GetHeight()));
-    }
-    return true;
-  }
-  return false;
-}
-
-bool BasicScene2DInteractor::OnKeyboardEvent(const GuiAdapterKeyboardEvent& guiEvent)
-{
-  switch (guiEvent.sym[0])
-  {
-  case 's':
-  {
-    viewportController_->FitContent(compositor_->GetWidth(), compositor_->GetHeight());
-    return true;
-  };
-  }
-  return false;
-}
-
-bool BasicScene2DInteractor::OnWheelEvent(const GuiAdapterWheelEvent& guiEvent)
-{
-  return false;
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/Qt/Scene2DInteractor.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Applications/Generic/Scene2DInteractor.h"
-#include "../../Framework/Scene2DViewport/IFlexiblePointerTracker.h"
-
-
-class BasicScene2DInteractor : public OrthancStone::Scene2DInteractor
-{
-  boost::shared_ptr<OrthancStone::IFlexiblePointerTracker>  currentTracker_;
-public:
-  BasicScene2DInteractor(boost::shared_ptr<OrthancStone::ViewportController> viewportController) :
-    Scene2DInteractor(viewportController)
-  {}
-
-  virtual bool OnMouseEvent(const OrthancStone::GuiAdapterMouseEvent& event, const OrthancStone::PointerEvent& pointerEvent) override;
-  virtual bool OnKeyboardEvent(const OrthancStone::GuiAdapterKeyboardEvent& guiEvent);
-  virtual bool OnWheelEvent(const OrthancStone::GuiAdapterWheelEvent& guiEvent);
-};
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/README.md	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-
-**These samples are deprecated and not guaranteed to work. A migration to a 
-new version of the Stone API is underway.**
-
-Please read orthanc-stone/OrthancStone/Samples/README.md first for general requirements.
-
-
-
-Deprecated -- to be sorted
-===========================
-
-The following assumes that the source code to be downloaded in
-`~/orthanc-stone` and Orthanc source code to be checked out in
-`~/orthanc`. 
-
-Building the WASM samples
--------------------------------------
-
-```
-cd ~/orthanc-stone/Applications/Samples
-./build-wasm.sh
-```
-
-Serving the WASM samples
-------------------------------------
-```
-# launch an Orthanc listening on 8042 port:
-Orthanc
-
-# launch an nginx that will serve the WASM static files and reverse
-# proxy
-sudo nginx -p $(pwd) -c nginx.local.conf
-```
-
-You can now open the samples in http://localhost:9977
-
-Building the SDL native samples (SimpleViewer only)
----------------------------------------------------
-
-The following also assumes that you have checked out the Orthanc
-source code in an `orthanc` folder next to the Stone of Orthanc
-repository, please enter the following:
-
-**Simple make generator with dynamic build**
-
-```
-# Please set $currentDir to the current folder
-mkdir -p ~/builds/orthanc-stone-build
-cd ~/builds/orthanc-stone-build
-cmake -DORTHANC_FRAMEWORK_SOURCE=path \
-    -DORTHANC_FRAMEWORK_ROOT=$currentDir/../../../orthanc \
-    -DALLOW_DOWNLOADS=ON -DENABLE_SDL=ON \
-    ~/orthanc-stone/Applications/Samples/
-```
-
-**Ninja generator with static SDL build (pwsh script)**
-
-```
-# Please yourself one level above the orthanc-stone and orthanc folders
-if( -not (test-path stone_build_sdl)) { mkdir stone_build_sdl }
-cd stone_build_sdl
-cmake -G Ninja -DSTATIC_BUILD=ON -DOPENSSL_NO_CAPIENG=ON -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT="$($pwd)\..\orthanc" -DALLOW_DOWNLOADS=ON -DENABLE_SDL=ON ../orthanc-stone/Applications/Samples/
-```
-
-**Ninja generator with static SDL build (bash/zsh script)**
-
-```
-# Please yourself one level above the orthanc-stone and orthanc folders
-if( -not (test-path stone_build_sdl)) { mkdir stone_build_sdl }
-cd stone_build_sdl
-cmake -G Ninja -DSTATIC_BUILD=ON -DOPENSSL_NO_CAPIENG=ON -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT="`pwd`/../orthanc" -DALLOW_DOWNLOADS=ON -DENABLE_SDL=ON ../orthanc-stone/Applications/Samples/
-```
-
-**Visual Studio 2017 generator with static SDL build  (pwsh script)**
-
-```
-# The following will use Visual Studio 2017 to build the SDL samples
-# in debug mode (with multiple compilers in parallel). NOTE: place 
-# yourself one level above the `orthanc-stone` and `orthanc` folders
-
-if( -not (test-path stone_build_sdl)) { mkdir stone_build_sdl }
-cd stone_build_sdl
-cmake -G "Visual Studio 15 2017 Win64" -DMSVC_MULTIPLE_PROCESSES=ON -DSTATIC_BUILD=ON -DOPENSSL_NO_CAPIENG=ON -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT="$($pwd)\..\orthanc" -DALLOW_DOWNLOADS=ON -DENABLE_SDL=ON ../orthanc-stone/Applications/Samples/
-cmake --build . --config Debug
-```
-
-If you are working on Windows, add the correct generator option to
-cmake to, for instance, generate msbuild files for Visual Studio.
-
-Then, under Linux:
-```
-cmake --build . --target OrthancStoneSimpleViewer -- -j 5
-```
-
-Note: replace `$($pwd)` with the current directory when not using Powershell
-
-Building the Qt native samples (SimpleViewer only) under Windows:
-------------------------------------------------------------------
-
-**Visual Studio 2017 generator with static Qt build  (pwsh script)**
-
-For instance, if Qt is installed in `C:\Qt\5.12.0\msvc2017_64`
-
-```
-# The following will use Visual Studio 2017 to build the SDL samples
-# in debug mode (with multiple compilers in parallel). NOTE: place 
-# yourself one level above the `orthanc-stone` and `orthanc` folders
-
-if( -not (test-path stone_build_qt)) { mkdir stone_build_qt }
-cd stone_build_qt
-cmake -G "Visual Studio 15 2017 Win64" -DMSVC_MULTIPLE_PROCESSES=ON -DSTATIC_BUILD=ON -DOPENSSL_NO_CAPIENG=ON -DCMAKE_PREFIX_PATH=C:\Qt\5.12.0\msvc2017_64 -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT="$($pwd)\..\orthanc" -DALLOW_DOWNLOADS=ON -DENABLE_QT=ON  ../orthanc-stone/Applications/Samples/
-cmake --build . --config Debug
-```
-
-Note: replace `$($pwd)` with the current directory when not using Powershell
-
-
-
-
-
-
-Building the SDL native samples (SimpleViewer only) under Windows:
-------------------------------------------------------------------
-`cmake -DSTATIC_BUILD=ON -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT="$($pwd)\..\orthanc" -DALLOW_DOWNLOADS=ON -DENABLE_SDL=ON -G "Visual Studio 15 2017 Win64" ../orthanc-stone/Applications/Samples/`
-
-Note: replace `$($pwd)` with the current directory when not using Powershell
-
-Executing the native samples:
---------------------------------
-```
-# launch an Orthanc listening on 8042 port:
-Orthanc
-
-# launch the sample
-./OrthancStoneSimpleViewer --studyId=XX
-``` 
-
-Build the Application Samples
------------------------------
-
-**Visual Studio 2008 (v90) **
-
-```
-cmake -G "Visual Studio 9 2008" -DUSE_LEGACY_JSONCPP=ON -DENABLE_OPENGL=ON -DSTATIC_BUILD=ON -DOPENSSL_NO_CAPIENG=ON -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT="$($pwd)\..\orthanc" -DALLOW_DOWNLOADS=ON -DENABLE_SDL=ON ../orthanc-stone/Applications/Samples
-```
-
-**Visual Studio 2019 (v142) **
-
-```
-cmake -G "Visual Studio 16 2019" -A x64 -DMSVC_MULTIPLE_PROCESSES=ON -DENABLE_OPENGL=ON -DSTATIC_BUILD=ON -DOPENSSL_NO_CAPIENG=ON -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT="$($pwd)\..\orthanc" -DALLOW_DOWNLOADS=ON -DENABLE_SDL=ON ../orthanc-stone/Applications/Samples
-```
-
-**Visual Studio 2017 (v140) **
-
-```
-cmake -G "Visual Studio 15 2017 Win64" -DMSVC_MULTIPLE_PROCESSES=ON -DENABLE_OPENGL=ON -DSTATIC_BUILD=ON -DOPENSSL_NO_CAPIENG=ON -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT="$($pwd)\..\orthanc" -DALLOW_DOWNLOADS=ON -DENABLE_SDL=ON ../orthanc-stone/Applications/Samples
-```
-
-
-Build the core Samples
----------------------------
-How to build the newest (2019-04-29) SDL samples under Windows, *inside* a
-folder that is sibling to the orthanc-stone folder: 
-
-**Visual Studio 2019 (v142) **
-
-```
-cmake -G "Visual Studio 16 2019" -A x64 -DMSVC_MULTIPLE_PROCESSES=ON -DENABLE_OPENGL=ON -DSTATIC_BUILD=ON -DOPENSSL_NO_CAPIENG=ON -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT="$($pwd)\..\orthanc" -DALLOW_DOWNLOADS=ON -DENABLE_SDL=ON ../orthanc-stone/OrthancStone/Samples/Sdl
-```
-
-**Visual Studio 2017 (v140) **
-
-```
-cmake -G "Visual Studio 15 2017 Win64" -DMSVC_MULTIPLE_PROCESSES=ON -DENABLE_OPENGL=ON -DSTATIC_BUILD=ON -DOPENSSL_NO_CAPIENG=ON -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT="$($pwd)\..\orthanc" -DALLOW_DOWNLOADS=ON -DENABLE_SDL=ON ../orthanc-stone/OrthancStone/Samples/Sdl
-```
-
-**Visual Studio 2008 (v90) **
-
-```
-cmake -G "Visual Studio 9 2008" -DUSE_LEGACY_JSONCPP=ON -DENABLE_OPENGL=ON -DSTATIC_BUILD=ON -DOPENSSL_NO_CAPIENG=ON -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT="$($pwd)\..\orthanc" -DALLOW_DOWNLOADS=ON -DENABLE_SDL=ON ../orthanc-stone/OrthancStone/Samples/Sdl
-```
-
-And under Ubuntu (note the /mnt/c/osi/dev/orthanc folder):
-```
-cmake -G "Ninja" -DENABLE_OPENGL=ON -DSTATIC_BUILD=OFF -DOPENSSL_NO_CAPIENG=ON -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT="/mnt/c/osi/dev/orthanc" -DALLOW_DOWNLOADS=ON -DENABLE_SDL=ON ../orthanc-stone/OrthancStone/Samples/Sdl
-```
-
-TODO trackers:
-- CANCELLED (using outlined text now) text overlay 50% --> ColorTextureLayer 50%
-- DONE angle tracker: draw arcs
-- Handles on arc
-- Select measure tool with hit test --> Delete command
-
-
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/Sdl/BasicScene.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,418 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-// From Stone
-#include "../../Framework/Viewport/SdlViewport.h"
-#include "../../Framework/Scene2D/CairoCompositor.h"
-#include "../../Framework/Scene2D/ColorTextureSceneLayer.h"
-#include "../../Framework/Scene2D/OpenGLCompositor.h"
-#include "../../Framework/Scene2D/PanSceneTracker.h"
-#include "../../Framework/Scene2D/RotateSceneTracker.h"
-#include "../../Framework/Scene2D/ZoomSceneTracker.h"
-#include "../../Framework/Scene2DViewport/ViewportController.h"
-#include "../../Framework/Scene2DViewport/UndoStack.h"
-
-#include "../../Framework/StoneInitialization.h"
-#include "../../Framework/Messages/MessageBroker.h"
-
-// From Orthanc framework
-#include <Core/Logging.h>
-#include <Core/OrthancException.h>
-#include <Core/Images/Image.h>
-#include <Core/Images/ImageProcessing.h>
-#include <Core/Images/PngWriter.h>
-
-#include <boost/make_shared.hpp>
-
-#include <SDL.h>
-#include <stdio.h>
-
-static const unsigned int FONT_SIZE = 32;
-static const int LAYER_POSITION = 150;
-
-#define OPENGL_ENABLED 0
-
-void PrepareScene(OrthancStone::Scene2D& scene)
-{
-  using namespace OrthancStone;
-
-  // Texture of 2x2 size
-  {
-    Orthanc::Image i(Orthanc::PixelFormat_RGB24, 2, 2, false);
-    
-    uint8_t *p = reinterpret_cast<uint8_t*>(i.GetRow(0));
-    p[0] = 255;
-    p[1] = 0;
-    p[2] = 0;
-
-    p[3] = 0;
-    p[4] = 255;
-    p[5] = 0;
-
-    p = reinterpret_cast<uint8_t*>(i.GetRow(1));
-    p[0] = 0;
-    p[1] = 0;
-    p[2] = 255;
-
-    p[3] = 255;
-    p[4] = 0;
-    p[5] = 0;
-
-    scene.SetLayer(12, new ColorTextureSceneLayer(i));
-
-    std::unique_ptr<ColorTextureSceneLayer> l(new ColorTextureSceneLayer(i));
-    l->SetOrigin(-3, 2);
-    l->SetPixelSpacing(1.5, 1);
-    l->SetAngle(20.0 / 180.0 * M_PI);
-    scene.SetLayer(14, l.release());
-  }
-
-  // Texture of 1x1 size
-  {
-    Orthanc::Image i(Orthanc::PixelFormat_RGB24, 1, 1, false);
-    
-    uint8_t *p = reinterpret_cast<uint8_t*>(i.GetRow(0));
-    p[0] = 255;
-    p[1] = 0;
-    p[2] = 0;
-
-    std::unique_ptr<ColorTextureSceneLayer> l(new ColorTextureSceneLayer(i));
-    l->SetOrigin(-2, 1);
-    l->SetAngle(20.0 / 180.0 * M_PI);
-    scene.SetLayer(13, l.release());
-  }
-
-  // Some lines
-  {
-    std::unique_ptr<PolylineSceneLayer> layer(new PolylineSceneLayer);
-
-    layer->SetThickness(10);
-
-    PolylineSceneLayer::Chain chain;
-    chain.push_back(ScenePoint2D(0 - 0.5, 0 - 0.5));
-    chain.push_back(ScenePoint2D(0 - 0.5, 2 - 0.5));
-    chain.push_back(ScenePoint2D(2 - 0.5, 2 - 0.5));
-    chain.push_back(ScenePoint2D(2 - 0.5, 0 - 0.5));
-    layer->AddChain(chain, true, 255, 0, 0);
-
-    chain.clear();
-    chain.push_back(ScenePoint2D(-5, -5));
-    chain.push_back(ScenePoint2D(5, -5));
-    chain.push_back(ScenePoint2D(5, 5));
-    chain.push_back(ScenePoint2D(-5, 5));
-    layer->AddChain(chain, true, 0, 255, 0);
-
-    double dy = 1.01;
-    chain.clear();
-    chain.push_back(ScenePoint2D(-4, -4));
-    chain.push_back(ScenePoint2D(4, -4 + dy));
-    chain.push_back(ScenePoint2D(-4, -4 + 2.0 * dy));
-    chain.push_back(ScenePoint2D(4, 2));
-    layer->AddChain(chain, false, 0, 0, 255);
-
-    scene.SetLayer(50, layer.release());
-  }
-
-  // Some text
-  {
-    std::unique_ptr<TextSceneLayer> layer(new TextSceneLayer);
-    layer->SetText("Hello");
-    scene.SetLayer(100, layer.release());
-  }
-}
-
-
-void TakeScreenshot(const std::string& target,
-                    const OrthancStone::Scene2D& scene,
-                    unsigned int canvasWidth,
-                    unsigned int canvasHeight)
-{
-  using namespace OrthancStone;
-  // Take a screenshot, then save it as PNG file
-  CairoCompositor compositor(scene, canvasWidth, canvasHeight);
-  compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, FONT_SIZE, Orthanc::Encoding_Latin1);
-  compositor.Refresh();
-
-  Orthanc::ImageAccessor canvas;
-  compositor.GetCanvas().GetReadOnlyAccessor(canvas);
-
-  Orthanc::Image png(Orthanc::PixelFormat_RGB24, canvas.GetWidth(), canvas.GetHeight(), false);
-  Orthanc::ImageProcessing::Convert(png, canvas);
-        
-  Orthanc::PngWriter writer;
-  writer.WriteToFile(target, png);
-}
-
-
-void HandleApplicationEvent(const SDL_Event& event,
-                            boost::shared_ptr<OrthancStone::ViewportController>& controller,
-                            boost::shared_ptr<OrthancStone::IFlexiblePointerTracker>& activeTracker)
-{
-  using namespace OrthancStone;
-
-  Scene2D& scene = controller->GetScene();
-  IViewport& viewport = controller->GetViewport();
-
-  if (event.type == SDL_MOUSEMOTION)
-  {
-    int scancodeCount = 0;
-    const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount);
-
-    if (activeTracker.get() == NULL &&
-        SDL_SCANCODE_LCTRL < scancodeCount &&
-        keyboardState[SDL_SCANCODE_LCTRL])
-    {
-      // The "left-ctrl" key is down, while no tracker is present
-
-      PointerEvent e;
-      e.AddPosition(viewport.GetPixelCenterCoordinates(event.button.x, event.button.y));
-
-      ScenePoint2D p = e.GetMainPosition().Apply(scene.GetCanvasToSceneTransform());
-
-      char buf[64];
-      sprintf(buf, "(%0.02f,%0.02f)", p.GetX(), p.GetY());
-
-      if (scene.HasLayer(LAYER_POSITION))
-      {
-        TextSceneLayer& layer =
-          dynamic_cast<TextSceneLayer&>(scene.GetLayer(LAYER_POSITION));
-        layer.SetText(buf);
-        layer.SetPosition(p.GetX(), p.GetY());
-      }
-      else
-      {
-        std::unique_ptr<TextSceneLayer> 
-          layer(new TextSceneLayer);
-        layer->SetColor(0, 255, 0);
-        layer->SetText(buf);
-        layer->SetBorder(20);
-        layer->SetAnchor(BitmapAnchor_BottomCenter);
-        layer->SetPosition(p.GetX(), p.GetY());
-        scene.SetLayer(LAYER_POSITION, layer.release());
-      }
-    }
-    else
-    {
-      scene.DeleteLayer(LAYER_POSITION);
-    }
-  }
-  else if (event.type == SDL_MOUSEBUTTONDOWN)
-  {
-    PointerEvent e;
-    e.AddPosition(viewport.GetPixelCenterCoordinates(event.button.x, event.button.y));
-
-    switch (event.button.button)
-    {
-      case SDL_BUTTON_MIDDLE:
-        activeTracker = boost::make_shared<PanSceneTracker>(controller, e);
-        break;
-
-      case SDL_BUTTON_RIGHT:
-        activeTracker = boost::make_shared<ZoomSceneTracker>
-          (controller, e, viewport.GetCanvasHeight());
-        break;
-
-      case SDL_BUTTON_LEFT:
-        activeTracker = boost::make_shared<RotateSceneTracker>(controller, e);
-        break;
-
-      default:
-        break;
-    }
-  }
-  else if (event.type == SDL_KEYDOWN &&
-           event.key.repeat == 0 /* Ignore key bounce */)
-  {
-    switch (event.key.keysym.sym)
-    {
-      case SDLK_s:
-        controller->FitContent(viewport.GetCanvasWidth(), 
-                               viewport.GetCanvasHeight());
-        break;
-              
-      case SDLK_c:
-        TakeScreenshot("screenshot.png", scene, 
-                       viewport.GetCanvasWidth(), 
-                       viewport.GetCanvasHeight());
-        break;
-              
-      default:
-        break;
-    }
-  }
-}
-
-#if OPENGL_ENABLED==1
-static void GLAPIENTRY
-OpenGLMessageCallback(GLenum source,
-                      GLenum type,
-                      GLuint id,
-                      GLenum severity,
-                      GLsizei length,
-                      const GLchar* message,
-                      const void* userParam )
-{
-  if (severity != GL_DEBUG_SEVERITY_NOTIFICATION)
-  {
-    fprintf(stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n",
-            ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ),
-            type, severity, message );
-  }
-}
-#endif
-
-void Run(OrthancStone::MessageBroker& broker,
-         OrthancStone::SdlViewport& viewport)
-{
-  using namespace OrthancStone;
-  
-  boost::shared_ptr<ViewportController> controller(
-    new ViewportController(boost::make_shared<UndoStack>(), broker, viewport));
-  
-#if OPENGL_ENABLED==1
-  glEnable(GL_DEBUG_OUTPUT);
-  glDebugMessageCallback(OpenGLMessageCallback, 0);
-#endif
-
-  boost::shared_ptr<IFlexiblePointerTracker> tracker;
-
-  bool firstShown = true;
-  bool stop = false;
-  while (!stop)
-  {
-    viewport.Refresh();
-
-    SDL_Event event;
-    while (!stop &&
-           SDL_PollEvent(&event))
-    {
-      if (event.type == SDL_QUIT)
-      {
-        stop = true;
-        break;
-      }
-      else if (event.type == SDL_MOUSEMOTION)
-      {
-        if (tracker)
-        {
-          PointerEvent e;
-          e.AddPosition(viewport.GetPixelCenterCoordinates(
-            event.button.x, event.button.y));
-          tracker->PointerMove(e);
-        }
-      }
-      else if (event.type == SDL_MOUSEBUTTONUP)
-      {
-        if (tracker)
-        {
-          PointerEvent e;
-          e.AddPosition(viewport.GetPixelCenterCoordinates(
-            event.button.x, event.button.y));
-          tracker->PointerUp(e);
-          if(!tracker->IsAlive())
-            tracker.reset();
-        }
-      }
-      else if (event.type == SDL_WINDOWEVENT)
-      {
-        switch (event.window.event)
-        {
-          case SDL_WINDOWEVENT_SIZE_CHANGED:
-            tracker.reset();
-            viewport.UpdateSize(event.window.data1, event.window.data2);
-            break;
-
-          case SDL_WINDOWEVENT_SHOWN:
-            if (firstShown)
-            {
-              // Once the window is first shown, fit the content to its size
-              controller->FitContent(viewport.GetCanvasWidth(), viewport.GetCanvasHeight());
-              firstShown = false;
-            }
-            
-            break;
-
-          default:
-            break;
-        }
-      }
-      else if (event.type == SDL_KEYDOWN &&
-               event.key.repeat == 0 /* Ignore key bounce */)
-      {
-        switch (event.key.keysym.sym)
-        {
-          case SDLK_f:
-            viewport.GetWindow().ToggleMaximize();
-            break;
-              
-          case SDLK_q:
-            stop = true;
-            break;
-
-          default:
-            break;
-        }
-      }
-      
-      HandleApplicationEvent(event, controller, tracker);
-    }
-
-    SDL_Delay(1);
-  }
-}
-
-
-
-
-/**
- * IMPORTANT: The full arguments to "main()" are needed for SDL on
- * Windows. Otherwise, one gets the linking error "undefined reference
- * to `SDL_main'". https://wiki.libsdl.org/FAQWindows
- **/
-int main(int argc, char* argv[])
-{
-  OrthancStone::StoneInitialize();
-  Orthanc::Logging::EnableInfoLevel(true);
-
-  try
-  {
-#if OPENGL_ENABLED==1
-    OrthancStone::SdlOpenGLViewport viewport("Hello", 1024, 768);
-#else
-    OrthancStone::SdlCairoViewport viewport("Hello", 1024, 768);
-#endif
-    PrepareScene(viewport.GetScene());
-
-    viewport.GetCompositor().SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, 
-                                     FONT_SIZE, Orthanc::Encoding_Latin1);
-    
-    OrthancStone::MessageBroker broker;
-    Run(broker, viewport);
-  }
-  catch (Orthanc::OrthancException& e)
-  {
-    LOG(ERROR) << "EXCEPTION: " << e.What();
-  }
-
-  OrthancStone::StoneFinalize();
-
-  return 0;
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/Sdl/CMakeLists.txt	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-cmake_minimum_required(VERSION 2.8.3)
-
-#####################################################################
-## Configuration of the Orthanc framework
-#####################################################################
-
-# This CMake file defines the "ORTHANC_STONE_VERSION" macro, so it
-# must be the first inclusion
-include(${CMAKE_SOURCE_DIR}/../../Resources/CMake/Version.cmake)
-
-if (ORTHANC_STONE_VERSION STREQUAL "mainline")
-  set(ORTHANC_FRAMEWORK_VERSION "mainline")
-  set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "hg")
-else()
-  set(ORTHANC_FRAMEWORK_VERSION "1.5.7")
-  set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "web")
-endif()
-
-set(ORTHANC_FRAMEWORK_SOURCE "${ORTHANC_FRAMEWORK_DEFAULT_SOURCE}" CACHE STRING "Source of the Orthanc source code (can be \"hg\", \"archive\", \"web\" or \"path\")")
-set(ORTHANC_FRAMEWORK_ARCHIVE "" CACHE STRING "Path to the Orthanc archive, if ORTHANC_FRAMEWORK_SOURCE is \"archive\"")
-set(ORTHANC_FRAMEWORK_ROOT "" CACHE STRING "Path to the Orthanc source directory, if ORTHANC_FRAMEWORK_SOURCE is \"path\"")
-
-
-#####################################################################
-## Configuration of the Stone framework
-#####################################################################
-
-include(${CMAKE_SOURCE_DIR}/../../Resources/CMake/OrthancStoneParameters.cmake)
-include(${ORTHANC_ROOT}/Resources/CMake/DownloadPackage.cmake)
-
-DownloadPackage(
-  "a24b8136b8f3bb93f166baf97d9328de"
-  "http://orthanc.osimis.io/ThirdPartyDownloads/ubuntu-font-family-0.83.zip"
-  "${CMAKE_BINARY_DIR}/ubuntu-font-family-0.83")
-
-set(ORTHANC_STONE_APPLICATION_RESOURCES
-  UBUNTU_FONT  ${CMAKE_BINARY_DIR}/ubuntu-font-family-0.83/Ubuntu-R.ttf
-  )
-
-SET(ENABLE_SDL_CONSOLE OFF CACHE BOOL "Enable the use of the MIT-licensed SDL_Console")
-SET(ENABLE_GOOGLE_TEST OFF)
-SET(ENABLE_LOCALE ON)
-SET(ENABLE_SDL ON)
-SET(ENABLE_WEB_CLIENT ON)
-SET(ORTHANC_SANDBOXED OFF)
-LIST(APPEND ORTHANC_BOOST_COMPONENTS program_options)
-
-include(${CMAKE_SOURCE_DIR}/../../Resources/CMake/OrthancStoneConfiguration.cmake)
-
-add_definitions(
-  -DORTHANC_ENABLE_LOGGING_PLUGIN=0
-  )
-
-
-#####################################################################
-## Build the samples
-#####################################################################
-
-add_library(OrthancStone STATIC
-  ${ORTHANC_STONE_SOURCES}
-  )
-
-#
-# BasicScene
-# 
-
-add_executable(BasicScene
-  BasicScene.cpp
-  )
-
-target_link_libraries(BasicScene OrthancStone)
-
-#
-# TrackerSample
-# 
-
-LIST(APPEND TRACKERSAMPLE_SOURCE "TrackerSample.cpp")
-LIST(APPEND TRACKERSAMPLE_SOURCE "TrackerSampleApp.cpp")
-LIST(APPEND TRACKERSAMPLE_SOURCE "TrackerSampleApp.h")
-
-if (MSVC AND MSVC_VERSION GREATER 1700)
-  LIST(APPEND TRACKERSAMPLE_SOURCE "cpp.hint")
-endif()
-
-add_executable(TrackerSample
-  ${TRACKERSAMPLE_SOURCE}
-  )
-
-target_link_libraries(TrackerSample OrthancStone)
-
-#
-# Loader
-# 
-
-add_executable(Loader
-  Loader.cpp
-  )
-
-target_link_libraries(Loader OrthancStone)
-
-#
-# FusionMprSdl
-# 
-
-add_executable(FusionMprSdl
-  FusionMprSdl.cpp
-  FusionMprSdl.h
-)
-
-target_link_libraries(FusionMprSdl OrthancStone)
-
-#
-# Multiplatform Basic Scene
-#
-
-LIST(APPEND MP_BASIC_SCENE_SOURCE "../MultiPlatform/BasicScene/BasicScene.cpp")
-LIST(APPEND MP_BASIC_SCENE_SOURCE "../MultiPlatform/BasicScene/BasicScene.h")
-LIST(APPEND MP_BASIC_SCENE_SOURCE "../MultiPlatform/BasicScene/mainSdl.cpp")
-
-if (MSVC AND MSVC_VERSION GREATER 1700)
-  LIST(APPEND MP_BASIC_SCENE_SOURCE "cpp.hint")
-endif()
-
-add_executable(MpBasicScene
-  ${MP_BASIC_SCENE_SOURCE}
-  )
-
-target_include_directories(MpBasicScene PUBLIC ${ORTHANC_STONE_ROOT})
-target_link_libraries(MpBasicScene OrthancStone)
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/Sdl/FusionMprSdl.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,805 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "FusionMprSdl.h"
-
-#include "../../Framework/OpenGL/SdlOpenGLContext.h"
-
-#include "../../Framework/StoneInitialization.h"
-
-#include "../../Framework/Scene2D/CairoCompositor.h"
-#include "../../Framework/Scene2D/ColorTextureSceneLayer.h"
-#include "../../Framework/Scene2D/OpenGLCompositor.h"
-#include "../../Framework/Scene2D/PanSceneTracker.h"
-#include "../../Framework/Scene2D/ZoomSceneTracker.h"
-#include "../../Framework/Scene2D/RotateSceneTracker.h"
-
-#include "../../Framework/Scene2DViewport/UndoStack.h"
-#include "../../Framework/Scene2DViewport/CreateLineMeasureTracker.h"
-#include "../../Framework/Scene2DViewport/CreateAngleMeasureTracker.h"
-#include "../../Framework/Scene2DViewport/IFlexiblePointerTracker.h"
-#include "../../Framework/Scene2DViewport/MeasureTool.h"
-#include "../../Framework/Scene2DViewport/PredeclaredTypes.h"
-
-#include "../../Framework/Volumes/VolumeSceneLayerSource.h"
-
-#include <Core/Images/Image.h>
-#include <Core/Images/ImageProcessing.h>
-#include <Core/Images/PngWriter.h>
-#include <Core/Logging.h>
-#include <Core/OrthancException.h>
-
-#include <boost/shared_ptr.hpp>
-#include <boost/weak_ptr.hpp>
-#include <boost/make_shared.hpp>
-
-#include <stdio.h>
-#include "../../Framework/Oracle/GetOrthancWebViewerJpegCommand.h"
-#include "../../Framework/Oracle/ThreadedOracle.h"
-#include "../../Framework/Loaders/OrthancSeriesVolumeProgressiveLoader.h"
-#include "../../Framework/Loaders/OrthancMultiframeVolumeLoader.h"
-#include "../../Framework/Loaders/DicomStructureSetLoader.h"
-#include "../../Framework/Scene2D/GrayscaleStyleConfigurator.h"
-#include "../../Framework/Scene2D/LookupTableStyleConfigurator.h"
-#include "../../Framework/Volumes/DicomVolumeImageMPRSlicer.h"
-#include "Core/SystemToolbox.h"
-
-namespace OrthancStone
-{
-  const char* FusionMprMeasureToolToString(size_t i)
-  {
-    static const char* descs[] = {
-      "FusionMprGuiTool_Rotate",
-      "FusionMprGuiTool_Pan",
-      "FusionMprGuiTool_Zoom",
-      "FusionMprGuiTool_LineMeasure",
-      "FusionMprGuiTool_CircleMeasure",
-      "FusionMprGuiTool_AngleMeasure",
-      "FusionMprGuiTool_EllipseMeasure",
-      "FusionMprGuiTool_LAST"
-    };
-    if (i >= FusionMprGuiTool_LAST)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, "Wrong tool index");
-    }
-    return descs[i];
-  }
-
-  Scene2D& FusionMprSdlApp::GetScene()
-  {
-    return controller_->GetScene();
-  }
-
-  const Scene2D& FusionMprSdlApp::GetScene() const
-  {
-    return controller_->GetScene();
-  }
-
-  void FusionMprSdlApp::SelectNextTool()
-  {
-    currentTool_ = static_cast<FusionMprGuiTool>(currentTool_ + 1);
-    if (currentTool_ == FusionMprGuiTool_LAST)
-      currentTool_ = static_cast<FusionMprGuiTool>(0);;
-    printf("Current tool is now: %s\n", FusionMprMeasureToolToString(currentTool_));
-  }
-
-  void FusionMprSdlApp::DisplayInfoText()
-  {
-    // do not try to use stuff too early!
-    ICompositor* pCompositor = &(viewport_.GetCompositor());
-    if (pCompositor == NULL)
-      return;
-
-    std::stringstream msg;
-	
-	for (std::map<std::string, std::string>::const_iterator kv = infoTextMap_.begin();
-		kv != infoTextMap_.end(); ++kv)
-    {
-      msg << kv->first << " : " << kv->second << std::endl;
-    }
-	std::string msgS = msg.str();
-
-    TextSceneLayer* layerP = NULL;
-    if (GetScene().HasLayer(FIXED_INFOTEXT_LAYER_ZINDEX))
-    {
-      TextSceneLayer& layer = dynamic_cast<TextSceneLayer&>(
-        GetScene().GetLayer(FIXED_INFOTEXT_LAYER_ZINDEX));
-      layerP = &layer;
-    }
-    else
-    {
-      std::unique_ptr<TextSceneLayer> layer(new TextSceneLayer);
-      layerP = layer.get();
-      layer->SetColor(0, 255, 0);
-      layer->SetFontIndex(1);
-      layer->SetBorder(20);
-      layer->SetAnchor(BitmapAnchor_TopLeft);
-      //layer->SetPosition(0,0);
-      GetScene().SetLayer(FIXED_INFOTEXT_LAYER_ZINDEX, layer.release());
-    }
-    // position the fixed info text in the upper right corner
-    layerP->SetText(msgS.c_str());
-    double cX = viewport_.GetCompositor().GetCanvasWidth() * (-0.5);
-    double cY = viewport_.GetCompositor().GetCanvasHeight() * (-0.5);
-    GetScene().GetCanvasToSceneTransform().Apply(cX,cY);
-    layerP->SetPosition(cX, cY);
-  }
-
-  void FusionMprSdlApp::DisplayFloatingCtrlInfoText(const PointerEvent& e)
-  {
-    ScenePoint2D p = e.GetMainPosition().Apply(GetScene().GetCanvasToSceneTransform());
-
-    char buf[128];
-    sprintf(buf, "S:(%0.02f,%0.02f) C:(%0.02f,%0.02f)", 
-      p.GetX(), p.GetY(), 
-      e.GetMainPosition().GetX(), e.GetMainPosition().GetY());
-
-    if (GetScene().HasLayer(FLOATING_INFOTEXT_LAYER_ZINDEX))
-    {
-      TextSceneLayer& layer =
-        dynamic_cast<TextSceneLayer&>(GetScene().GetLayer(FLOATING_INFOTEXT_LAYER_ZINDEX));
-      layer.SetText(buf);
-      layer.SetPosition(p.GetX(), p.GetY());
-    }
-    else
-    {
-      std::unique_ptr<TextSceneLayer> layer(new TextSceneLayer);
-      layer->SetColor(0, 255, 0);
-      layer->SetText(buf);
-      layer->SetBorder(20);
-      layer->SetAnchor(BitmapAnchor_BottomCenter);
-      layer->SetPosition(p.GetX(), p.GetY());
-      GetScene().SetLayer(FLOATING_INFOTEXT_LAYER_ZINDEX, layer.release());
-    }
-  }
-
-  void FusionMprSdlApp::HideInfoText()
-  {
-    GetScene().DeleteLayer(FLOATING_INFOTEXT_LAYER_ZINDEX);
-  }
-
-  void FusionMprSdlApp::HandleApplicationEvent(
-    const SDL_Event & event)
-  {
-    DisplayInfoText();
-
-    if (event.type == SDL_MOUSEMOTION)
-    {
-      int scancodeCount = 0;
-      const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount);
-
-      if (activeTracker_.get() == NULL &&
-        SDL_SCANCODE_LALT < scancodeCount &&
-        keyboardState[SDL_SCANCODE_LALT])
-      {
-        // The "left-ctrl" key is down, while no tracker is present
-        // Let's display the info text
-        PointerEvent e;
-        e.AddPosition(controller_->GetViewport().GetPixelCenterCoordinates(
-          event.button.x, event.button.y));
-
-        DisplayFloatingCtrlInfoText(e);
-      }
-      else
-      {
-        HideInfoText();
-        //LOG(TRACE) << "(event.type == SDL_MOUSEMOTION)";
-        if (activeTracker_.get() != NULL)
-        {
-          //LOG(TRACE) << "(activeTracker_.get() != NULL)";
-          PointerEvent e;
-          e.AddPosition(controller_->GetViewport().GetPixelCenterCoordinates(
-            event.button.x, event.button.y));
-          
-          //LOG(TRACE) << "event.button.x = " << event.button.x << "     " <<
-          //  "event.button.y = " << event.button.y;
-          LOG(TRACE) << "activeTracker_->PointerMove(e); " <<
-            e.GetMainPosition().GetX() << " " << e.GetMainPosition().GetY();
-          
-          activeTracker_->PointerMove(e);
-          if (!activeTracker_->IsAlive())
-            activeTracker_.reset();
-        }
-      }
-    }
-    else if (event.type == SDL_MOUSEBUTTONUP)
-    {
-      if (activeTracker_)
-      {
-        PointerEvent e;
-        e.AddPosition(controller_->GetViewport().GetPixelCenterCoordinates(event.button.x, event.button.y));
-        activeTracker_->PointerUp(e);
-        if (!activeTracker_->IsAlive())
-          activeTracker_.reset();
-      }
-    }
-    else if (event.type == SDL_MOUSEBUTTONDOWN)
-    {
-      PointerEvent e;
-      e.AddPosition(controller_->GetViewport().GetPixelCenterCoordinates(
-        event.button.x, event.button.y));
-      if (activeTracker_)
-      {
-        activeTracker_->PointerDown(e);
-        if (!activeTracker_->IsAlive())
-          activeTracker_.reset();
-      }
-      else
-      {
-        // we ATTEMPT to create a tracker if need be
-        activeTracker_ = CreateSuitableTracker(event, e);
-      }
-    }
-    else if (event.type == SDL_KEYDOWN &&
-      event.key.repeat == 0 /* Ignore key bounce */)
-    {
-      switch (event.key.keysym.sym)
-      {
-      case SDLK_ESCAPE:
-        if (activeTracker_)
-        {
-          activeTracker_->Cancel();
-          if (!activeTracker_->IsAlive())
-            activeTracker_.reset();
-        }
-        break;
-
-      case SDLK_t:
-        if (!activeTracker_)
-          SelectNextTool();
-        else
-        {
-          LOG(WARNING) << "You cannot change the active tool when an interaction"
-            " is taking place";
-        }
-        break;
-      case SDLK_s:
-        controller_->FitContent(viewport_.GetCompositor().GetCanvasWidth(),
-          viewport_.GetCompositor().GetCanvasHeight());
-        break;
-
-      case SDLK_z:
-        LOG(TRACE) << "SDLK_z has been pressed. event.key.keysym.mod == " << event.key.keysym.mod;
-        if (event.key.keysym.mod & KMOD_CTRL)
-        {
-          if (controller_->CanUndo())
-          {
-            LOG(TRACE) << "Undoing...";
-            controller_->Undo();
-          }
-          else
-          {
-            LOG(WARNING) << "Nothing to undo!!!";
-          }
-        }
-        break;
-
-      case SDLK_y:
-        LOG(TRACE) << "SDLK_y has been pressed. event.key.keysym.mod == " << event.key.keysym.mod;
-        if (event.key.keysym.mod & KMOD_CTRL)
-        {
-          if (controller_->CanRedo())
-          {
-            LOG(TRACE) << "Redoing...";
-            controller_->Redo();
-          }
-          else
-          {
-            LOG(WARNING) << "Nothing to redo!!!";
-          }
-        }
-        break;
-
-      case SDLK_c:
-        TakeScreenshot(
-          "screenshot.png",
-          viewport_.GetCompositor().GetCanvasWidth(),
-          viewport_.GetCompositor().GetCanvasHeight());
-        break;
-
-      default:
-        break;
-      }
-    }
-  }
-
-
-  void FusionMprSdlApp::OnSceneTransformChanged(
-    const ViewportController::SceneTransformChanged& message)
-  {
-    DisplayInfoText();
-  }
-
-  boost::shared_ptr<IFlexiblePointerTracker> FusionMprSdlApp::CreateSuitableTracker(
-    const SDL_Event & event,
-    const PointerEvent & e)
-  {
-    using namespace Orthanc;
-
-    switch (event.button.button)
-    {
-    case SDL_BUTTON_MIDDLE:
-      return boost::shared_ptr<IFlexiblePointerTracker>(new PanSceneTracker
-        (controller_, e));
-
-    case SDL_BUTTON_RIGHT:
-      return boost::shared_ptr<IFlexiblePointerTracker>(new ZoomSceneTracker
-        (controller_, e, viewport_.GetCompositor().GetCanvasHeight()));
-
-    case SDL_BUTTON_LEFT:
-    {
-      //LOG(TRACE) << "CreateSuitableTracker: case SDL_BUTTON_LEFT:";
-      // TODO: we need to iterate on the set of measuring tool and perform
-      // a hit test to check if a tracker needs to be created for edition.
-      // Otherwise, depending upon the active tool, we might want to create
-      // a "measuring tool creation" tracker
-
-      // TODO: if there are conflicts, we should prefer a tracker that 
-      // pertains to the type of measuring tool currently selected (TBD?)
-      boost::shared_ptr<IFlexiblePointerTracker> hitTestTracker = TrackerHitTest(e);
-
-      if (hitTestTracker != NULL)
-      {
-        //LOG(TRACE) << "hitTestTracker != NULL";
-        return hitTestTracker;
-      }
-      else
-      {
-        switch (currentTool_)
-        {
-        case FusionMprGuiTool_Rotate:
-          //LOG(TRACE) << "Creating RotateSceneTracker";
-          return boost::shared_ptr<IFlexiblePointerTracker>(new RotateSceneTracker(
-            controller_, e));
-        case FusionMprGuiTool_Pan:
-          return boost::shared_ptr<IFlexiblePointerTracker>(new PanSceneTracker(
-            controller_, e));
-        case FusionMprGuiTool_Zoom:
-          return boost::shared_ptr<IFlexiblePointerTracker>(new ZoomSceneTracker(
-            controller_, e, viewport_.GetCompositor().GetCanvasHeight()));
-        //case GuiTool_AngleMeasure:
-        //  return new AngleMeasureTracker(GetScene(), e);
-        //case GuiTool_CircleMeasure:
-        //  return new CircleMeasureTracker(GetScene(), e);
-        //case GuiTool_EllipseMeasure:
-        //  return new EllipseMeasureTracker(GetScene(), e);
-        case FusionMprGuiTool_LineMeasure:
-          return boost::shared_ptr<IFlexiblePointerTracker>(new CreateLineMeasureTracker(
-            IObserver::GetBroker(), controller_, e));
-        case FusionMprGuiTool_AngleMeasure:
-          return boost::shared_ptr<IFlexiblePointerTracker>(new CreateAngleMeasureTracker(
-            IObserver::GetBroker(), controller_, e));
-        case FusionMprGuiTool_CircleMeasure:
-          LOG(ERROR) << "Not implemented yet!";
-          return boost::shared_ptr<IFlexiblePointerTracker>();
-        case FusionMprGuiTool_EllipseMeasure:
-          LOG(ERROR) << "Not implemented yet!";
-          return boost::shared_ptr<IFlexiblePointerTracker>();
-        default:
-          throw OrthancException(ErrorCode_InternalError, "Wrong tool!");
-        }
-      }
-    }
-    default:
-      return boost::shared_ptr<IFlexiblePointerTracker>();
-    }
-  }
-
-
-  FusionMprSdlApp::FusionMprSdlApp(MessageBroker& broker)
-    : IObserver(broker)
-    , broker_(broker)
-    , oracleObservable_(broker)
-    , oracle_(*this)
-    , currentTool_(FusionMprGuiTool_Rotate)
-    , undoStack_(new UndoStack)
-    , viewport_("Hello", 1024, 1024, false) // False means we do NOT let Windows treat this as a legacy application that needs to be scaled
-  {
-    //oracleObservable.RegisterObserverCallback
-    //(new Callable
-    //  <FusionMprSdlApp, SleepOracleCommand::TimeoutMessage>(*this, &FusionMprSdlApp::Handle));
-
-    //oracleObservable.RegisterObserverCallback
-    //(new Callable
-    //  <Toto, GetOrthancImageCommand::SuccessMessage>(*this, &FusionMprSdlApp::Handle));
-
-    //oracleObservable.RegisterObserverCallback
-    //(new Callable
-    //  <FusionMprSdlApp, GetOrthancWebViewerJpegCommand::SuccessMessage>(*this, &ToFusionMprSdlAppto::Handle));
-
-    oracleObservable_.RegisterObserverCallback
-    (new Callable
-      <FusionMprSdlApp, OracleCommandExceptionMessage>(*this, &FusionMprSdlApp::Handle));
-    
-    controller_ = boost::shared_ptr<ViewportController>(
-      new ViewportController(undoStack_, broker_, viewport_));
-
-    controller_->RegisterObserverCallback(
-      new Callable<FusionMprSdlApp, ViewportController::SceneTransformChanged>
-      (*this, &FusionMprSdlApp::OnSceneTransformChanged));
-
-    TEXTURE_2x2_1_ZINDEX = 1;
-    TEXTURE_1x1_ZINDEX = 2;
-    TEXTURE_2x2_2_ZINDEX = 3;
-    LINESET_1_ZINDEX = 4;
-    LINESET_2_ZINDEX = 5;
-    FLOATING_INFOTEXT_LAYER_ZINDEX = 6;
-    FIXED_INFOTEXT_LAYER_ZINDEX = 7;
-  }
-
-  void FusionMprSdlApp::PrepareScene()
-  {
-    // Texture of 2x2 size
-    {
-      Orthanc::Image i(Orthanc::PixelFormat_RGB24, 2, 2, false);
-
-      uint8_t* p = reinterpret_cast<uint8_t*>(i.GetRow(0));
-      p[0] = 255;
-      p[1] = 0;
-      p[2] = 0;
-
-      p[3] = 0;
-      p[4] = 255;
-      p[5] = 0;
-
-      p = reinterpret_cast<uint8_t*>(i.GetRow(1));
-      p[0] = 0;
-      p[1] = 0;
-      p[2] = 255;
-
-      p[3] = 255;
-      p[4] = 0;
-      p[5] = 0;
-
-      GetScene().SetLayer(TEXTURE_2x2_1_ZINDEX, new ColorTextureSceneLayer(i));
-    }
-  }
-
-  void FusionMprSdlApp::DisableTracker()
-  {
-    if (activeTracker_)
-    {
-      activeTracker_->Cancel();
-      activeTracker_.reset();
-    }
-  }
-
-  void FusionMprSdlApp::TakeScreenshot(const std::string& target,
-    unsigned int canvasWidth,
-    unsigned int canvasHeight)
-  {
-    CairoCompositor compositor(GetScene(), canvasWidth, canvasHeight);
-    compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, FONT_SIZE_0, Orthanc::Encoding_Latin1);
-    compositor.Refresh();
-
-    Orthanc::ImageAccessor canvas;
-    compositor.GetCanvas().GetReadOnlyAccessor(canvas);
-
-    Orthanc::Image png(Orthanc::PixelFormat_RGB24, canvas.GetWidth(), canvas.GetHeight(), false);
-    Orthanc::ImageProcessing::Convert(png, canvas);
-
-    Orthanc::PngWriter writer;
-    writer.WriteToFile(target, png);
-  }
-
-
-  boost::shared_ptr<IFlexiblePointerTracker> FusionMprSdlApp::TrackerHitTest(const PointerEvent & e)
-  {
-    // std::vector<boost::shared_ptr<MeasureTool>> measureTools_;
-    return boost::shared_ptr<IFlexiblePointerTracker>();
-  }
-
-  static void GLAPIENTRY
-    OpenGLMessageCallback(GLenum source,
-      GLenum type,
-      GLuint id,
-      GLenum severity,
-      GLsizei length,
-      const GLchar* message,
-      const void* userParam)
-  {
-    if (severity != GL_DEBUG_SEVERITY_NOTIFICATION)
-    {
-      fprintf(stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n",
-        (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""),
-        type, severity, message);
-    }
-  }
-
-  static bool g_stopApplication = false;
-  
-
-  void FusionMprSdlApp::Handle(const DicomVolumeImage::GeometryReadyMessage& message)
-  {
-    printf("Geometry ready\n");
-
-    //plane_ = message.GetOrigin().GetGeometry().GetSagittalGeometry();
-    //plane_ = message.GetOrigin().GetGeometry().GetAxialGeometry();
-    plane_ = message.GetOrigin().GetGeometry().GetCoronalGeometry();
-    plane_.SetOrigin(message.GetOrigin().GetGeometry().GetCoordinates(0.5f, 0.5f, 0.5f));
-
-    //Refresh();
-  }
-
-
-  void FusionMprSdlApp::Handle(const OracleCommandExceptionMessage& message)
-  {
-    printf("EXCEPTION: [%s] on command type %d\n", message.GetException().What(), message.GetCommand().GetType());
-
-    switch (message.GetCommand().GetType())
-    {
-    case IOracleCommand::Type_GetOrthancWebViewerJpeg:
-      printf("URI: [%s]\n", dynamic_cast<const GetOrthancWebViewerJpegCommand&>
-        (message.GetCommand()).GetUri().c_str());
-      break;
-
-    default:
-      break;
-    }
-  }
-
-  void FusionMprSdlApp::SetVolume1(int depth,
-    const boost::shared_ptr<OrthancStone::IVolumeSlicer>& volume,
-    OrthancStone::ILayerStyleConfigurator* style)
-  {
-    source1_.reset(new OrthancStone::VolumeSceneLayerSource(controller_->GetScene(), depth, volume));
-
-    if (style != NULL)
-    {
-      source1_->SetConfigurator(style);
-    }
-  }
-
-  void FusionMprSdlApp::SetVolume2(int depth,
-    const boost::shared_ptr<OrthancStone::IVolumeSlicer>& volume,
-    OrthancStone::ILayerStyleConfigurator* style)
-  {
-    source2_.reset(new OrthancStone::VolumeSceneLayerSource(controller_->GetScene(), depth, volume));
-
-    if (style != NULL)
-    {
-      source2_->SetConfigurator(style);
-    }
-  }
-
-  void FusionMprSdlApp::SetStructureSet(int depth,
-    const boost::shared_ptr<OrthancStone::DicomStructureSetLoader>& volume)
-  {
-    source3_.reset(new OrthancStone::VolumeSceneLayerSource(controller_->GetScene(), depth, volume));
-  }
-  
-  void FusionMprSdlApp::Run()
-  {
-    // False means we do NOT let Windows treat this as a legacy application
-    // that needs to be scaled
-    controller_->FitContent(viewport_.GetCanvasWidth(), viewport_.GetCanvasHeight());
-
-    glEnable(GL_DEBUG_OUTPUT);
-    glDebugMessageCallback(OpenGLMessageCallback, 0);
-
-    viewport_.GetCompositor().SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT,
-      FONT_SIZE_0, Orthanc::Encoding_Latin1);
-    viewport_.GetCompositor().SetFont(1, Orthanc::EmbeddedResources::UBUNTU_FONT,
-      FONT_SIZE_1, Orthanc::Encoding_Latin1);
-
-
-    //////// from loader
-    {
-      Orthanc::WebServiceParameters p;
-      //p.SetUrl("http://localhost:8043/");
-      p.SetCredentials("orthanc", "orthanc");
-      oracle_.SetOrthancParameters(p);
-    }
-
-    //////// from Run
-
-    boost::shared_ptr<DicomVolumeImage>  ct(new DicomVolumeImage);
-    boost::shared_ptr<DicomVolumeImage>  dose(new DicomVolumeImage);
-
-
-    boost::shared_ptr<OrthancSeriesVolumeProgressiveLoader> ctLoader;
-    boost::shared_ptr<OrthancMultiframeVolumeLoader> doseLoader;
-    boost::shared_ptr<DicomStructureSetLoader>  rtstructLoader;
-
-    {
-      ctLoader.reset(new OrthancSeriesVolumeProgressiveLoader(ct, oracle_, oracleObservable_));
-      doseLoader.reset(new OrthancMultiframeVolumeLoader(dose, oracle_, oracleObservable_));
-      rtstructLoader.reset(new DicomStructureSetLoader(oracle_, oracleObservable_));
-    }
-
-    //toto->SetReferenceLoader(*ctLoader);
-    //doseLoader->RegisterObserverCallback
-    //(new Callable
-    //  <FusionMprSdlApp, DicomVolumeImage::GeometryReadyMessage>(*this, &FusionMprSdlApp::Handle));
-    ctLoader->RegisterObserverCallback
-    (new Callable
-      <FusionMprSdlApp, DicomVolumeImage::GeometryReadyMessage>(*this, &FusionMprSdlApp::Handle));
-
-    this->SetVolume1(0, ctLoader, new GrayscaleStyleConfigurator);
-
-    {
-      std::unique_ptr<LookupTableStyleConfigurator> config(new LookupTableStyleConfigurator);
-      config->SetLookupTable(Orthanc::EmbeddedResources::COLORMAP_HOT);
-
-      boost::shared_ptr<DicomVolumeImageMPRSlicer> tmp(new DicomVolumeImageMPRSlicer(dose));
-      this->SetVolume2(1, tmp, config.release());
-    }
-
-    this->SetStructureSet(2, rtstructLoader);
-
-#if 1
-    /*
-    BGO data
-    http://localhost:8042/twiga-orthanc-viewer-demo/twiga-orthanc-viewer-demo.html?ct-series=a04ecf01-79b2fc33-58239f7e-ad9db983-28e81afa
-    &
-    dose-instance=830a69ff-8e4b5ee3-b7f966c8-bccc20fb-d322dceb
-    &
-    struct-instance=54460695-ba3885ee-ddf61ac0-f028e31d-a6e474d9
-    */
-    ctLoader->LoadSeries("a04ecf01-79b2fc33-58239f7e-ad9db983-28e81afa");  // CT
-    doseLoader->LoadInstance("830a69ff-8e4b5ee3-b7f966c8-bccc20fb-d322dceb");  // RT-DOSE
-    rtstructLoader->LoadInstance("54460695-ba3885ee-ddf61ac0-f028e31d-a6e474d9");  // RT-STRUCT
-#else
-    //ctLoader->LoadSeries("cb3ea4d1-d08f3856-ad7b6314-74d88d77-60b05618");  // CT
-    //doseLoader->LoadInstance("41029085-71718346-811efac4-420e2c15-d39f99b6");  // RT-DOSE
-    //rtstructLoader->LoadInstance("83d9c0c3-913a7fee-610097d7-cbf0522d-fd75bee6");  // RT-STRUCT
-
-    // 2017-05-16
-    ctLoader->LoadSeries("a04ecf01-79b2fc33-58239f7e-ad9db983-28e81afa");  // CT
-    doseLoader->LoadInstance("eac822ef-a395f94e-e8121fe0-8411fef8-1f7bffad");  // RT-DOSE
-    rtstructLoader->LoadInstance("54460695-ba3885ee-ddf61ac0-f028e31d-a6e474d9");  // RT-STRUCT
-#endif
-
-    oracle_.Start();
-
-//// END from loader
-
-    while (!g_stopApplication)
-    {
-      viewport_.GetCompositor().Refresh();
-
-//////// from loader
-      if (source1_.get() != NULL)
-      {
-        source1_->Update(plane_);
-      }
-
-      if (source2_.get() != NULL)
-      {
-        source2_->Update(plane_);
-      }
-
-      if (source3_.get() != NULL)
-      {
-        source3_->Update(plane_);
-      }
-//// END from loader
-
-      SDL_Event event;
-      while (!g_stopApplication && SDL_PollEvent(&event))
-      {
-        if (event.type == SDL_QUIT)
-        {
-          g_stopApplication = true;
-          break;
-        }
-        else if (event.type == SDL_WINDOWEVENT &&
-          event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
-        {
-          DisableTracker(); // was: tracker.reset(NULL);
-        }
-        else if (event.type == SDL_KEYDOWN &&
-          event.key.repeat == 0 /* Ignore key bounce */)
-        {
-          switch (event.key.keysym.sym)
-          {
-          case SDLK_f:
-            viewport_.GetWindow().ToggleMaximize();
-            break;
-
-          case SDLK_s:
-            controller_->FitContent(viewport_.GetCanvasWidth(), viewport_.GetCanvasHeight());
-            break;
-
-          case SDLK_q:
-            g_stopApplication = true;
-            break;
-          default:
-            break;
-          }
-        }
-        HandleApplicationEvent(event);
-      }
-      SDL_Delay(1);
-    }
-
-    //// from loader
-
-    //Orthanc::SystemToolbox::ServerBarrier();
-
-    /**
-     * WARNING => The oracle must be stopped BEFORE the objects using
-     * it are destroyed!!! This forces to wait for the completion of
-     * the running callback methods. Otherwise, the callbacks methods
-     * might still be running while their parent object is destroyed,
-     * resulting in crashes. This is very visible if adding a sleep(),
-     * as in (*).
-     **/
-
-    oracle_.Stop();
-    //// END from loader
-  }
-
-  void FusionMprSdlApp::SetInfoDisplayMessage(
-    std::string key, std::string value)
-  {
-    if (value == "")
-      infoTextMap_.erase(key);
-    else
-      infoTextMap_[key] = value;
-    DisplayInfoText();
-  }
-
-}
-
-
-boost::weak_ptr<OrthancStone::FusionMprSdlApp> g_app;
-
-void FusionMprSdl_SetInfoDisplayMessage(std::string key, std::string value)
-{
-  boost::shared_ptr<OrthancStone::FusionMprSdlApp> app = g_app.lock();
-  if (app)
-  {
-    app->SetInfoDisplayMessage(key, value);
-  }
-}
-
-/**
- * IMPORTANT: The full arguments to "main()" are needed for SDL on
- * Windows. Otherwise, one gets the linking error "undefined reference
- * to `SDL_main'". https://wiki.libsdl.org/FAQWindows
- **/
-int main(int argc, char* argv[])
-{
-  using namespace OrthancStone;
-
-  StoneInitialize();
-  Orthanc::Logging::EnableInfoLevel(true);
-//  Orthanc::Logging::EnableTraceLevel(true);
-
-  try
-  {
-    OrthancStone::MessageBroker broker;
-    boost::shared_ptr<FusionMprSdlApp> app(new FusionMprSdlApp(broker));
-    g_app = app;
-    app->PrepareScene();
-    app->Run();
-  }
-  catch (Orthanc::OrthancException& e)
-  {
-    LOG(ERROR) << "EXCEPTION: " << e.What();
-  }
-
-  StoneFinalize();
-
-  return 0;
-}
-
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/Sdl/FusionMprSdl.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,209 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Framework/Viewport/SdlViewport.h"
-
-#include "../../Framework/Messages/IObserver.h"
-#include "../../Framework/Messages/IMessageEmitter.h"
-#include "../../Framework/Oracle/OracleCommandExceptionMessage.h"
-#include "../../Framework/Scene2DViewport/ViewportController.h"
-#include "../../Framework/Volumes/DicomVolumeImage.h"
-#include "../../Framework/Oracle/ThreadedOracle.h"
-
-#include <boost/enable_shared_from_this.hpp>
-#include <boost/thread.hpp>
-#include <boost/noncopyable.hpp>
-
-#include <SDL.h>
-
-namespace OrthancStone
-{
-  class OpenGLCompositor;
-  class IVolumeSlicer;
-  class ILayerStyleConfigurator;
-  class DicomStructureSetLoader;
-  class IOracle;
-  class ThreadedOracle;
-  class VolumeSceneLayerSource;
-  class NativeFusionMprApplicationContext;
-  class SdlOpenGLViewport;
-   
-  enum FusionMprGuiTool
-  {
-    FusionMprGuiTool_Rotate = 0,
-    FusionMprGuiTool_Pan,
-    FusionMprGuiTool_Zoom,
-    FusionMprGuiTool_LineMeasure,
-    FusionMprGuiTool_CircleMeasure,
-    FusionMprGuiTool_AngleMeasure,
-    FusionMprGuiTool_EllipseMeasure,
-    FusionMprGuiTool_LAST
-  };
-
-  const char* MeasureToolToString(size_t i);
-
-  static const unsigned int FONT_SIZE_0 = 32;
-  static const unsigned int FONT_SIZE_1 = 24;
-
-  class Scene2D;
-  class UndoStack;
-
-  /**
-  This application subclasses IMessageEmitter to use a mutex before forwarding Oracle messages (that
-  can be sent from multiple threads)
-  */
-  class FusionMprSdlApp : public IObserver
-    , public boost::enable_shared_from_this<FusionMprSdlApp>
-    , public IMessageEmitter
-  {
-  public:
-    // 12 because.
-    FusionMprSdlApp(MessageBroker& broker);
-
-    void PrepareScene();
-    void Run();
-    void SetInfoDisplayMessage(std::string key, std::string value);
-    void DisableTracker();
-
-    Scene2D&       GetScene();
-    const Scene2D& GetScene() const;
-
-    void HandleApplicationEvent(const SDL_Event& event);
-
-    /**
-    This method is called when the scene transform changes. It allows to
-    recompute the visual elements whose content depend upon the scene transform
-    */
-    void OnSceneTransformChanged(
-      const ViewportController::SceneTransformChanged& message);
-
-
-    virtual void EmitMessage(const IObserver& observer,
-      const IMessage& message) ORTHANC_OVERRIDE
-    {
-      try
-      {
-        boost::unique_lock<boost::shared_mutex>  lock(mutex_);
-        oracleObservable_.EmitMessage(observer, message);
-      }
-      catch (Orthanc::OrthancException& e)
-      {
-        LOG(ERROR) << "Exception while emitting a message: " << e.What();
-        throw;
-      }
-    }
-    
-  private:
-#if 1
-    // if threaded (not wasm)
-    MessageBroker& broker_;
-    IObservable oracleObservable_;
-    ThreadedOracle oracle_;
-    boost::shared_mutex mutex_; // to serialize messages from the ThreadedOracle
-#endif
-
-    void SelectNextTool();
-
-    /**
-    This returns a random point in the canvas part of the scene, but in
-    scene coordinates
-    */
-    ScenePoint2D GetRandomPointInScene() const;
-
-    boost::shared_ptr<IFlexiblePointerTracker> TrackerHitTest(const PointerEvent& e);
-
-    boost::shared_ptr<IFlexiblePointerTracker> CreateSuitableTracker(
-      const SDL_Event& event,
-      const PointerEvent& e);
-
-    void TakeScreenshot(
-      const std::string& target,
-      unsigned int canvasWidth,
-      unsigned int canvasHeight);
-
-    /**
-      This adds the command at the top of the undo stack
-    */
-    void Commit(boost::shared_ptr<TrackerCommand> cmd);
-    void Undo();
-    void Redo();
-
-
-    // TODO private
-    void Handle(const DicomVolumeImage::GeometryReadyMessage& message);
-    void Handle(const OracleCommandExceptionMessage& message);
-
-    void SetVolume1(
-      int depth,
-      const boost::shared_ptr<IVolumeSlicer>& volume,
-      ILayerStyleConfigurator* style);
-    
-    void SetVolume2(
-      int depth,
-      const boost::shared_ptr<IVolumeSlicer>& volume,
-      ILayerStyleConfigurator* style);
-
-    void SetStructureSet(
-      int depth, 
-      const boost::shared_ptr<DicomStructureSetLoader>& volume);
-
-
-
-  private:
-    void DisplayFloatingCtrlInfoText(const PointerEvent& e);
-    void DisplayInfoText();
-    void HideInfoText();
-
-  private:
-    CoordinateSystem3D  plane_;
-
-    boost::shared_ptr<VolumeSceneLayerSource>  source1_, source2_, source3_;
-
-    /**
-    WARNING: the measuring tools do store a reference to the scene, and it
-    paramount that the scene gets destroyed AFTER the measurement tools.
-    */
-    boost::shared_ptr<ViewportController> controller_;
-
-    std::map<std::string, std::string> infoTextMap_;
-    boost::shared_ptr<IFlexiblePointerTracker> activeTracker_;
-
-    //static const int LAYER_POSITION = 150;
-
-    int TEXTURE_2x2_1_ZINDEX;
-    int TEXTURE_1x1_ZINDEX;
-    int TEXTURE_2x2_2_ZINDEX;
-    int LINESET_1_ZINDEX;
-    int LINESET_2_ZINDEX;
-    int FLOATING_INFOTEXT_LAYER_ZINDEX;
-    int FIXED_INFOTEXT_LAYER_ZINDEX;
-
-    FusionMprGuiTool currentTool_;
-    boost::shared_ptr<UndoStack> undoStack_;
-    SdlOpenGLViewport viewport_;
-  };
-
-}
-
-
- 
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/Sdl/Loader.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,518 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "../../Framework/Loaders/DicomStructureSetLoader.h"
-#include "../../Framework/Loaders/OrthancMultiframeVolumeLoader.h"
-#include "../../Framework/Loaders/OrthancSeriesVolumeProgressiveLoader.h"
-#include "../../Framework/Oracle/SleepOracleCommand.h"
-#include "../../Framework/Oracle/ThreadedOracle.h"
-#include "../../Framework/Scene2D/CairoCompositor.h"
-#include "../../Framework/Scene2D/GrayscaleStyleConfigurator.h"
-#include "../../Framework/Scene2D/LookupTableStyleConfigurator.h"
-#include "../../Framework/StoneInitialization.h"
-#include "../../Framework/Volumes/VolumeSceneLayerSource.h"
-#include "../../Framework/Volumes/DicomVolumeImageMPRSlicer.h"
-#include "../../Framework/Volumes/DicomVolumeImageReslicer.h"
-
-// From Orthanc framework
-#include <Core/Images/ImageProcessing.h>
-#include <Core/Images/PngWriter.h>
-#include <Core/Logging.h>
-#include <Core/OrthancException.h>
-#include <Core/SystemToolbox.h>
-
-
-namespace OrthancStone
-{
-  class NativeApplicationContext : public IMessageEmitter
-  {
-  private:
-    boost::shared_mutex  mutex_;
-    MessageBroker        broker_;
-    IObservable          oracleObservable_;
-
-  public:
-    NativeApplicationContext() :
-      oracleObservable_(broker_)
-    {
-    }
-
-
-    virtual void EmitMessage(const IObserver& observer,
-                             const IMessage& message) ORTHANC_OVERRIDE
-    {
-      try
-      {
-        boost::unique_lock<boost::shared_mutex>  lock(mutex_);
-        oracleObservable_.EmitMessage(observer, message);
-      }
-      catch (Orthanc::OrthancException& e)
-      {
-        LOG(ERROR) << "Exception while emitting a message: " << e.What();
-      }
-    }
-
-
-    class ReaderLock : public boost::noncopyable
-    {
-    private:
-      NativeApplicationContext&                that_;
-      boost::shared_lock<boost::shared_mutex>  lock_;
-
-    public:
-      ReaderLock(NativeApplicationContext& that) : 
-        that_(that),
-        lock_(that.mutex_)
-      {
-      }
-    };
-
-
-    class WriterLock : public boost::noncopyable
-    {
-    private:
-      NativeApplicationContext&                that_;
-      boost::unique_lock<boost::shared_mutex>  lock_;
-
-    public:
-      WriterLock(NativeApplicationContext& that) : 
-        that_(that),
-        lock_(that.mutex_)
-      {
-      }
-
-      MessageBroker& GetBroker() 
-      {
-        return that_.broker_;
-      }
-
-      IObservable& GetOracleObservable()
-      {
-        return that_.oracleObservable_;
-      }
-    };
-  };
-}
-
-
-
-class Toto : public OrthancStone::IObserver
-{
-private:
-  OrthancStone::CoordinateSystem3D  plane_;
-  OrthancStone::IOracle&            oracle_;
-  OrthancStone::Scene2D             scene_;
-  std::unique_ptr<OrthancStone::VolumeSceneLayerSource>  source1_, source2_, source3_;
-
-
-  void Refresh()
-  {
-    if (source1_.get() != NULL)
-    {
-      source1_->Update(plane_);
-    }
-      
-    if (source2_.get() != NULL)
-    {
-      source2_->Update(plane_);
-    }
-
-    if (source3_.get() != NULL)
-    {
-      source3_->Update(plane_);
-    }
-
-    scene_.FitContent(1024, 768);
-      
-    {
-      OrthancStone::CairoCompositor compositor(scene_, 1024, 768);
-      compositor.Refresh();
-        
-      Orthanc::ImageAccessor accessor;
-      compositor.GetCanvas().GetReadOnlyAccessor(accessor);
-
-      Orthanc::Image tmp(Orthanc::PixelFormat_RGB24, accessor.GetWidth(), accessor.GetHeight(), false);
-      Orthanc::ImageProcessing::Convert(tmp, accessor);
-        
-      static unsigned int count = 0;
-      char buf[64];
-      sprintf(buf, "scene-%06d.png", count++);
-        
-      Orthanc::PngWriter writer;
-      writer.WriteToFile(buf, tmp);
-    }
-  }
-
-  
-  void Handle(const OrthancStone::DicomVolumeImage::GeometryReadyMessage& message)
-  {
-    printf("Geometry ready\n");
-    
-    plane_ = message.GetOrigin().GetGeometry().GetSagittalGeometry();
-    //plane_ = message.GetOrigin().GetGeometry().GetAxialGeometry();
-    //plane_ = message.GetOrigin().GetGeometry().GetCoronalGeometry();
-    plane_.SetOrigin(message.GetOrigin().GetGeometry().GetCoordinates(0.5f, 0.5f, 0.5f));
-
-    Refresh();
-  }
-  
-  
-  void Handle(const OrthancStone::SleepOracleCommand::TimeoutMessage& message)
-  {
-    if (message.GetOrigin().HasPayload())
-    {
-      printf("TIMEOUT! %d\n", dynamic_cast<const Orthanc::SingleValueObject<unsigned int>& >(message.GetOrigin().GetPayload()).GetValue());
-    }
-    else
-    {
-      printf("TIMEOUT\n");
-
-      Refresh();
-
-      /**
-       * The sleep() leads to a crash if the oracle is still running,
-       * while this object is destroyed. Always stop the oracle before
-       * destroying active objects.  (*)
-       **/
-      // boost::this_thread::sleep(boost::posix_time::seconds(2));
-
-      oracle_.Schedule(*this, new OrthancStone::SleepOracleCommand(message.GetOrigin().GetDelay()));
-    }
-  }
-
-  void Handle(const OrthancStone::OrthancRestApiCommand::SuccessMessage& message)
-  {
-    Json::Value v;
-    message.ParseJsonBody(v);
-
-    printf("ICI [%s]\n", v.toStyledString().c_str());
-  }
-
-  void Handle(const OrthancStone::GetOrthancImageCommand::SuccessMessage& message)
-  {
-    printf("IMAGE %dx%d\n", message.GetImage().GetWidth(), message.GetImage().GetHeight());
-  }
-
-  void Handle(const OrthancStone::GetOrthancWebViewerJpegCommand::SuccessMessage& message)
-  {
-    printf("WebViewer %dx%d\n", message.GetImage().GetWidth(), message.GetImage().GetHeight());
-  }
-
-  void Handle(const OrthancStone::OracleCommandExceptionMessage& message)
-  {
-    printf("EXCEPTION: [%s] on command type %d\n", message.GetException().What(), message.GetCommand().GetType());
-
-    switch (message.GetCommand().GetType())
-    {
-      case OrthancStone::IOracleCommand::Type_GetOrthancWebViewerJpeg:
-        printf("URI: [%s]\n", dynamic_cast<const OrthancStone::GetOrthancWebViewerJpegCommand&>
-               (message.GetCommand()).GetUri().c_str());
-        break;
-      
-      default:
-        break;
-    }
-  }
-
-public:
-  Toto(OrthancStone::IOracle& oracle,
-       OrthancStone::IObservable& oracleObservable) :
-    IObserver(oracleObservable.GetBroker()),
-    oracle_(oracle)
-  {
-    oracleObservable.RegisterObserverCallback
-      (new OrthancStone::Callable
-       <Toto, OrthancStone::SleepOracleCommand::TimeoutMessage>(*this, &Toto::Handle));
-
-    oracleObservable.RegisterObserverCallback
-      (new OrthancStone::Callable
-       <Toto, OrthancStone::OrthancRestApiCommand::SuccessMessage>(*this, &Toto::Handle));
-
-    oracleObservable.RegisterObserverCallback
-      (new OrthancStone::Callable
-       <Toto, OrthancStone::GetOrthancImageCommand::SuccessMessage>(*this, &Toto::Handle));
-
-    oracleObservable.RegisterObserverCallback
-      (new OrthancStone::Callable
-       <Toto, OrthancStone::GetOrthancWebViewerJpegCommand::SuccessMessage>(*this, &Toto::Handle));
-
-    oracleObservable.RegisterObserverCallback
-      (new OrthancStone::Callable
-       <Toto, OrthancStone::OracleCommandExceptionMessage>(*this, &Toto::Handle));
-  }
-
-  void SetReferenceLoader(OrthancStone::IObservable& loader)
-  {
-    loader.RegisterObserverCallback
-      (new OrthancStone::Callable
-       <Toto, OrthancStone::DicomVolumeImage::GeometryReadyMessage>(*this, &Toto::Handle));
-  }
-
-  void SetVolume1(int depth,
-                  const boost::shared_ptr<OrthancStone::IVolumeSlicer>& volume,
-                  OrthancStone::ILayerStyleConfigurator* style)
-  {
-    source1_.reset(new OrthancStone::VolumeSceneLayerSource(scene_, depth, volume));
-
-    if (style != NULL)
-    {
-      source1_->SetConfigurator(style);
-    }
-  }
-
-  void SetVolume2(int depth,
-                  const boost::shared_ptr<OrthancStone::IVolumeSlicer>& volume,
-                  OrthancStone::ILayerStyleConfigurator* style)
-  {
-    source2_.reset(new OrthancStone::VolumeSceneLayerSource(scene_, depth, volume));
-
-    if (style != NULL)
-    {
-      source2_->SetConfigurator(style);
-    }
-  }
-
-  void SetStructureSet(int depth,
-                       const boost::shared_ptr<OrthancStone::DicomStructureSetLoader>& volume)
-  {
-    source3_.reset(new OrthancStone::VolumeSceneLayerSource(scene_, depth, volume));
-  }
-                       
-};
-
-
-void Run(OrthancStone::NativeApplicationContext& context,
-         OrthancStone::ThreadedOracle& oracle)
-{
-  // the oracle has been supplied with the context (as an IEmitter) upon
-  // creation
-  boost::shared_ptr<OrthancStone::DicomVolumeImage>  ct(new OrthancStone::DicomVolumeImage);
-  boost::shared_ptr<OrthancStone::DicomVolumeImage>  dose(new OrthancStone::DicomVolumeImage);
-
-  
-  boost::shared_ptr<Toto> toto;
-  boost::shared_ptr<OrthancStone::OrthancSeriesVolumeProgressiveLoader> ctLoader;
-  boost::shared_ptr<OrthancStone::OrthancMultiframeVolumeLoader> doseLoader;
-  boost::shared_ptr<OrthancStone::DicomStructureSetLoader>  rtstructLoader;
-
-  {
-    OrthancStone::NativeApplicationContext::WriterLock lock(context);
-    toto.reset(new Toto(oracle, lock.GetOracleObservable()));
-
-    // the oracle is used to schedule commands
-    // the oracleObservable is used by the loaders to:
-    // - request the broker (lifetime mgmt)
-    // - register the loader callbacks (called indirectly by the oracle)
-    ctLoader.reset(new OrthancStone::OrthancSeriesVolumeProgressiveLoader(ct, oracle, lock.GetOracleObservable()));
-    doseLoader.reset(new OrthancStone::OrthancMultiframeVolumeLoader(dose, oracle, lock.GetOracleObservable()));
-    rtstructLoader.reset(new OrthancStone::DicomStructureSetLoader(oracle, lock.GetOracleObservable()));
-  }
-
-
-  //toto->SetReferenceLoader(*ctLoader);
-  toto->SetReferenceLoader(*doseLoader);
-
-
-#if 1
-  toto->SetVolume1(0, ctLoader, new OrthancStone::GrayscaleStyleConfigurator);
-#else
-  {
-    boost::shared_ptr<OrthancStone::IVolumeSlicer> reslicer(new OrthancStone::DicomVolumeImageReslicer(ct));
-    toto->SetVolume1(0, reslicer, new OrthancStone::GrayscaleStyleConfigurator);
-  }
-#endif  
-  
-
-  {
-    std::unique_ptr<OrthancStone::LookupTableStyleConfigurator> config(new OrthancStone::LookupTableStyleConfigurator);
-    config->SetLookupTable(Orthanc::EmbeddedResources::COLORMAP_HOT);
-
-    boost::shared_ptr<OrthancStone::DicomVolumeImageMPRSlicer> tmp(new OrthancStone::DicomVolumeImageMPRSlicer(dose));
-    toto->SetVolume2(1, tmp, config.release());
-  }
-
-  toto->SetStructureSet(2, rtstructLoader);
-  
-  oracle.Schedule(*toto, new OrthancStone::SleepOracleCommand(100));
-
-  if (0)
-  {
-    Json::Value v = Json::objectValue;
-    v["Level"] = "Series";
-    v["Query"] = Json::objectValue;
-
-    std::unique_ptr<OrthancStone::OrthancRestApiCommand>  command(new OrthancStone::OrthancRestApiCommand);
-    command->SetMethod(Orthanc::HttpMethod_Post);
-    command->SetUri("/tools/find");
-    command->SetBody(v);
-
-    oracle.Schedule(*toto, command.release());
-  }
-  
-  if(0)
-  {
-    if (0)
-    {
-      std::unique_ptr<OrthancStone::GetOrthancImageCommand>  command(new OrthancStone::GetOrthancImageCommand);
-      command->SetHttpHeader("Accept", std::string(Orthanc::EnumerationToString(Orthanc::MimeType_Jpeg)));
-      command->SetUri("/instances/6687cc73-07cae193-52ff29c8-f646cb16-0753ed92/preview");
-      oracle.Schedule(*toto, command.release());
-    }
-    
-    if (0)
-    {
-      std::unique_ptr<OrthancStone::GetOrthancImageCommand>  command(new OrthancStone::GetOrthancImageCommand);
-      command->SetHttpHeader("Accept", std::string(Orthanc::EnumerationToString(Orthanc::MimeType_Png)));
-      command->SetUri("/instances/6687cc73-07cae193-52ff29c8-f646cb16-0753ed92/preview");
-      oracle.Schedule(*toto, command.release());
-    }
-    
-    if (0)
-    {
-      std::unique_ptr<OrthancStone::GetOrthancImageCommand>  command(new OrthancStone::GetOrthancImageCommand);
-      command->SetHttpHeader("Accept", std::string(Orthanc::EnumerationToString(Orthanc::MimeType_Png)));
-      command->SetUri("/instances/6687cc73-07cae193-52ff29c8-f646cb16-0753ed92/image-uint16");
-      oracle.Schedule(*toto, command.release());
-    }
-    
-    if (0)
-    {
-      std::unique_ptr<OrthancStone::GetOrthancImageCommand>  command(new OrthancStone::GetOrthancImageCommand);
-      command->SetHttpHeader("Accept-Encoding", "gzip");
-      command->SetHttpHeader("Accept", std::string(Orthanc::EnumerationToString(Orthanc::MimeType_Pam)));
-      command->SetUri("/instances/6687cc73-07cae193-52ff29c8-f646cb16-0753ed92/image-uint16");
-      oracle.Schedule(*toto, command.release());
-    }
-    
-    if (0)
-    {
-      std::unique_ptr<OrthancStone::GetOrthancImageCommand>  command(new OrthancStone::GetOrthancImageCommand);
-      command->SetHttpHeader("Accept", std::string(Orthanc::EnumerationToString(Orthanc::MimeType_Pam)));
-      command->SetUri("/instances/6687cc73-07cae193-52ff29c8-f646cb16-0753ed92/image-uint16");
-      oracle.Schedule(*toto, command.release());
-    }
-
-    if (0)
-    {
-      std::unique_ptr<OrthancStone::GetOrthancWebViewerJpegCommand>  command(new OrthancStone::GetOrthancWebViewerJpegCommand);
-      command->SetHttpHeader("Accept-Encoding", "gzip");
-      command->SetInstance("e6c7c20b-c9f65d7e-0d76f2e2-830186f2-3e3c600e");
-      command->SetQuality(90);
-      oracle.Schedule(*toto, command.release());
-    }
-
-
-    if (0)
-    {
-      for (unsigned int i = 0; i < 10; i++)
-      {
-        std::unique_ptr<OrthancStone::SleepOracleCommand> command(new OrthancStone::SleepOracleCommand(i * 1000));
-        command->SetPayload(new Orthanc::SingleValueObject<unsigned int>(42 * i));
-        oracle.Schedule(*toto, command.release());
-      }
-    }
-  }
-  
-  // 2017-11-17-Anonymized
-#if 0
-  // BGO data
-  ctLoader->LoadSeries("a04ecf01-79b2fc33-58239f7e-ad9db983-28e81afa");  // CT
-  doseLoader->LoadInstance("830a69ff-8e4b5ee3-b7f966c8-bccc20fb-d322dceb");  // RT-DOSE
-  //rtstructLoader->LoadInstance("54460695-ba3885ee-ddf61ac0-f028e31d-a6e474d9");  // RT-STRUCT
-#else
-  //ctLoader->LoadSeries("cb3ea4d1-d08f3856-ad7b6314-74d88d77-60b05618");  // CT
-  //doseLoader->LoadInstance("41029085-71718346-811efac4-420e2c15-d39f99b6");  // RT-DOSE
-  //rtstructLoader->LoadInstance("83d9c0c3-913a7fee-610097d7-cbf0522d-fd75bee6");  // RT-STRUCT
-
-  // 2017-05-16
-  ctLoader->LoadSeries("a04ecf01-79b2fc33-58239f7e-ad9db983-28e81afa");  // CT
-  doseLoader->LoadInstance("eac822ef-a395f94e-e8121fe0-8411fef8-1f7bffad");  // RT-DOSE
-  rtstructLoader->LoadInstance("54460695-ba3885ee-ddf61ac0-f028e31d-a6e474d9");  // RT-STRUCT
-#endif
-  // 2015-01-28-Multiframe
-  //doseLoader->LoadInstance("88f71e2a-5fad1c61-96ed14d6-5b3d3cf7-a5825279");  // Multiframe CT
-  
-  // Delphine
-  //ctLoader->LoadSeries("5990e39c-51e5f201-fe87a54c-31a55943-e59ef80e");  // CT
-  //ctLoader->LoadSeries("67f1b334-02c16752-45026e40-a5b60b6b-030ecab5");  // Lung 1/10mm
-
-
-  {
-    LOG(WARNING) << "...Waiting for Ctrl-C...";
-
-    oracle.Start();
-
-    Orthanc::SystemToolbox::ServerBarrier();
-
-    /**
-     * WARNING => The oracle must be stopped BEFORE the objects using
-     * it are destroyed!!! This forces to wait for the completion of
-     * the running callback methods. Otherwise, the callbacks methods
-     * might still be running while their parent object is destroyed,
-     * resulting in crashes. This is very visible if adding a sleep(),
-     * as in (*).
-     **/
-
-    oracle.Stop();
-  }
-}
-
-
-
-/**
- * IMPORTANT: The full arguments to "main()" are needed for SDL on
- * Windows. Otherwise, one gets the linking error "undefined reference
- * to `SDL_main'". https://wiki.libsdl.org/FAQWindows
- **/
-int main(int argc, char* argv[])
-{
-  OrthancStone::StoneInitialize();
-  //Orthanc::Logging::EnableInfoLevel(true);
-
-  try
-  {
-    OrthancStone::NativeApplicationContext context;
-
-    OrthancStone::ThreadedOracle oracle(context);
-    //oracle.SetThreadsCount(1);
-
-    {
-      Orthanc::WebServiceParameters p;
-      //p.SetUrl("http://localhost:8043/");
-      p.SetCredentials("orthanc", "orthanc");
-      oracle.SetOrthancParameters(p);
-    }
-
-    //oracle.Start();
-
-    Run(context, oracle);
-    
-    //oracle.Stop();
-  }
-  catch (Orthanc::OrthancException& e)
-  {
-    LOG(ERROR) << "EXCEPTION: " << e.What();
-  }
-
-  OrthancStone::StoneFinalize();
-
-  return 0;
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/Sdl/RadiographyEditor.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,267 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "../Shared/RadiographyEditorApp.h"
-
-// From Stone
-#include "../../Framework/Oracle/SleepOracleCommand.h"
-#include "../../Framework/Oracle/ThreadedOracle.h"
-#include "../../Applications/Sdl/SdlOpenGLWindow.h"
-#include "../../Framework/Scene2D/OpenGLCompositor.h"
-#include "../../Framework/Scene2D/CairoCompositor.h"
-#include "../../Framework/Scene2D/ColorTextureSceneLayer.h"
-#include "../../Framework/Scene2D/OpenGLCompositor.h"
-#include "../../Framework/StoneInitialization.h"
-
-#include <Core/Logging.h>
-#include <Core/OrthancException.h>
-
-
-#include <boost/shared_ptr.hpp>
-#include <boost/weak_ptr.hpp>
-
-#include <SDL.h>
-#include <stdio.h>
-
-using namespace OrthancStone;
-
-namespace OrthancStone
-{
-  class NativeApplicationContext : public IMessageEmitter
-  {
-  private:
-    boost::shared_mutex  mutex_;
-    MessageBroker        broker_;
-    IObservable          oracleObservable_;
-
-  public:
-    NativeApplicationContext() :
-      oracleObservable_(broker_)
-    {
-    }
-
-
-    virtual void EmitMessage(const IObserver& observer,
-                             const IMessage& message) ORTHANC_OVERRIDE
-    {
-      try
-      {
-        boost::unique_lock<boost::shared_mutex>  lock(mutex_);
-        oracleObservable_.EmitMessage(observer, message);
-      }
-      catch (Orthanc::OrthancException& e)
-      {
-        LOG(ERROR) << "Exception while emitting a message: " << e.What();
-      }
-    }
-
-
-    class ReaderLock : public boost::noncopyable
-    {
-    private:
-      NativeApplicationContext&                that_;
-      boost::shared_lock<boost::shared_mutex>  lock_;
-
-    public:
-      ReaderLock(NativeApplicationContext& that) :
-        that_(that),
-        lock_(that.mutex_)
-      {
-      }
-    };
-
-
-    class WriterLock : public boost::noncopyable
-    {
-    private:
-      NativeApplicationContext&                that_;
-      boost::unique_lock<boost::shared_mutex>  lock_;
-
-    public:
-      WriterLock(NativeApplicationContext& that) :
-        that_(that),
-        lock_(that.mutex_)
-      {
-      }
-
-      MessageBroker& GetBroker()
-      {
-        return that_.broker_;
-      }
-
-      IObservable& GetOracleObservable()
-      {
-        return that_.oracleObservable_;
-      }
-    };
-  };
-}
-
-class OpenGlSdlCompositorFactory : public ICompositorFactory
-{
-  OpenGL::IOpenGLContext& openGlContext_;
-
-public:
-  OpenGlSdlCompositorFactory(OpenGL::IOpenGLContext& openGlContext) :
-    openGlContext_(openGlContext)
-  {}
-
-  ICompositor* GetCompositor(const Scene2D& scene)
-  {
-
-    OpenGLCompositor* compositor = new OpenGLCompositor(openGlContext_, scene);
-    compositor->SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT,
-                         FONT_SIZE_0, Orthanc::Encoding_Latin1);
-    compositor->SetFont(1, Orthanc::EmbeddedResources::UBUNTU_FONT,
-                         FONT_SIZE_1, Orthanc::Encoding_Latin1);
-    return compositor;
-  }
-};
-
-static void GLAPIENTRY
-OpenGLMessageCallback(GLenum source,
-                      GLenum type,
-                      GLuint id,
-                      GLenum severity,
-                      GLsizei length,
-                      const GLchar* message,
-                      const void* userParam)
-{
-  if (severity != GL_DEBUG_SEVERITY_NOTIFICATION)
-  {
-    fprintf(stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n",
-            (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""),
-            type, severity, message);
-  }
-}
-
-
-/**
- * IMPORTANT: The full arguments to "main()" are needed for SDL on
- * Windows. Otherwise, one gets the linking error "undefined reference
- * to `SDL_main'". https://wiki.libsdl.org/FAQWindows
- **/
-int main(int argc, char* argv[])
-{
-  using namespace OrthancStone;
-
-  StoneInitialize();
-  Orthanc::Logging::EnableInfoLevel(true);
-  //  Orthanc::Logging::EnableTraceLevel(true);
-
-  try
-  {
-    OrthancStone::NativeApplicationContext context;
-    OrthancStone::NativeApplicationContext::WriterLock lock(context);
-    OrthancStone::ThreadedOracle oracle(context);
-
-    // False means we do NOT let Windows treat this as a legacy application
-    // that needs to be scaled
-    SdlOpenGLWindow window("Hello", 1024, 1024, false);
-
-    glEnable(GL_DEBUG_OUTPUT);
-    glDebugMessageCallback(OpenGLMessageCallback, 0);
-
-    std::unique_ptr<OpenGlSdlCompositorFactory> compositorFactory(new OpenGlSdlCompositorFactory(window));
-    boost::shared_ptr<RadiographyEditorApp> app(new RadiographyEditorApp(oracle, lock.GetOracleObservable(), compositorFactory.release()));
-    app->PrepareScene();
-    app->FitContent(window.GetCanvasWidth(), window.GetCanvasHeight());
-
-    bool stopApplication = false;
-
-    while (!stopApplication)
-    {
-      app->Refresh();
-
-      SDL_Event event;
-      while (!stopApplication && SDL_PollEvent(&event))
-      {
-        OrthancStone::KeyboardModifiers modifiers = OrthancStone::KeyboardModifiers_None;
-        if (event.key.keysym.mod & KMOD_CTRL)
-          modifiers = static_cast<OrthancStone::KeyboardModifiers>(static_cast<int>(modifiers) | static_cast<int>(OrthancStone::KeyboardModifiers_Control));
-        if (event.key.keysym.mod & KMOD_ALT)
-          modifiers = static_cast<OrthancStone::KeyboardModifiers>(static_cast<int>(modifiers) | static_cast<int>(OrthancStone::KeyboardModifiers_Alt));
-        if (event.key.keysym.mod & KMOD_SHIFT)
-          modifiers = static_cast<OrthancStone::KeyboardModifiers>(static_cast<int>(modifiers) | static_cast<int>(OrthancStone::KeyboardModifiers_Shift));
-
-        OrthancStone::MouseButton button;
-        if (event.button.button == SDL_BUTTON_LEFT)
-          button = OrthancStone::MouseButton_Left;
-        else if (event.button.button == SDL_BUTTON_MIDDLE)
-          button = OrthancStone::MouseButton_Middle;
-        else if (event.button.button == SDL_BUTTON_RIGHT)
-          button = OrthancStone::MouseButton_Right;
-
-        if (event.type == SDL_QUIT)
-        {
-          stopApplication = true;
-          break;
-        }
-        else if (event.type == SDL_WINDOWEVENT &&
-                 event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
-        {
-          app->DisableTracker(); // was: tracker.reset(NULL);
-          app->UpdateSize();
-        }
-        else if (event.type == SDL_KEYDOWN &&
-                 event.key.repeat == 0 /* Ignore key bounce */)
-        {
-          switch (event.key.keysym.sym)
-          {
-          case SDLK_f:
-            window.GetWindow().ToggleMaximize();
-            break;
-
-          case SDLK_q:
-            stopApplication = true;
-            break;
-          default:
-          {
-            app->OnKeyPressed(event.key.keysym.sym, modifiers);
-           }
-          }
-        }
-        else if (event.type == SDL_MOUSEBUTTONDOWN)
-        {
-          app->OnMouseDown(event.button.x, event.button.y, modifiers, button);
-        }
-        else if (event.type == SDL_MOUSEMOTION)
-        {
-          app->OnMouseMove(event.button.x, event.button.y, modifiers);
-        }
-        else if (event.type == SDL_MOUSEBUTTONUP)
-        {
-          app->OnMouseUp(event.button.x, event.button.y, modifiers, button);
-        }
-      }
-      SDL_Delay(1);
-    }
-  }
-  catch (Orthanc::OrthancException& e)
-  {
-    LOG(ERROR) << "EXCEPTION: " << e.What();
-  }
-
-  StoneFinalize();
-
-  return 0;
-}
-
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/Sdl/TrackerSample.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "TrackerSampleApp.h"
-
- // From Stone
-#include "../../Framework/OpenGL/SdlOpenGLContext.h"
-#include "../../Framework/Scene2D/CairoCompositor.h"
-#include "../../Framework/Scene2D/ColorTextureSceneLayer.h"
-#include "../../Framework/Scene2D/OpenGLCompositor.h"
-#include "../../Framework/StoneInitialization.h"
-
-#include <Core/Logging.h>
-#include <Core/OrthancException.h>
-
-
-#include <boost/shared_ptr.hpp>
-#include <boost/weak_ptr.hpp>
-
-#include <SDL.h>
-#include <stdio.h>
-
-/*
-TODO:
-
-- to decouple the trackers from the sample, we need to supply them with
-  the scene rather than the app
-
-- in order to do that, we need a GetNextFreeZIndex function (or something 
-  along those lines) in the scene object
-
-*/
-
-boost::weak_ptr<OrthancStone::TrackerSampleApp> g_app;
-
-void TrackerSample_SetInfoDisplayMessage(std::string key, std::string value)
-{
-  boost::shared_ptr<OrthancStone::TrackerSampleApp> app = g_app.lock();
-  if (app)
-  {
-    app->SetInfoDisplayMessage(key, value);
-  }
-}
-
-/**
- * IMPORTANT: The full arguments to "main()" are needed for SDL on
- * Windows. Otherwise, one gets the linking error "undefined reference
- * to `SDL_main'". https://wiki.libsdl.org/FAQWindows
- **/
-int main(int argc, char* argv[])
-{
-  using namespace OrthancStone;
-
-  StoneInitialize();
-  Orthanc::Logging::EnableInfoLevel(true);
-//  Orthanc::Logging::EnableTraceLevel(true);
-
-  try
-  {
-    MessageBroker broker;
-    boost::shared_ptr<TrackerSampleApp> app(new TrackerSampleApp(broker));
-    g_app = app;
-    app->PrepareScene();
-    app->Run();
-  }
-  catch (Orthanc::OrthancException& e)
-  {
-    LOG(ERROR) << "EXCEPTION: " << e.What();
-  }
-
-  StoneFinalize();
-
-  return 0;
-}
-
-
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/Sdl/TrackerSampleApp.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,733 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "TrackerSampleApp.h"
-
-#include "../../Framework/OpenGL/SdlOpenGLContext.h"
-#include "../../Framework/Scene2D/CairoCompositor.h"
-#include "../../Framework/Scene2D/ColorTextureSceneLayer.h"
-#include "../../Framework/Scene2D/OpenGLCompositor.h"
-#include "../../Framework/Scene2D/PanSceneTracker.h"
-#include "../../Framework/Scene2D/RotateSceneTracker.h"
-#include "../../Framework/Scene2D/Scene2D.h"
-#include "../../Framework/Scene2D/ZoomSceneTracker.h"
-#include "../../Framework/Scene2DViewport/UndoStack.h"
-#include "../../Framework/Scene2DViewport/CreateAngleMeasureTracker.h"
-#include "../../Framework/Scene2DViewport/CreateLineMeasureTracker.h"
-#include "../../Framework/StoneInitialization.h"
-
-// From Orthanc framework
-#include <Core/Logging.h>
-#include <Core/OrthancException.h>
-#include <Core/Images/Image.h>
-#include <Core/Images/ImageProcessing.h>
-#include <Core/Images/PngWriter.h>
-
-#include <boost/ref.hpp>
-#include <boost/make_shared.hpp>
-#include <SDL.h>
-
-#include <stdio.h>
-
-namespace OrthancStone
-{
-  const char* MeasureToolToString(size_t i)
-  {
-    static const char* descs[] = {
-      "GuiTool_Rotate",
-      "GuiTool_Pan",
-      "GuiTool_Zoom",
-      "GuiTool_LineMeasure",
-      "GuiTool_CircleMeasure",
-      "GuiTool_AngleMeasure",
-      "GuiTool_EllipseMeasure",
-      "GuiTool_LAST"
-    };
-    if (i >= GuiTool_LAST)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, "Wrong tool index");
-    }
-    return descs[i];
-  }
-
-  void TrackerSampleApp::SelectNextTool()
-  {
-    currentTool_ = static_cast<GuiTool>(currentTool_ + 1);
-    if (currentTool_ == GuiTool_LAST)
-      currentTool_ = static_cast<GuiTool>(0);;
-    printf("Current tool is now: %s\n", MeasureToolToString(currentTool_));
-  }
-
-  void TrackerSampleApp::DisplayInfoText()
-  {
-    // do not try to use stuff too early!
-    std::stringstream msg;
-	
-	for (std::map<std::string, std::string>::const_iterator kv = infoTextMap_.begin();
-		kv != infoTextMap_.end(); ++kv)
-    {
-      msg << kv->first << " : " << kv->second << std::endl;
-    }
-	std::string msgS = msg.str();
-
-    TextSceneLayer* layerP = NULL;
-    if (controller_->GetScene().HasLayer(FIXED_INFOTEXT_LAYER_ZINDEX))
-    {
-      TextSceneLayer& layer = dynamic_cast<TextSceneLayer&>(
-        controller_->GetScene().GetLayer(FIXED_INFOTEXT_LAYER_ZINDEX));
-      layerP = &layer;
-    }
-    else
-    {
-      std::unique_ptr<TextSceneLayer> layer(new TextSceneLayer);
-      layerP = layer.get();
-      layer->SetColor(0, 255, 0);
-      layer->SetFontIndex(1);
-      layer->SetBorder(20);
-      layer->SetAnchor(BitmapAnchor_TopLeft);
-      //layer->SetPosition(0,0);
-      controller_->GetScene().SetLayer(FIXED_INFOTEXT_LAYER_ZINDEX, layer.release());
-    }
-    // position the fixed info text in the upper right corner
-    layerP->SetText(msgS.c_str());
-    double cX = GetCompositor().GetCanvasWidth() * (-0.5);
-    double cY = GetCompositor().GetCanvasHeight() * (-0.5);
-    controller_->GetScene().GetCanvasToSceneTransform().Apply(cX,cY);
-    layerP->SetPosition(cX, cY);
-  }
-
-  void TrackerSampleApp::DisplayFloatingCtrlInfoText(const PointerEvent& e)
-  {
-    ScenePoint2D p = e.GetMainPosition().Apply(controller_->GetScene().GetCanvasToSceneTransform());
-
-    char buf[128];
-    sprintf(buf, "S:(%0.02f,%0.02f) C:(%0.02f,%0.02f)", 
-      p.GetX(), p.GetY(), 
-      e.GetMainPosition().GetX(), e.GetMainPosition().GetY());
-
-    if (controller_->GetScene().HasLayer(FLOATING_INFOTEXT_LAYER_ZINDEX))
-    {
-      TextSceneLayer& layer =
-        dynamic_cast<TextSceneLayer&>(controller_->GetScene().GetLayer(FLOATING_INFOTEXT_LAYER_ZINDEX));
-      layer.SetText(buf);
-      layer.SetPosition(p.GetX(), p.GetY());
-    }
-    else
-    {
-      std::unique_ptr<TextSceneLayer> layer(new TextSceneLayer);
-      layer->SetColor(0, 255, 0);
-      layer->SetText(buf);
-      layer->SetBorder(20);
-      layer->SetAnchor(BitmapAnchor_BottomCenter);
-      layer->SetPosition(p.GetX(), p.GetY());
-      controller_->GetScene().SetLayer(FLOATING_INFOTEXT_LAYER_ZINDEX, layer.release());
-    }
-  }
-
-  void TrackerSampleApp::HideInfoText()
-  {
-    controller_->GetScene().DeleteLayer(FLOATING_INFOTEXT_LAYER_ZINDEX);
-  }
-
-  ScenePoint2D TrackerSampleApp::GetRandomPointInScene() const
-  {
-    unsigned int w = GetCompositor().GetCanvasWidth();
-    LOG(TRACE) << "GetCompositor().GetCanvasWidth() = " << 
-      GetCompositor().GetCanvasWidth();
-    unsigned int h = GetCompositor().GetCanvasHeight();
-    LOG(TRACE) << "GetCompositor().GetCanvasHeight() = " << 
-      GetCompositor().GetCanvasHeight();
-
-    if ((w >= RAND_MAX) || (h >= RAND_MAX))
-      LOG(WARNING) << "Canvas is too big : tools will not be randomly placed";
-
-    int x = rand() % w;
-    int y = rand() % h;
-    LOG(TRACE) << "random x = " << x << "random y = " << y;
-
-    ScenePoint2D p = controller_->GetViewport().GetPixelCenterCoordinates(x, y);
-    LOG(TRACE) << "--> p.GetX() = " << p.GetX() << " p.GetY() = " << p.GetY();
-
-    ScenePoint2D r = p.Apply(controller_->GetScene().GetCanvasToSceneTransform());
-    LOG(TRACE) << "--> r.GetX() = " << r.GetX() << " r.GetY() = " << r.GetY();
-    return r;
-  }
-
-  void TrackerSampleApp::CreateRandomMeasureTool()
-  {
-    static bool srandCalled = false;
-    if (!srandCalled)
-    {
-      srand(42);
-      srandCalled = true;
-    }
-
-    int i = rand() % 2;
-    LOG(TRACE) << "random i = " << i;
-    switch (i)
-    {
-    case 0:
-      // line measure
-      {
-        boost::shared_ptr<CreateLineMeasureCommand> cmd = 
-          boost::make_shared<CreateLineMeasureCommand>(
-		  boost::ref(IObserver::GetBroker()),
-            controller_,
-            GetRandomPointInScene());
-        cmd->SetEnd(GetRandomPointInScene());
-        controller_->PushCommand(cmd);
-      }
-      break;
-    case 1:
-      // angle measure
-      {
-      boost::shared_ptr<CreateAngleMeasureCommand> cmd =
-        boost::make_shared<CreateAngleMeasureCommand>(
-          boost::ref(IObserver::GetBroker()),
-          controller_,
-          GetRandomPointInScene());
-        cmd->SetCenter(GetRandomPointInScene());
-        cmd->SetSide2End(GetRandomPointInScene());
-        controller_->PushCommand(cmd);
-      }
-      break;
-    }
-  }
-
-  void TrackerSampleApp::HandleApplicationEvent(
-    const SDL_Event & event)
-  {
-    DisplayInfoText();
-
-    if (event.type == SDL_MOUSEMOTION)
-    {
-      int scancodeCount = 0;
-      const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount);
-
-      if (activeTracker_.get() == NULL &&
-        SDL_SCANCODE_LALT < scancodeCount &&
-        keyboardState[SDL_SCANCODE_LALT])
-      {
-        // The "left-ctrl" key is down, while no tracker is present
-        // Let's display the info text
-        PointerEvent e;
-        e.AddPosition(controller_->GetViewport().GetPixelCenterCoordinates(
-          event.button.x, event.button.y));
-
-        DisplayFloatingCtrlInfoText(e);
-      }
-      else if (activeTracker_.get() != NULL)
-      {
-        HideInfoText();
-        //LOG(TRACE) << "(event.type == SDL_MOUSEMOTION)";
-        if (activeTracker_.get() != NULL)
-        {
-          //LOG(TRACE) << "(activeTracker_.get() != NULL)";
-          PointerEvent e;
-          e.AddPosition(controller_->GetViewport().GetPixelCenterCoordinates(
-            event.button.x, event.button.y));
-          
-          //LOG(TRACE) << "event.button.x = " << event.button.x << "     " <<
-          //  "event.button.y = " << event.button.y;
-          LOG(TRACE) << "activeTracker_->PointerMove(e); " <<
-            e.GetMainPosition().GetX() << " " << e.GetMainPosition().GetY();
-          
-          activeTracker_->PointerMove(e);
-          if (!activeTracker_->IsAlive())
-            activeTracker_.reset();
-        }
-      }
-      else
-      {
-        HideInfoText();
-
-        PointerEvent e;
-        e.AddPosition(controller_->GetViewport().GetPixelCenterCoordinates(event.button.x, event.button.y));
-
-        ScenePoint2D scenePos = e.GetMainPosition().Apply(
-          controller_->GetScene().GetCanvasToSceneTransform());
-        //auto measureTools = GetController()->HitTestMeasureTools(scenePos);
-        //LOG(TRACE) << "# of hit tests: " << measureTools.size();
-        
-        // this returns the collection of measuring tools where hit test is true
-        std::vector<boost::shared_ptr<MeasureTool> > measureTools = controller_->HitTestMeasureTools(scenePos);
-
-        // let's refresh the measuring tools highlighted state
-        // first let's tag them as "unhighlighted"
-        controller_->ResetMeasuringToolsHighlight();
-
-        // then immediately take the first one and ask it to highlight the 
-        // measuring tool UI part that is hot
-        if (measureTools.size() > 0)
-        {
-          measureTools[0]->Highlight(scenePos);
-        }
-      }
-    }
-    else if (event.type == SDL_MOUSEBUTTONUP)
-    {
-      if (activeTracker_)
-      {
-        PointerEvent e;
-        e.AddPosition(controller_->GetViewport().GetPixelCenterCoordinates(event.button.x, event.button.y));
-        activeTracker_->PointerUp(e);
-        if (!activeTracker_->IsAlive())
-          activeTracker_.reset();
-      }
-    }
-    else if (event.type == SDL_MOUSEBUTTONDOWN)
-    {
-      PointerEvent e;
-      e.AddPosition(controller_->GetViewport().GetPixelCenterCoordinates(
-        event.button.x, event.button.y));
-      if (activeTracker_)
-      {
-        activeTracker_->PointerDown(e);
-        if (!activeTracker_->IsAlive())
-          activeTracker_.reset();
-      }
-      else
-      {
-        // we ATTEMPT to create a tracker if need be
-        activeTracker_ = CreateSuitableTracker(event, e);
-      }
-    }
-    else if (event.type == SDL_KEYDOWN &&
-      event.key.repeat == 0 /* Ignore key bounce */)
-    {
-      switch (event.key.keysym.sym)
-      {
-      case SDLK_ESCAPE:
-        if (activeTracker_)
-        {
-          activeTracker_->Cancel();
-          if (!activeTracker_->IsAlive())
-            activeTracker_.reset();
-        }
-        break;
-
-      case SDLK_t:
-        if (!activeTracker_)
-          SelectNextTool();
-        else
-        {
-          LOG(WARNING) << "You cannot change the active tool when an interaction"
-            " is taking place";
-        }
-        break;
-
-      case SDLK_m:
-        CreateRandomMeasureTool();
-        break;
-      case SDLK_s:
-        controller_->FitContent(GetCompositor().GetCanvasWidth(),
-          GetCompositor().GetCanvasHeight());
-        break;
-
-      case SDLK_z:
-        LOG(TRACE) << "SDLK_z has been pressed. event.key.keysym.mod == " << event.key.keysym.mod;
-        if (event.key.keysym.mod & KMOD_CTRL)
-        {
-          if (controller_->CanUndo())
-          {
-            LOG(TRACE) << "Undoing...";
-            controller_->Undo();
-          }
-          else
-          {
-            LOG(WARNING) << "Nothing to undo!!!";
-          }
-        }
-        break;
-
-      case SDLK_y:
-        LOG(TRACE) << "SDLK_y has been pressed. event.key.keysym.mod == " << event.key.keysym.mod;
-        if (event.key.keysym.mod & KMOD_CTRL)
-        {
-          if (controller_->CanRedo())
-          {
-            LOG(TRACE) << "Redoing...";
-            controller_->Redo();
-          }
-          else
-          {
-            LOG(WARNING) << "Nothing to redo!!!";
-          }
-        }
-        break;
-
-      case SDLK_c:
-        TakeScreenshot(
-          "screenshot.png",
-          GetCompositor().GetCanvasWidth(),
-          GetCompositor().GetCanvasHeight());
-        break;
-
-      default:
-        break;
-      }
-    }
-  }
-
-
-  void TrackerSampleApp::OnSceneTransformChanged(
-    const ViewportController::SceneTransformChanged& message)
-  {
-    DisplayInfoText();
-  }
-
-  boost::shared_ptr<IFlexiblePointerTracker> TrackerSampleApp::CreateSuitableTracker(
-    const SDL_Event & event,
-    const PointerEvent & e)
-  {
-    using namespace Orthanc;
-
-    switch (event.button.button)
-    {
-    case SDL_BUTTON_MIDDLE:
-      return boost::shared_ptr<IFlexiblePointerTracker>(new PanSceneTracker
-        (controller_, e));
-
-    case SDL_BUTTON_RIGHT:
-      return boost::shared_ptr<IFlexiblePointerTracker>(new ZoomSceneTracker
-        (controller_, e, GetCompositor().GetCanvasHeight()));
-
-    case SDL_BUTTON_LEFT:
-    {
-      //LOG(TRACE) << "CreateSuitableTracker: case SDL_BUTTON_LEFT:";
-      // TODO: we need to iterate on the set of measuring tool and perform
-      // a hit test to check if a tracker needs to be created for edition.
-      // Otherwise, depending upon the active tool, we might want to create
-      // a "measuring tool creation" tracker
-
-      // TODO: if there are conflicts, we should prefer a tracker that 
-      // pertains to the type of measuring tool currently selected (TBD?)
-      boost::shared_ptr<IFlexiblePointerTracker> hitTestTracker = TrackerHitTest(e);
-
-      if (hitTestTracker != NULL)
-      {
-        //LOG(TRACE) << "hitTestTracker != NULL";
-        return hitTestTracker;
-      }
-      else
-      {
-        switch (currentTool_)
-        {
-        case GuiTool_Rotate:
-          //LOG(TRACE) << "Creating RotateSceneTracker";
-          return boost::shared_ptr<IFlexiblePointerTracker>(new RotateSceneTracker(
-            controller_, e));
-        case GuiTool_Pan:
-          return boost::shared_ptr<IFlexiblePointerTracker>(new PanSceneTracker(
-            controller_, e));
-        case GuiTool_Zoom:
-          return boost::shared_ptr<IFlexiblePointerTracker>(new ZoomSceneTracker(
-            controller_, e, GetCompositor().GetCanvasHeight()));
-        //case GuiTool_AngleMeasure:
-        //  return new AngleMeasureTracker(GetScene(), e);
-        //case GuiTool_CircleMeasure:
-        //  return new CircleMeasureTracker(GetScene(), e);
-        //case GuiTool_EllipseMeasure:
-        //  return new EllipseMeasureTracker(GetScene(), e);
-        case GuiTool_LineMeasure:
-          return boost::shared_ptr<IFlexiblePointerTracker>(new CreateLineMeasureTracker(
-            IObserver::GetBroker(), controller_, e));
-        case GuiTool_AngleMeasure:
-          return boost::shared_ptr<IFlexiblePointerTracker>(new CreateAngleMeasureTracker(
-            IObserver::GetBroker(), controller_, e));
-        case GuiTool_CircleMeasure:
-          LOG(ERROR) << "Not implemented yet!";
-          return boost::shared_ptr<IFlexiblePointerTracker>();
-        case GuiTool_EllipseMeasure:
-          LOG(ERROR) << "Not implemented yet!";
-          return boost::shared_ptr<IFlexiblePointerTracker>();
-        default:
-          throw OrthancException(ErrorCode_InternalError, "Wrong tool!");
-        }
-      }
-    }
-    default:
-      return boost::shared_ptr<IFlexiblePointerTracker>();
-    }
-  }
-
-
-  TrackerSampleApp::TrackerSampleApp(MessageBroker& broker) : IObserver(broker)
-    , currentTool_(GuiTool_Rotate)
-    , undoStack_(new UndoStack)
-    , viewport_("Hello", 1024, 1024, false) // False means we do NOT let Windows treat this as a legacy application that needs to be scaled
-  {
-    controller_ = boost::shared_ptr<ViewportController>(
-      new ViewportController(undoStack_, broker, viewport_));
-
-    controller_->RegisterObserverCallback(
-      new Callable<TrackerSampleApp, ViewportController::SceneTransformChanged>
-      (*this, &TrackerSampleApp::OnSceneTransformChanged));
-
-    TEXTURE_2x2_1_ZINDEX = 1;
-    TEXTURE_1x1_ZINDEX = 2;
-    TEXTURE_2x2_2_ZINDEX = 3;
-    LINESET_1_ZINDEX = 4;
-    LINESET_2_ZINDEX = 5;
-    FLOATING_INFOTEXT_LAYER_ZINDEX = 6;
-    FIXED_INFOTEXT_LAYER_ZINDEX = 7;
-  }
-
-  void TrackerSampleApp::PrepareScene()
-  {
-    // Texture of 2x2 size
-    {
-      Orthanc::Image i(Orthanc::PixelFormat_RGB24, 2, 2, false);
-
-      uint8_t* p = reinterpret_cast<uint8_t*>(i.GetRow(0));
-      p[0] = 255;
-      p[1] = 0;
-      p[2] = 0;
-
-      p[3] = 0;
-      p[4] = 255;
-      p[5] = 0;
-
-      p = reinterpret_cast<uint8_t*>(i.GetRow(1));
-      p[0] = 0;
-      p[1] = 0;
-      p[2] = 255;
-
-      p[3] = 255;
-      p[4] = 0;
-      p[5] = 0;
-
-      controller_->GetScene().SetLayer(TEXTURE_2x2_1_ZINDEX, new ColorTextureSceneLayer(i));
-
-      std::unique_ptr<ColorTextureSceneLayer> l(new ColorTextureSceneLayer(i));
-      l->SetOrigin(-3, 2);
-      l->SetPixelSpacing(1.5, 1);
-      l->SetAngle(20.0 / 180.0 * M_PI);
-      controller_->GetScene().SetLayer(TEXTURE_2x2_2_ZINDEX, l.release());
-    }
-
-    // Texture of 1x1 size
-    {
-      Orthanc::Image i(Orthanc::PixelFormat_RGB24, 1, 1, false);
-
-      uint8_t* p = reinterpret_cast<uint8_t*>(i.GetRow(0));
-      p[0] = 255;
-      p[1] = 0;
-      p[2] = 0;
-
-      std::unique_ptr<ColorTextureSceneLayer> l(new ColorTextureSceneLayer(i));
-      l->SetOrigin(-2, 1);
-      l->SetAngle(20.0 / 180.0 * M_PI);
-      controller_->GetScene().SetLayer(TEXTURE_1x1_ZINDEX, l.release());
-    }
-
-    // Some lines
-    {
-      std::unique_ptr<PolylineSceneLayer> layer(new PolylineSceneLayer);
-
-      layer->SetThickness(1);
-
-      PolylineSceneLayer::Chain chain;
-      chain.push_back(ScenePoint2D(0 - 0.5, 0 - 0.5));
-      chain.push_back(ScenePoint2D(0 - 0.5, 2 - 0.5));
-      chain.push_back(ScenePoint2D(2 - 0.5, 2 - 0.5));
-      chain.push_back(ScenePoint2D(2 - 0.5, 0 - 0.5));
-      layer->AddChain(chain, true, 255, 0, 0);
-
-      chain.clear();
-      chain.push_back(ScenePoint2D(-5, -5));
-      chain.push_back(ScenePoint2D(5, -5));
-      chain.push_back(ScenePoint2D(5, 5));
-      chain.push_back(ScenePoint2D(-5, 5));
-      layer->AddChain(chain, true, 0, 255, 0);
-
-      double dy = 1.01;
-      chain.clear();
-      chain.push_back(ScenePoint2D(-4, -4));
-      chain.push_back(ScenePoint2D(4, -4 + dy));
-      chain.push_back(ScenePoint2D(-4, -4 + 2.0 * dy));
-      chain.push_back(ScenePoint2D(4, 2));
-      layer->AddChain(chain, false, 0, 0, 255);
-
-      controller_->GetScene().SetLayer(LINESET_1_ZINDEX, layer.release());
-    }
-
-    // Some text
-    {
-      std::unique_ptr<TextSceneLayer> layer(new TextSceneLayer);
-      layer->SetText("Hello");
-      controller_->GetScene().SetLayer(LINESET_2_ZINDEX, layer.release());
-    }
-  }
-
-
-  void TrackerSampleApp::DisableTracker()
-  {
-    if (activeTracker_)
-    {
-      activeTracker_->Cancel();
-      activeTracker_.reset();
-    }
-  }
-
-  void TrackerSampleApp::TakeScreenshot(const std::string& target,
-    unsigned int canvasWidth,
-    unsigned int canvasHeight)
-  {
-    CairoCompositor compositor(controller_->GetScene(), canvasWidth, canvasHeight);
-    compositor.SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, FONT_SIZE_0, Orthanc::Encoding_Latin1);
-    compositor.Refresh();
-
-    Orthanc::ImageAccessor canvas;
-    compositor.GetCanvas().GetReadOnlyAccessor(canvas);
-
-    Orthanc::Image png(Orthanc::PixelFormat_RGB24, canvas.GetWidth(), canvas.GetHeight(), false);
-    Orthanc::ImageProcessing::Convert(png, canvas);
-
-    Orthanc::PngWriter writer;
-    writer.WriteToFile(target, png);
-  }
-
-
-  boost::shared_ptr<IFlexiblePointerTracker> TrackerSampleApp::TrackerHitTest(const PointerEvent & e)
-  {
-    // std::vector<boost::shared_ptr<MeasureTool>> measureTools_;
-    ScenePoint2D scenePos = e.GetMainPosition().Apply(
-      controller_->GetScene().GetCanvasToSceneTransform());
-
-    std::vector<boost::shared_ptr<MeasureTool> > measureTools = controller_->HitTestMeasureTools(scenePos);
-
-    if (measureTools.size() > 0)
-    {
-      return measureTools[0]->CreateEditionTracker(e);
-    }
-    return boost::shared_ptr<IFlexiblePointerTracker>();
-  }
-
-  static void GLAPIENTRY
-    OpenGLMessageCallback(GLenum source,
-      GLenum type,
-      GLuint id,
-      GLenum severity,
-      GLsizei length,
-      const GLchar* message,
-      const void* userParam)
-  {
-    if (severity != GL_DEBUG_SEVERITY_NOTIFICATION)
-    {
-      fprintf(stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n",
-        (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""),
-        type, severity, message);
-    }
-  }
-
-  static bool g_stopApplication = false;
-  
-  ICompositor& TrackerSampleApp::GetCompositor()
-  {
-    using namespace Orthanc;
-    try
-    {
-      SdlViewport& viewport = dynamic_cast<SdlViewport&>(viewport_);
-      return viewport.GetCompositor();
-    }
-    catch (std::bad_cast e)
-    {
-      throw OrthancException(ErrorCode_InternalError, "Wrong viewport type!");
-     }
-  }
-
-  const ICompositor& TrackerSampleApp::GetCompositor() const
-  {
-    using namespace Orthanc;
-    try
-    {
-      SdlViewport& viewport = const_cast<SdlViewport&>(dynamic_cast<const SdlViewport&>(viewport_));
-      return viewport.GetCompositor();
-    }
-    catch (std::bad_cast e)
-    {
-      throw OrthancException(ErrorCode_InternalError, "Wrong viewport type!");
-    }
-  }
-
-
-  void TrackerSampleApp::Run()
-  {
-    controller_->FitContent(viewport_.GetCanvasWidth(), viewport_.GetCanvasHeight());
-
-    glEnable(GL_DEBUG_OUTPUT);
-    glDebugMessageCallback(OpenGLMessageCallback, 0);
-
-    GetCompositor().SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT,
-      FONT_SIZE_0, Orthanc::Encoding_Latin1);
-    GetCompositor().SetFont(1, Orthanc::EmbeddedResources::UBUNTU_FONT,
-      FONT_SIZE_1, Orthanc::Encoding_Latin1);
-
-    while (!g_stopApplication)
-    {
-      GetCompositor().Refresh();
-
-      SDL_Event event;
-      while (!g_stopApplication && SDL_PollEvent(&event))
-      {
-        if (event.type == SDL_QUIT)
-        {
-          g_stopApplication = true;
-          break;
-        }
-        else if (event.type == SDL_WINDOWEVENT &&
-          event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
-        {
-          DisableTracker(); // was: tracker.reset(NULL);
-        }
-        else if (event.type == SDL_KEYDOWN &&
-          event.key.repeat == 0 /* Ignore key bounce */)
-        {
-          switch (event.key.keysym.sym)
-          {
-          case SDLK_f:
-            viewport_.GetWindow().ToggleMaximize();
-            break;
-
-          case SDLK_q:
-            g_stopApplication = true;
-            break;
-          default:
-            break;
-          }
-        }
-        HandleApplicationEvent(event);
-      }
-      SDL_Delay(1);
-    }
-  }
-
-  void TrackerSampleApp::SetInfoDisplayMessage(
-    std::string key, std::string value)
-  {
-    if (value == "")
-      infoTextMap_.erase(key);
-    else
-      infoTextMap_[key] = value;
-    DisplayInfoText();
-  }
-
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/Sdl/TrackerSampleApp.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Framework/Messages/IObserver.h"
-#include "../../Framework/Scene2D/OpenGLCompositor.h"
-#include "../../Framework/Scene2DViewport/IFlexiblePointerTracker.h"
-#include "../../Framework/Scene2DViewport/MeasureTool.h"
-#include "../../Framework/Scene2DViewport/PredeclaredTypes.h"
-#include "../../Framework/Scene2DViewport/ViewportController.h"
-#include "../../Framework/Viewport/SdlViewport.h"
-
-#include <SDL.h>
-
-#include <boost/make_shared.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/enable_shared_from_this.hpp>
-
-namespace OrthancStone
-{
-  enum GuiTool
-  {
-    GuiTool_Rotate = 0,
-    GuiTool_Pan,
-    GuiTool_Zoom,
-    GuiTool_LineMeasure,
-    GuiTool_CircleMeasure,
-    GuiTool_AngleMeasure,
-    GuiTool_EllipseMeasure,
-    GuiTool_LAST
-  };
-
-  const char* MeasureToolToString(size_t i);
-
-  static const unsigned int FONT_SIZE_0 = 32;
-  static const unsigned int FONT_SIZE_1 = 24;
-
-  class Scene2D;
-  class UndoStack;
-
-  class TrackerSampleApp : public IObserver
-    , public boost::enable_shared_from_this<TrackerSampleApp>
-  {
-  public:
-    // 12 because.
-    TrackerSampleApp(MessageBroker& broker);
-    void PrepareScene();
-    void Run();
-    void SetInfoDisplayMessage(std::string key, std::string value);
-    void DisableTracker();
-
-    void HandleApplicationEvent(const SDL_Event& event);
-
-    /**
-    This method is called when the scene transform changes. It allows to
-    recompute the visual elements whose content depend upon the scene transform
-    */
-    void OnSceneTransformChanged(
-      const ViewportController::SceneTransformChanged& message);
-
-  private:
-    void SelectNextTool();
-    void CreateRandomMeasureTool();
-
-
-    /**
-    In the case of this app, the viewport is an SDL viewport and it has 
-    a OpenGLCompositor& GetCompositor() method
-    */
-    ICompositor& GetCompositor();
-
-    /**
-    See the other overload
-    */
-    const ICompositor& GetCompositor() const;
-
-    /**
-    This returns a random point in the canvas part of the scene, but in
-    scene coordinates
-    */
-    ScenePoint2D GetRandomPointInScene() const;
-
-    boost::shared_ptr<IFlexiblePointerTracker> TrackerHitTest(const PointerEvent& e);
-
-    boost::shared_ptr<IFlexiblePointerTracker> CreateSuitableTracker(
-      const SDL_Event& event,
-      const PointerEvent& e);
-
-    void TakeScreenshot(
-      const std::string& target,
-      unsigned int canvasWidth,
-      unsigned int canvasHeight);
-
-    /**
-      This adds the command at the top of the undo stack
-    */
-    void Commit(boost::shared_ptr<TrackerCommand> cmd);
-    void Undo();
-    void Redo();
-
-  private:
-    void DisplayFloatingCtrlInfoText(const PointerEvent& e);
-    void DisplayInfoText();
-    void HideInfoText();
-
-  private:
-    /**
-    WARNING: the measuring tools do store a reference to the scene, and it 
-    paramount that the scene gets destroyed AFTER the measurement tools.
-    */
-    boost::shared_ptr<ViewportController> controller_;
-
-    std::map<std::string, std::string> infoTextMap_;
-    boost::shared_ptr<IFlexiblePointerTracker> activeTracker_;
-
-    //static const int LAYER_POSITION = 150;
-
-    int TEXTURE_2x2_1_ZINDEX;
-    int TEXTURE_1x1_ZINDEX;
-    int TEXTURE_2x2_2_ZINDEX;
-    int LINESET_1_ZINDEX;
-    int LINESET_2_ZINDEX;
-    int FLOATING_INFOTEXT_LAYER_ZINDEX;
-    int FIXED_INFOTEXT_LAYER_ZINDEX;
-
-    GuiTool currentTool_;
-    boost::shared_ptr<UndoStack> undoStack_;
-    SdlOpenGLViewport viewport_;
-  };
-
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/Sdl/cpp.hint	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-#define ORTHANC_OVERRIDE
-#define ORTHANC_STONE_DEFINE_EMPTY_MESSAGE(FILE, LINE, NAME) class NAME : public ::OrthancStone::IMessage {};
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/WebAssembly/BasicMPR.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,427 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-
-#include "dev.h"
-
-#include <emscripten.h>
-
-#include "../../Framework/Loaders/OrthancSeriesVolumeProgressiveLoader.h"
-#include "../../Framework/Oracle/SleepOracleCommand.h"
-#include "../../Framework/Oracle/WebAssemblyOracle.h"
-#include "../../Framework/Scene2D/GrayscaleStyleConfigurator.h"
-#include "../../Framework/StoneInitialization.h"
-#include "../../Framework/Volumes/VolumeSceneLayerSource.h"
-
-
-namespace OrthancStone
-{
-  class VolumeSlicerWidget : public IObserver
-  {
-  private:
-    OrthancStone::WebAssemblyViewport      viewport_;
-    std::unique_ptr<VolumeSceneLayerSource>  source_;
-    VolumeProjection                       projection_;
-    std::vector<CoordinateSystem3D>        planes_;
-    size_t                                 currentPlane_;
-
-    void Handle(const DicomVolumeImage::GeometryReadyMessage& message)
-    {
-      LOG(INFO) << "Geometry is available";
-
-      const VolumeImageGeometry& geometry = message.GetOrigin().GetGeometry();
-
-      const unsigned int depth = geometry.GetProjectionDepth(projection_);
-      currentPlane_ = depth / 2;
-      
-      planes_.resize(depth);
-
-      for (unsigned int z = 0; z < depth; z++)
-      {
-        planes_[z] = geometry.GetProjectionSlice(projection_, z);
-      }
-
-      Refresh();
-
-      viewport_.FitContent();
-    }
-    
-  public:
-    VolumeSlicerWidget(MessageBroker& broker,
-                         const std::string& canvas,
-                         VolumeProjection projection) :
-      IObserver(broker),
-      viewport_(broker, canvas),
-      projection_(projection),
-      currentPlane_(0)
-    {
-    }
-
-    void UpdateSize()
-    {
-      viewport_.UpdateSize();
-    }
-
-    void SetSlicer(int layerDepth,
-                   const boost::shared_ptr<IVolumeSlicer>& slicer,
-                   IObservable& loader,
-                   ILayerStyleConfigurator* configurator)
-    {
-      if (source_.get() != NULL)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls,
-                                        "Only one slicer can be registered");
-      }
-      
-      loader.RegisterObserverCallback(
-        new Callable<VolumeSlicerWidget, DicomVolumeImage::GeometryReadyMessage>
-        (*this, &VolumeSlicerWidget::Handle));
-
-      source_.reset(new VolumeSceneLayerSource(viewport_.GetScene(), layerDepth, slicer));
-
-      if (configurator != NULL)
-      {
-        source_->SetConfigurator(configurator);
-      }
-    }    
-
-    void Refresh()
-    {
-      if (source_.get() != NULL &&
-          currentPlane_ < planes_.size())
-      {
-        source_->Update(planes_[currentPlane_]);
-        viewport_.Refresh();
-      }
-    }
-
-    size_t GetSlicesCount() const
-    {
-      return planes_.size();
-    }
-
-    void Scroll(int delta)
-    {
-      if (!planes_.empty())
-      {
-        int tmp = static_cast<int>(currentPlane_) + delta;
-        unsigned int next;
-
-        if (tmp < 0)
-        {
-          next = 0;
-        }
-        else if (tmp >= static_cast<int>(planes_.size()))
-        {
-          next = planes_.size() - 1;
-        }
-        else
-        {
-          next = static_cast<size_t>(tmp);
-        }
-
-        if (next != currentPlane_)
-        {
-          currentPlane_ = next;
-          Refresh();
-        }
-      }
-    }
-  };
-}
-
-
-
-
-boost::shared_ptr<OrthancStone::DicomVolumeImage>  ct_(new OrthancStone::DicomVolumeImage);
-
-boost::shared_ptr<OrthancStone::OrthancSeriesVolumeProgressiveLoader>  loader_;
-
-std::unique_ptr<OrthancStone::VolumeSlicerWidget>  widget1_;
-std::unique_ptr<OrthancStone::VolumeSlicerWidget>  widget2_;
-std::unique_ptr<OrthancStone::VolumeSlicerWidget>  widget3_;
-
-OrthancStone::MessageBroker  broker_;
-OrthancStone::WebAssemblyOracle  oracle_(broker_);
-
-
-EM_BOOL OnWindowResize(int eventType, const EmscriptenUiEvent *uiEvent, void *userData)
-{
-  try
-  {
-    if (widget1_.get() != NULL)
-    {
-      widget1_->UpdateSize();
-    }
-  
-    if (widget2_.get() != NULL)
-    {
-      widget2_->UpdateSize();
-    }
-  
-    if (widget3_.get() != NULL)
-    {
-      widget3_->UpdateSize();
-    }
-  }
-  catch (Orthanc::OrthancException& e)
-  {
-    LOG(ERROR) << "Exception while updating canvas size: " << e.What();
-  }
-  
-  return true;
-}
-
-
-
-
-EM_BOOL OnAnimationFrame(double time, void *userData)
-{
-  try
-  {
-    if (widget1_.get() != NULL)
-    {
-      widget1_->Refresh();
-    }
-  
-    if (widget2_.get() != NULL)
-    {
-      widget2_->Refresh();
-    }
-  
-    if (widget3_.get() != NULL)
-    {
-      widget3_->Refresh();
-    }
-
-    return true;
-  }
-  catch (Orthanc::OrthancException& e)
-  {
-    LOG(ERROR) << "Exception in the animation loop, stopping now: " << e.What();
-    return false;
-  }  
-}
-
-
-static bool ctrlDown_ = false;
-
-
-EM_BOOL OnMouseWheel(int eventType,
-                     const EmscriptenWheelEvent *wheelEvent,
-                     void *userData)
-{
-  try
-  {
-    if (userData != NULL)
-    {
-      int delta = 0;
-
-      if (wheelEvent->deltaY < 0)
-      {
-        delta = -1;
-      }
-           
-      if (wheelEvent->deltaY > 0)
-      {
-        delta = 1;
-      }
-
-      OrthancStone::VolumeSlicerWidget& widget =
-        *reinterpret_cast<OrthancStone::VolumeSlicerWidget*>(userData);
-      
-      if (ctrlDown_)
-      {
-        delta *= static_cast<int>(widget.GetSlicesCount() / 10);
-      }
-
-      widget.Scroll(delta);
-    }
-  }
-  catch (Orthanc::OrthancException& e)
-  {
-    LOG(ERROR) << "Exception in the wheel event: " << e.What();
-  }
-  
-  return true;
-}
-
-
-EM_BOOL OnKeyDown(int eventType,
-                  const EmscriptenKeyboardEvent *keyEvent,
-                  void *userData)
-{
-  ctrlDown_ = keyEvent->ctrlKey;
-  return false;
-}
-
-
-EM_BOOL OnKeyUp(int eventType,
-                const EmscriptenKeyboardEvent *keyEvent,
-                void *userData)
-{
-  ctrlDown_ = false;
-  return false;
-}
-
-
-
-
-namespace OrthancStone
-{
-  class TestSleep : public IObserver
-  {
-  private:
-    WebAssemblyOracle&  oracle_;
-
-    void Schedule()
-    {
-      oracle_.Schedule(*this, new OrthancStone::SleepOracleCommand(2000));
-    }
-    
-    void Handle(const SleepOracleCommand::TimeoutMessage& message)
-    {
-      LOG(INFO) << "TIMEOUT";
-      Schedule();
-    }
-    
-  public:
-    TestSleep(MessageBroker& broker,
-              WebAssemblyOracle& oracle) :
-      IObserver(broker),
-      oracle_(oracle)
-    {
-      oracle.RegisterObserverCallback(
-        new Callable<TestSleep, SleepOracleCommand::TimeoutMessage>
-        (*this, &TestSleep::Handle));
-
-      LOG(INFO) << "STARTING";
-      Schedule();
-    }
-  };
-
-  //static TestSleep testSleep(broker_, oracle_);
-}
-
-
-
-static std::map<std::string, std::string> arguments_;
-
-static bool GetArgument(std::string& value,
-                        const std::string& key)
-{
-  std::map<std::string, std::string>::const_iterator found = arguments_.find(key);
-
-  if (found == arguments_.end())
-  {
-    return false;
-  }
-  else
-  {
-    value = found->second;
-    return true;
-  }
-}
-
-
-extern "C"
-{
-  int main(int argc, char const *argv[]) 
-  {
-    OrthancStone::StoneInitialize();
-    Orthanc::Logging::EnableInfoLevel(true);
-    // Orthanc::Logging::EnableTraceLevel(true);
-    EM_ASM(window.dispatchEvent(new CustomEvent("WebAssemblyLoaded")););
-  }
-
-  EMSCRIPTEN_KEEPALIVE
-  void SetArgument(const char* key, const char* value)
-  {
-    // This is called for each GET argument (cf. "app.js")
-    LOG(INFO) << "Received GET argument: [" << key << "] = [" << value << "]";
-    arguments_[key] = value;
-  }
-
-  EMSCRIPTEN_KEEPALIVE
-  void Initialize()
-  {
-    try
-    {
-      oracle_.SetOrthancRoot("..");
-      
-      loader_.reset(new OrthancStone::OrthancSeriesVolumeProgressiveLoader(ct_, oracle_, oracle_));
-    
-      widget1_.reset(new OrthancStone::VolumeSlicerWidget(broker_, "mycanvas1", OrthancStone::VolumeProjection_Axial));
-      {
-        std::unique_ptr<OrthancStone::GrayscaleStyleConfigurator> style(new OrthancStone::GrayscaleStyleConfigurator);
-        style->SetLinearInterpolation(true);
-        style->SetWindowing(OrthancStone::ImageWindowing_Bone);
-        widget1_->SetSlicer(0, loader_, *loader_, style.release());
-      }
-      widget1_->UpdateSize();
-
-      widget2_.reset(new OrthancStone::VolumeSlicerWidget(broker_, "mycanvas2", OrthancStone::VolumeProjection_Coronal));
-      {
-        std::unique_ptr<OrthancStone::GrayscaleStyleConfigurator> style(new OrthancStone::GrayscaleStyleConfigurator);
-        style->SetLinearInterpolation(true);
-        style->SetWindowing(OrthancStone::ImageWindowing_Bone);
-        widget2_->SetSlicer(0, loader_, *loader_, style.release());
-      }
-      widget2_->UpdateSize();
-
-      widget3_.reset(new OrthancStone::VolumeSlicerWidget(broker_, "mycanvas3", OrthancStone::VolumeProjection_Sagittal));
-      {
-        std::unique_ptr<OrthancStone::GrayscaleStyleConfigurator> style(new OrthancStone::GrayscaleStyleConfigurator);
-        style->SetLinearInterpolation(true);
-        style->SetWindowing(OrthancStone::ImageWindowing_Bone);
-        widget3_->SetSlicer(0, loader_, *loader_, style.release());
-      }
-      widget3_->UpdateSize();
-
-      emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, false, OnWindowResize); // DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1 !!
-
-      emscripten_set_wheel_callback("#mycanvas1", widget1_.get(), false, OnMouseWheel);
-      emscripten_set_wheel_callback("#mycanvas2", widget2_.get(), false, OnMouseWheel);
-      emscripten_set_wheel_callback("#mycanvas3", widget3_.get(), false, OnMouseWheel);
-
-      emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, false, OnKeyDown);
-      emscripten_set_keyup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, false, OnKeyUp);
-    
-      emscripten_request_animation_frame_loop(OnAnimationFrame, NULL);
-
-
-      std::string ct;
-      if (GetArgument(ct, "ct"))
-      {
-        //loader_->LoadSeries("a04ecf01-79b2fc33-58239f7e-ad9db983-28e81afa");
-        loader_->LoadSeries(ct);
-      }
-      else
-      {
-        LOG(ERROR) << "No Orthanc identifier for the CT series was provided";
-      }
-    }
-    catch (Orthanc::OrthancException& e)
-    {
-      LOG(ERROR) << "Exception during Initialize(): " << e.What();
-    }
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/WebAssembly/BasicMPR.html	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-<!doctype html>
-<html lang="en-us">
-  <head>
-    <meta charset="utf-8">
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-
-    <!-- Disable pinch zoom on mobile devices -->
-    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
-    <meta name="HandheldFriendly" content="true" />
-    
-    
-    <title>Stone of Orthanc</title>
-
-    <style>
-      html, body {
-      width: 100%;
-      height: 100%;
-      margin: 0px;
-      border: 0;
-      overflow: hidden; /*  Disable scrollbars */
-      display: block;  /* No floating content on sides */
-      }
-
-      #mycanvas1 {
-      position:absolute;
-      left:0%;
-      top:0%;
-      background-color: red;
-      width: 50%;
-      height: 100%;
-      }
-
-      #mycanvas2 {
-      position:absolute;
-      left:50%;
-      top:0%;
-      background-color: green;
-      width: 50%;
-      height: 50%;
-      }
-
-      #mycanvas3 {
-      position:absolute;
-      left:50%;
-      top:50%;
-      background-color: blue;
-      width: 50%;
-      height: 50%;
-      }
-    </style>
-  </head>
-  <body>
-    <canvas id="mycanvas1" oncontextmenu="return false;"></canvas>
-    <canvas id="mycanvas2" oncontextmenu="return false;"></canvas>
-    <canvas id="mycanvas3" oncontextmenu="return false;"></canvas>
-
-    <script type="text/javascript" src="app.js"></script>
-    <script type="text/javascript" async src="BasicMPR.js"></script>
-  </body>
-</html>
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/WebAssembly/BasicScene.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "dev.h"
-
-#include <emscripten.h>
-#include <emscripten/html5.h>
-
-// From Stone
-#include "../../Framework/Scene2D/ColorTextureSceneLayer.h"
-#include "../../Framework/StoneInitialization.h"
-
-// From Orthanc framework
-#include <Core/Images/Image.h>
-#include <Core/Logging.h>
-#include <Core/OrthancException.h>
-
-void PrepareScene(OrthancStone::Scene2D& scene)
-{
-  using namespace OrthancStone;
-
-  // Texture of 2x2 size
-  if (1)
-  {
-    Orthanc::Image i(Orthanc::PixelFormat_RGB24, 2, 2, false);
-    
-    uint8_t *p = reinterpret_cast<uint8_t*>(i.GetRow(0));
-    p[0] = 255;
-    p[1] = 0;
-    p[2] = 0;
-
-    p[3] = 0;
-    p[4] = 255;
-    p[5] = 0;
-
-    p = reinterpret_cast<uint8_t*>(i.GetRow(1));
-    p[0] = 0;
-    p[1] = 0;
-    p[2] = 255;
-
-    p[3] = 255;
-    p[4] = 0;
-    p[5] = 0;
-
-    scene.SetLayer(12, new ColorTextureSceneLayer(i));
-
-    std::unique_ptr<ColorTextureSceneLayer> l(new ColorTextureSceneLayer(i));
-    l->SetOrigin(-3, 2);
-    l->SetPixelSpacing(1.5, 1);
-    l->SetAngle(20.0 / 180.0 * M_PI);
-    scene.SetLayer(14, l.release());
-  }
-
-  // Texture of 1x1 size
-  if (1)
-  {
-    Orthanc::Image i(Orthanc::PixelFormat_RGB24, 1, 1, false);
-    
-    uint8_t *p = reinterpret_cast<uint8_t*>(i.GetRow(0));
-    p[0] = 255;
-    p[1] = 0;
-    p[2] = 0;
-
-    std::unique_ptr<ColorTextureSceneLayer> l(new ColorTextureSceneLayer(i));
-    l->SetOrigin(-2, 1);
-    l->SetAngle(20.0 / 180.0 * M_PI);
-    scene.SetLayer(13, l.release());
-  }
-
-  // Some lines
-  if (1)
-  {
-    std::unique_ptr<PolylineSceneLayer> layer(new PolylineSceneLayer);
-
-    layer->SetThickness(1);
-
-    PolylineSceneLayer::Chain chain;
-    chain.push_back(ScenePoint2D(0 - 0.5, 0 - 0.5));
-    chain.push_back(ScenePoint2D(0 - 0.5, 2 - 0.5));
-    chain.push_back(ScenePoint2D(2 - 0.5, 2 - 0.5));
-    chain.push_back(ScenePoint2D(2 - 0.5, 0 - 0.5));
-    layer->AddChain(chain, true, 255, 0, 0);
-
-    chain.clear();
-    chain.push_back(ScenePoint2D(-5, -5));
-    chain.push_back(ScenePoint2D(5, -5));
-    chain.push_back(ScenePoint2D(5, 5));
-    chain.push_back(ScenePoint2D(-5, 5));
-    layer->AddChain(chain, true, 0, 255, 0);
-
-    double dy = 1.01;
-    chain.clear();
-    chain.push_back(ScenePoint2D(-4, -4));
-    chain.push_back(ScenePoint2D(4, -4 + dy));
-    chain.push_back(ScenePoint2D(-4, -4 + 2.0 * dy));
-    chain.push_back(ScenePoint2D(4, 2));
-    layer->AddChain(chain, false, 0, 0, 255);
-
-    scene.SetLayer(50, layer.release());
-  }
-
-  // Some text
-  if (1)
-  {
-    std::unique_ptr<TextSceneLayer> layer(new TextSceneLayer);
-    layer->SetText("Hello");
-    scene.SetLayer(100, layer.release());
-  }
-}
-
-
-std::unique_ptr<OrthancStone::WebAssemblyViewport>  viewport1_;
-std::unique_ptr<OrthancStone::WebAssemblyViewport>  viewport2_;
-std::unique_ptr<OrthancStone::WebAssemblyViewport>  viewport3_;
-boost::shared_ptr<OrthancStone::ViewportController>   controller1_;
-boost::shared_ptr<OrthancStone::ViewportController>   controller2_;
-boost::shared_ptr<OrthancStone::ViewportController>   controller3_;
-OrthancStone::MessageBroker broker_;
-
-
-EM_BOOL OnWindowResize(
-  int eventType, const EmscriptenUiEvent *uiEvent, void *userData)
-{
-  if (viewport1_.get() != NULL)
-  {
-    viewport1_->UpdateSize();
-  }
-  
-  if (viewport2_.get() != NULL)
-  {
-    viewport2_->UpdateSize();
-  }
-  
-  if (viewport3_.get() != NULL)
-  {
-    viewport3_->UpdateSize();
-  }
-  
-  return true;
-}
-
-extern "C"
-{
-  int main(int argc, char const *argv[]) 
-  {
-    OrthancStone::StoneInitialize();
-    // Orthanc::Logging::EnableInfoLevel(true);
-    // Orthanc::Logging::EnableTraceLevel(true);
-    EM_ASM(window.dispatchEvent(new CustomEvent("WebAssemblyLoaded")););
-  }
-
-  EMSCRIPTEN_KEEPALIVE
-  void Initialize()
-  {
-    viewport1_.reset(new OrthancStone::WebAssemblyViewport("mycanvas1"));
-    PrepareScene(viewport1_->GetScene());
-    viewport1_->UpdateSize();
-
-    viewport2_.reset(new OrthancStone::WebAssemblyViewport("mycanvas2"));
-    PrepareScene(viewport2_->GetScene());
-    viewport2_->UpdateSize();
-
-    viewport3_.reset(new OrthancStone::WebAssemblyViewport("mycanvas3"));
-    PrepareScene(viewport3_->GetScene());
-    viewport3_->UpdateSize();
-
-    viewport1_->GetCompositor().SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, 
-                                        FONT_SIZE, Orthanc::Encoding_Latin1);
-    viewport2_->GetCompositor().SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, 
-                                        FONT_SIZE, Orthanc::Encoding_Latin1);
-    viewport3_->GetCompositor().SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT, 
-                                        FONT_SIZE, Orthanc::Encoding_Latin1);
-
-    controller1_.reset(new OrthancStone::ViewportController(boost::make_shared<OrthancStone::UndoStack>(), broker_, *viewport1_));
-    controller2_.reset(new OrthancStone::ViewportController(boost::make_shared<OrthancStone::UndoStack>(), broker_, *viewport2_));
-    controller3_.reset(new OrthancStone::ViewportController(boost::make_shared<OrthancStone::UndoStack>(), broker_, *viewport3_));
-
-    controller1_->FitContent(viewport1_->GetCanvasWidth(), viewport1_->GetCanvasHeight());
-    controller2_->FitContent(viewport2_->GetCanvasWidth(), viewport2_->GetCanvasHeight());
-    controller3_->FitContent(viewport3_->GetCanvasWidth(), viewport3_->GetCanvasHeight());
-
-    viewport1_->Refresh();
-    viewport2_->Refresh();
-    viewport3_->Refresh();
-
-    SetupEvents("mycanvas1", controller1_);
-    SetupEvents("mycanvas2", controller2_);
-    SetupEvents("mycanvas3", controller3_);
-
-    emscripten_set_resize_callback("#window", NULL, false, OnWindowResize);
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/WebAssembly/BasicScene.html	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-<!doctype html>
-<html lang="en-us">
-  <head>
-    <meta charset="utf-8">
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-
-    <!-- Disable pinch zoom on mobile devices -->
-    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
-    <meta name="HandheldFriendly" content="true" />
-    
-    
-    <title>Stone of Orthanc</title>
-
-    <style>
-      html, body {
-      width: 100%;
-      height: 100%;
-      margin: 0px;
-      border: 0;
-      overflow: hidden; /*  Disable scrollbars */
-      display: block;  /* No floating content on sides */
-      }
-
-      #mycanvas1 {
-      position:absolute;
-      left:0%;
-      top:0%;
-      background-color: red;
-      width: 50%;
-      height: 100%;
-      }
-
-      #mycanvas2 {
-      position:absolute;
-      left:50%;
-      top:0%;
-      background-color: green;
-      width: 50%;
-      height: 50%;
-      }
-
-      #mycanvas3 {
-      position:absolute;
-      left:50%;
-      top:50%;
-      background-color: blue;
-      width: 50%;
-      height: 50%;
-      }
-    </style>
-  </head>
-  <body>
-    <canvas id="mycanvas1" oncontextmenu="return false;"></canvas>
-    <canvas id="mycanvas2" oncontextmenu="return false;"></canvas>
-    <canvas id="mycanvas3" oncontextmenu="return false;"></canvas>
-
-    <script type="text/javascript">
-      if (!('WebAssembly' in window)) {
-      alert('Sorry, your browser does not support WebAssembly :(');
-      } else {
-      window.addEventListener('WebAssemblyLoaded', function() {
-      Module.ccall('Initialize', null, null, null);
-      });
-      }
-    </script>
-
-    <script type="text/javascript" async src="BasicScene.js"></script>
-  </body>
-</html>
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/WebAssembly/CMakeLists.txt	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-cmake_minimum_required(VERSION 2.8.3)
-
-
-#####################################################################
-## Configuration of the Emscripten compiler for WebAssembly target
-#####################################################################
-
-set(WASM_FLAGS "-s WASM=1 -s FETCH=1")
-
-set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WASM_FLAGS}")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WASM_FLAGS}")
-set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXTRA_EXPORTED_RUNTIME_METHODS='[\"ccall\", \"cwrap\"]'")
-set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ERROR_ON_UNDEFINED_SYMBOLS=1")
-set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ALLOW_MEMORY_GROWTH=1")
-set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s ASSERTIONS=1 -s DISABLE_EXCEPTION_CATCHING=0")
-#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXIT_RUNTIME=1")
-
-#set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1")
-
-
-#####################################################################
-## Configuration of the Orthanc framework
-#####################################################################
-
-# This CMake file defines the "ORTHANC_STONE_VERSION" macro, so it
-# must be the first inclusion
-include(${CMAKE_SOURCE_DIR}/../../Resources/CMake/Version.cmake)
-
-if (ORTHANC_STONE_VERSION STREQUAL "mainline")
-  set(ORTHANC_FRAMEWORK_VERSION "mainline")
-  set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "hg")
-else()
-  set(ORTHANC_FRAMEWORK_VERSION "1.5.7")
-  set(ORTHANC_FRAMEWORK_DEFAULT_SOURCE "web")
-endif()
-
-set(ORTHANC_FRAMEWORK_SOURCE "${ORTHANC_FRAMEWORK_DEFAULT_SOURCE}" CACHE STRING "Source of the Orthanc source code (can be \"hg\", \"archive\", \"web\" or \"path\")")
-set(ORTHANC_FRAMEWORK_ARCHIVE "" CACHE STRING "Path to the Orthanc archive, if ORTHANC_FRAMEWORK_SOURCE is \"archive\"")
-set(ORTHANC_FRAMEWORK_ROOT "" CACHE STRING "Path to the Orthanc source directory, if ORTHANC_FRAMEWORK_SOURCE is \"path\"")
-
-
-#####################################################################
-## Configuration of the Stone framework
-#####################################################################
-
-include(${CMAKE_SOURCE_DIR}/../../Resources/CMake/OrthancStoneParameters.cmake)
-include(${ORTHANC_ROOT}/Resources/CMake/DownloadPackage.cmake)
-
-DownloadPackage(
-  "a24b8136b8f3bb93f166baf97d9328de"
-  "http://orthanc.osimis.io/ThirdPartyDownloads/ubuntu-font-family-0.83.zip"
-  "${CMAKE_BINARY_DIR}/ubuntu-font-family-0.83")
-
-set(ORTHANC_STONE_APPLICATION_RESOURCES
-  UBUNTU_FONT  ${CMAKE_BINARY_DIR}/ubuntu-font-family-0.83/Ubuntu-R.ttf
-  )
-
-SET(ENABLE_GOOGLE_TEST OFF)
-SET(ENABLE_LOCALE ON)
-SET(ORTHANC_SANDBOXED ON)
-SET(ENABLE_WASM ON)
-
-include(${CMAKE_SOURCE_DIR}/../../Resources/CMake/OrthancStoneConfiguration.cmake)
-
-add_definitions(
-  -DORTHANC_ENABLE_LOGGING_PLUGIN=0
-  )
-
-
-#####################################################################
-## Build the samples
-#####################################################################
-
-add_library(OrthancStone STATIC
-  ${ORTHANC_STONE_SOURCES}
-  )
-
-
-if (ON)
-  add_executable(BasicScene
-    BasicScene.cpp
-    #${CMAKE_CURRENT_LIST_DIR}/../Shared/SharedBasicScene.h
-    ${CMAKE_CURRENT_LIST_DIR}/../Shared/SharedBasicScene.cpp
-    )
-
-  target_link_libraries(BasicScene OrthancStone)
-
-  install(
-    TARGETS BasicScene
-    RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}
-    )
-endif()
-
-
-if (ON)
-  add_executable(BasicMPR
-    BasicMPR.cpp
-    )
-
-  target_link_libraries(BasicMPR OrthancStone)
-
-  install(
-    TARGETS BasicMPR
-    RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}
-    )
-endif()
-  
-
-install(
-  FILES
-  ${CMAKE_CURRENT_BINARY_DIR}/BasicMPR.wasm
-  ${CMAKE_CURRENT_BINARY_DIR}/BasicScene.wasm
-  ${CMAKE_SOURCE_DIR}/BasicMPR.html
-  ${CMAKE_SOURCE_DIR}/BasicScene.html
-  ${CMAKE_SOURCE_DIR}/Configuration.json
-  ${CMAKE_SOURCE_DIR}/app.js
-  ${CMAKE_SOURCE_DIR}/index.html
-  DESTINATION ${CMAKE_INSTALL_PREFIX}
-  )
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/WebAssembly/Configuration.json	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-{
-  "Plugins": [
-    "/usr/local/share/orthanc/plugins/libOrthancWebViewer.so",
-    "/usr/local/share/orthanc/plugins/libServeFolders.so"
-  ],
-  "StorageDirectory" : "/var/lib/orthanc/db",
-  "IndexDirectory" : "/var/lib/orthanc/db",
-  "RemoteAccessAllowed" : true,
-  "AuthenticationEnabled" : false,
-  "ServeFolders" : {
-    "AllowCache" : false,
-    "GenerateETag" : true,
-    "Folders" : {
-      "/stone" : "/root/stone"
-    }
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/WebAssembly/ConfigurationLocalSJO.json	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-{
-  "Plugins": [
-    "/home/jodogne/Subversion/orthanc-webviewer/r/libOrthancWebViewer.so",
-    "/home/jodogne/Subversion/orthanc/r/libServeFolders.so"
-  ],
-  "StorageDirectory" : "/tmp/orthanc-db",
-  "IndexDirectory" : "/tmp/orthanc-db",
-  "RemoteAccessAllowed" : true,
-  "AuthenticationEnabled" : false,
-  "ServeFolders" : {
-    "AllowCache" : false,
-    "GenerateETag" : true,
-    "Folders" : {
-      "/stone" : "/tmp/stone"
-    }
-  },
-  "WebViewer" : {
-    "CachePath" : "/tmp/orthanc-db/WebViewerCache"
-  }
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/WebAssembly/NOTES.txt	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-Docker SJO
-==========
-
-$ source ~/Downloads/emsdk/emsdk_env.sh
-$ cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN}/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_BUILD_TYPE=Release -DALLOW_DOWNLOADS=ON .. -DCMAKE_INSTALL_PREFIX=/tmp/stone
-$ ninja install
-$ docker run -p 4242:4242 -p 8042:8042 --rm -v /tmp/stone:/root/stone:ro -v /tmp/stone-db/:/var/lib/orthanc/db/ jodogne/orthanc-plugins:latest /root/stone/Configuration.json --verbose
-
-WARNING: This won't work using "orthanc-plugins:1.5.6", as support for
-PAM is mandatatory in "/instances/.../image-uint16".
-
-
-Docker BGO
-==========
-
-On Ubuntu WSL
--------------
-. ~/apps/emsdk/emsdk_env.sh
-cd /mnt/c/osi/dev/
-mkdir -p build_stone_newsamples_wasm_wsl
-mkdir -p build_install_stone_newsamples_wasm_wsl
-cd build_stone_newsamples_wasm_wsl
-cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN}/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_BUILD_TYPE=Release -DALLOW_DOWNLOADS=ON /mnt/c/osi/dev/orthanc-stone/OrthancStone/Samples/WebAssembly -DCMAKE_INSTALL_PREFIX=/mnt/c/osi/dev/build_install_stone_newsamples_wasm_wsl
-ninja install
-
-Then, on Windows
------------------
-docker run -p 4242:4242 -p 8042:8042 --rm -v "C:/osi/dev/build_install_stone_newsamples_wasm_wsl:/root/stone:ro" jodogne/orthanc-plugins:1.5.6 /root/stone/Configuration.json --verbose
-
-# WAIT A COUPLE OF SECS
-# if the archive has NOT already been unzipped, unzip it
-# upload dicom files to running orthanc
-
-cd C:\osi\dev\twiga-orthanc-viewer\demo\dicomfiles
-if (-not (test-path RTVIEWER-c8febcc6-eb9e22a4-130f208c-e0a6a4cd-4d432c57)) { unzip RTVIEWER-c8febcc6-eb9e22a4-130f208c-e0a6a4cd-4d432c57.zip}
-ImportDicomFiles.ps1 127.0.0.1 8042 .\RTVIEWER-c8febcc6-eb9e22a4-130f208c-e0a6a4cd-4d432c57\
-
---> localhost:8042 --> Plugins --> serve-folders --> stone --> ...
-
-Local BGO
-==========
-
-. ~/apps/emsdk/emsdk_env.sh
-cd /mnt/c/osi/dev/
-mkdir -p build_stone_newsamples_wasm_wsl
-mkdir -p build_install_stone_newsamples_wasm_wsl
-cd build_stone_newsamples_wasm_wsl
-cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN}/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_BUILD_TYPE=Release -DALLOW_DOWNLOADS=ON /mnt/c/osi/dev/orthanc-stone/OrthancStone/Samples/WebAssembly -DCMAKE_INSTALL_PREFIX=/mnt/c/osi/dev/build_install_stone_newsamples_wasm_wsl
-
-
-
-TODO: Orthanc.exe 
-
-
-Local SJO
-==========
-
-$ source ~/Downloads/emsdk/emsdk_env.sh
-$ cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=${EMSCRIPTEN}/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_BUILD_TYPE=Release -DALLOW_DOWNLOADS=ON .. -DCMAKE_INSTALL_PREFIX=/tmp/stone
-$ ninja install
-
-$ make -C ~/Subversion/orthanc/r -j4
-$ make -C ~/Subversion/orthanc-webviewer/r -j4
-$ ~/Subversion/orthanc/r/Orthanc ../ConfigurationLocalSJO.json
-
-
-Local AM
-========
-
-. ~/apps/emsdk/emsdk_env.sh
-cd /mnt/c/o/
-mkdir -p build_stone_newsamples_wasm_wsl
-mkdir -p build_install_stone_newsamples_wasm_wsl
-cd build_stone_newsamples_wasm_wsl
-cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=${EMSDK}/fastcomp/emscripten/cmake/Modules/Platform/Emscripten.cmake -DORTHANC_FRAMEWORK_SOURCE=path -DORTHANC_FRAMEWORK_ROOT=/mnt/c/o/orthanc/ -DCMAKE_BUILD_TYPE=Release -DALLOW_DOWNLOADS=ON /mnt/c/o/orthanc-stone/OrthancStone/Samples/WebAssembly -DCMAKE_INSTALL_PREFIX=/mnt/c/o/build_install_stone_newsamples_wasm_wsl
-ninja
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/WebAssembly/app.js	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/**
- * This is a generic bootstrap code that is shared by all the Stone
- * sample applications.
- **/
-
-// Check support for WebAssembly
-if (!('WebAssembly' in window)) {
-  alert('Sorry, your browser does not support WebAssembly :(');
-} else {
-
-  // Wait for the module to be loaded (the event "WebAssemblyLoaded"
-  // must be emitted by the "main" function)
-  window.addEventListener('WebAssemblyLoaded', function() {
-
-    // Loop over the GET arguments
-    var parameters = window.location.search.substr(1);
-    if (parameters != null && parameters != '') {
-      var tokens = parameters.split('&');
-      for (var i = 0; i < tokens.length; i++) {
-        var arg = tokens[i].split('=');
-        if (arg.length == 2) {
-
-          // Send each GET argument to WebAssembly
-          Module.ccall('SetArgument', null, [ 'string', 'string' ],
-                       [ arg[0], decodeURIComponent(arg[1]) ]);
-        }
-      }
-    }
-
-    // Inform the WebAssembly module that it can start
-    Module.ccall('Initialize', null, null, null);
-  });
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/WebAssembly/dev.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,202 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Framework/Viewport/WebAssemblyViewport.h"
-#include "../../Framework/Scene2D/OpenGLCompositor.h"
-#include "../../Framework/Scene2D/PanSceneTracker.h"
-#include "../../Framework/Scene2D/RotateSceneTracker.h"
-#include "../../Framework/Scene2D/ZoomSceneTracker.h"
-#include "../../Framework/Scene2DViewport/UndoStack.h"
-#include "../../Framework/Scene2DViewport/ViewportController.h"
-
-#include <Core/OrthancException.h>
-
-#include <emscripten/html5.h>
-#include <boost/make_shared.hpp>
-
-static const unsigned int FONT_SIZE = 32;
-
-namespace OrthancStone
-{
-  class ActiveTracker : public boost::noncopyable
-  {
-  private:
-    boost::shared_ptr<IFlexiblePointerTracker> tracker_;
-    std::string                             canvasIdentifier_;
-    bool                                    insideCanvas_;
-    
-  public:
-    ActiveTracker(const boost::shared_ptr<IFlexiblePointerTracker>& tracker,
-                  const std::string& canvasId) :
-      tracker_(tracker),
-      canvasIdentifier_(canvasId),
-      insideCanvas_(true)
-    {
-      if (tracker_.get() == NULL)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
-      }
-    }
-
-    bool IsAlive() const
-    {
-      return tracker_->IsAlive();
-    }
-
-    void PointerMove(const PointerEvent& event)
-    {
-      tracker_->PointerMove(event);
-    }
-
-    void PointerUp(const PointerEvent& event)
-    {
-      tracker_->PointerUp(event);
-    }
-  };
-}
-
-static OrthancStone::PointerEvent* ConvertMouseEvent(
-  const EmscriptenMouseEvent&        source,
-  OrthancStone::IViewport& viewport)
-{
-  std::unique_ptr<OrthancStone::PointerEvent> target(
-    new OrthancStone::PointerEvent);
-
-  target->AddPosition(viewport.GetPixelCenterCoordinates(
-                        source.targetX, source.targetY));
-  target->SetAltModifier(source.altKey);
-  target->SetControlModifier(source.ctrlKey);
-  target->SetShiftModifier(source.shiftKey);
-
-  return target.release();
-}
-
-std::unique_ptr<OrthancStone::ActiveTracker> tracker_;
-
-EM_BOOL OnMouseEvent(int eventType, 
-                     const EmscriptenMouseEvent *mouseEvent, 
-                     void *userData)
-{
-  if (mouseEvent != NULL &&
-      userData != NULL)
-  {
-    boost::shared_ptr<OrthancStone::ViewportController>& controller = 
-      *reinterpret_cast<boost::shared_ptr<OrthancStone::ViewportController>*>(userData);
-
-    switch (eventType)
-    {
-      case EMSCRIPTEN_EVENT_CLICK:
-      {
-        static unsigned int count = 0;
-        char buf[64];
-        sprintf(buf, "click %d", count++);
-
-        std::unique_ptr<OrthancStone::TextSceneLayer> layer(new OrthancStone::TextSceneLayer);
-        layer->SetText(buf);
-        controller->GetViewport().GetScene().SetLayer(100, layer.release());
-        controller->GetViewport().Refresh();
-        break;
-      }
-
-      case EMSCRIPTEN_EVENT_MOUSEDOWN:
-      {
-        boost::shared_ptr<OrthancStone::IFlexiblePointerTracker> t;
-
-        {
-          std::unique_ptr<OrthancStone::PointerEvent> event(
-            ConvertMouseEvent(*mouseEvent, controller->GetViewport()));
-
-          switch (mouseEvent->button)
-          {
-            case 0:  // Left button
-              emscripten_console_log("Creating RotateSceneTracker");
-              t.reset(new OrthancStone::RotateSceneTracker(
-                        controller, *event));
-              break;
-
-            case 1:  // Middle button
-              emscripten_console_log("Creating PanSceneTracker");
-              LOG(INFO) << "Creating PanSceneTracker" ;
-              t.reset(new OrthancStone::PanSceneTracker(
-                        controller, *event));
-              break;
-
-            case 2:  // Right button
-              emscripten_console_log("Creating ZoomSceneTracker");
-              t.reset(new OrthancStone::ZoomSceneTracker(
-                        controller, *event, controller->GetViewport().GetCanvasWidth()));
-              break;
-
-            default:
-              break;
-          }
-        }
-
-        if (t.get() != NULL)
-        {
-          tracker_.reset(
-            new OrthancStone::ActiveTracker(t, controller->GetViewport().GetCanvasIdentifier()));
-          controller->GetViewport().Refresh();
-        }
-
-        break;
-      }
-
-      case EMSCRIPTEN_EVENT_MOUSEMOVE:
-        if (tracker_.get() != NULL)
-        {
-          std::unique_ptr<OrthancStone::PointerEvent> event(
-            ConvertMouseEvent(*mouseEvent, controller->GetViewport()));
-          tracker_->PointerMove(*event);
-          controller->GetViewport().Refresh();
-        }
-        break;
-
-      case EMSCRIPTEN_EVENT_MOUSEUP:
-        if (tracker_.get() != NULL)
-        {
-          std::unique_ptr<OrthancStone::PointerEvent> event(
-            ConvertMouseEvent(*mouseEvent, controller->GetViewport()));
-          tracker_->PointerUp(*event);
-          controller->GetViewport().Refresh();
-          if (!tracker_->IsAlive())
-            tracker_.reset();
-        }
-        break;
-
-      default:
-        break;
-    }
-  }
-
-  return true;
-}
-
-
-void SetupEvents(const std::string& canvas,
-                 boost::shared_ptr<OrthancStone::ViewportController>& controller)
-{
-  emscripten_set_mousedown_callback(canvas.c_str(), &controller, false, OnMouseEvent);
-  emscripten_set_mousemove_callback(canvas.c_str(), &controller, false, OnMouseEvent);
-  emscripten_set_mouseup_callback(canvas.c_str(), &controller, false, OnMouseEvent);
-}
--- a/OrthancStone/Resources/Graveyard/Deprecated/Samples/WebAssembly/index.html	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-<!doctype html>
-<html lang="en-us">
-  <head>
-    <meta charset="utf-8">
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-
-    <title>Stone of Orthanc</title>
-  </head>
-  <body>
-    <h1>Available samples</h1>
-    <ul>
-      <li><a href="BasicScene.html">Basic scene</a></li>
-      <li><a href="BasicMPR.html">Basic MPR display</a></li>
-    </ul>
-  </body>
-</html>
--- a/OrthancStone/Sources/Deprecated/GuiAdapter.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1139 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "GuiAdapter.h"
-
-#if ORTHANC_ENABLE_OPENGL == 1
-#  include "../OpenGL/OpenGLIncludes.h"
-#endif
-
-#if ORTHANC_ENABLE_SDL == 1
-#  include <SDL_video.h>
-#  include <SDL_render.h>
-#  include <SDL.h>
-#endif
-
-#include <Compatibility.h>
-
-namespace OrthancStone
-{
-  std::ostream& operator<<(
-    std::ostream& os, const GuiAdapterKeyboardEvent& event)
-  {
-    os << "sym: " << event.sym << " (" << (int)(event.sym[0]) << ") ctrl: " << event.ctrlKey << ", " <<
-      "shift: " << event.shiftKey << ", " <<
-      "alt: " << event.altKey;
-    return os;
-  }
-
-  std::ostream& operator<<(
-    std::ostream& os, const GuiAdapterMouseEvent& event)
-  {
-    os << "targetX: " << event.targetX << " targetY: " << event.targetY << " button: " << event.button
-      << "ctrlKey: " << event.ctrlKey << "shiftKey: " << event.shiftKey << "altKey: " << event.altKey;
-      
-    return os;
-  }
-
-  int GuiAdapter::s_instanceCount = 0;
-
-#if ORTHANC_ENABLE_WASM == 1
-  void GuiAdapter::Run(GuiAdapterRunFunc /*func*/, void* /*cookie*/)
-  {
-  }
-
-  void ConvertFromPlatform(
-    GuiAdapterUiEvent& dest,
-    int                      eventType,
-    const EmscriptenUiEvent& src)
-  {
-    // no data for now
-  }
-
-  void ConvertFromPlatform(
-    GuiAdapterMouseEvent& dest,
-    int                         eventType,
-    const EmscriptenMouseEvent& src)
-  {
-    memset(&dest, 0, sizeof(GuiAdapterMouseEvent));
-    switch (eventType)
-    {
-    case EMSCRIPTEN_EVENT_CLICK:
-      LOG(ERROR) << "Emscripten EMSCRIPTEN_EVENT_CLICK is not supported";
-      ORTHANC_ASSERT(false, "Not supported");
-      break;
-    case EMSCRIPTEN_EVENT_MOUSEDOWN:
-      dest.type = GUIADAPTER_EVENT_MOUSEDOWN;
-      break;
-    case EMSCRIPTEN_EVENT_DBLCLICK:
-      dest.type = GUIADAPTER_EVENT_MOUSEDBLCLICK;
-      break;
-    case EMSCRIPTEN_EVENT_MOUSEMOVE:
-      dest.type = GUIADAPTER_EVENT_MOUSEMOVE;
-      break;
-    case EMSCRIPTEN_EVENT_MOUSEUP:
-      dest.type = GUIADAPTER_EVENT_MOUSEUP;
-      break;
-    case EMSCRIPTEN_EVENT_WHEEL:
-      dest.type = GUIADAPTER_EVENT_WHEEL;
-      break;
-
-    default:
-      LOG(ERROR) << "Emscripten event: " << eventType << " is not supported";
-      ORTHANC_ASSERT(false, "Not supported");
-    }
-    //dest.timestamp = src.timestamp;
-    //dest.screenX = src.screenX;
-    //dest.screenY = src.screenY;
-    //dest.clientX = src.clientX;
-    //dest.clientY = src.clientY;
-    dest.ctrlKey = src.ctrlKey;
-    dest.shiftKey = src.shiftKey;
-    dest.altKey = src.altKey;
-    //dest.metaKey = src.metaKey;
-    dest.button = src.button;
-    //dest.buttons = src.buttons;
-    //dest.movementX = src.movementX;
-    //dest.movementY = src.movementY;
-    dest.targetX = src.targetX;
-    dest.targetY = src.targetY;
-    //dest.canvasX = src.canvasX;
-    //dest.canvasY = src.canvasY;
-    //dest.padding = src.padding;
-  }
-
-  void ConvertFromPlatform( GuiAdapterWheelEvent& dest, int eventType, const EmscriptenWheelEvent& src)
-  {
-    ConvertFromPlatform(dest.mouse, eventType, src.mouse);
-    dest.deltaX = src.deltaX;
-    dest.deltaY = src.deltaY;
-    switch (src.deltaMode)
-    {
-    case DOM_DELTA_PIXEL:
-      dest.deltaMode = GUIADAPTER_DELTA_PIXEL;
-      break;
-    case DOM_DELTA_LINE:
-      dest.deltaMode = GUIADAPTER_DELTA_LINE;
-      break;
-    case DOM_DELTA_PAGE:
-      dest.deltaMode = GUIADAPTER_DELTA_PAGE;
-      break;
-    default:
-      ORTHANC_ASSERT(false, "Unknown deltaMode: " << src.deltaMode <<
-        " in wheel event...");
-    }
-    dest.deltaMode = src.deltaMode;
-  }
-
-  void ConvertFromPlatform(GuiAdapterKeyboardEvent& dest, const EmscriptenKeyboardEvent& src)
-  {
-    dest.sym[0] = src.key[0];
-    dest.sym[1] = 0;
-    dest.ctrlKey = src.ctrlKey;
-    dest.shiftKey = src.shiftKey;
-    dest.altKey = src.altKey;
-  }
-
-  template<typename GenericFunc>
-  struct FuncAdapterPayload
-  {
-    std::string canvasCssSelector;
-    void* userData;
-    GenericFunc callback;
-  };
-
-  template<typename GenericFunc,
-    typename GuiAdapterEvent,
-    typename EmscriptenEvent>
-    EM_BOOL OnEventAdapterFunc(
-      int eventType, const EmscriptenEvent* emEvent, void* userData)
-  {
-    // userData is OnMouseWheelFuncAdapterPayload
-    FuncAdapterPayload<GenericFunc>* payload =
-      reinterpret_cast<FuncAdapterPayload<GenericFunc>*>(userData);
-    // LOG(INFO) << "OnEventAdapterFunc";
-    // LOG(INFO) << "------------------";
-    // LOG(INFO) << "eventType: " << eventType << " wheelEvent: " << 
-    //   (int)wheelEvent << " userData: " << userData << 
-    //   " payload->userData: " << payload->userData;
-
-    GuiAdapterEvent guiEvent;
-    ConvertFromPlatform(guiEvent, eventType, *emEvent);
-    bool ret = (*(payload->callback))(payload->canvasCssSelector, &guiEvent, payload->userData);
-    return static_cast<EM_BOOL>(ret);
-  }
-
-  template<typename GenericFunc,
-    typename GuiAdapterEvent,
-    typename EmscriptenEvent>
-    EM_BOOL OnEventAdapterFunc2(
-      int /*eventType*/, const EmscriptenEvent* wheelEvent, void* userData)
-  {
-    // userData is OnMouseWheelFuncAdapterPayload
-    FuncAdapterPayload<GenericFunc>* payload =
-      reinterpret_cast<FuncAdapterPayload<GenericFunc>*>(userData);
-
-    GuiAdapterEvent guiEvent;
-    ConvertFromPlatform(guiEvent, *wheelEvent);
-    bool ret = (*(payload->callback))(payload->canvasCssSelector, &guiEvent, payload->userData);
-    return static_cast<EM_BOOL>(ret);
-  }
-
-  template<typename GenericFunc>
-  EM_BOOL OnEventAdapterFunc3(
-    double time, void* userData)
-  {
-    // userData is OnMouseWheelFuncAdapterPayload
-    FuncAdapterPayload<GenericFunc>* payload =
-      reinterpret_cast<FuncAdapterPayload<GenericFunc>*>(userData);
-    //std::unique_ptr< FuncAdapterPayload<GenericFunc> > deleter(payload);
-    bool ret = (*(payload->callback))(time, payload->userData);
-    return static_cast<EM_BOOL>(ret);
-  }
-
-  /*
-  
-  Explanation
-  ===========
-
-  - in "older" Emscripten, where DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR doesn't exist or is set to 0,
-    the following strings need to be used to register events:
-    - for canvas, the canvas DOM id. In case of <canvas id="mycanvas1" width='640' ...></canvas>", the string needs 
-      to be "mycanvas"
-    - for the window (for key events), the string needs to be "#window"
-  - in newer Emscripten where DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR==1 (or maybe is not there anymore, in the
-    future as of 2020-04-20)
-    - for canvas, the canvas DOM id. In case of <canvas id="mycanvas1" width='640' ...></canvas>", the string needs
-      to be "#mycanvas"  (notice the "number sign", aka "hash", NOT AKA "sharp", as can be read on https://en.wikipedia.org/wiki/Number_sign)
-    - for the window (for key events), the string needs to be EMSCRIPTEN_EVENT_TARGET_WINDOW. I do not mean 
-      "EMSCRIPTEN_EVENT_TARGET_WINDOW", but the #define EMSCRIPTEN_EVENT_TARGET_WINDOW         ((const char*)2) that
-      can be found in emscripten/html5.h
-
-  The code below converts the input canvasId (as in the old emscripten) to the emscripten-compliant one, with the
-  following compile condition : #if DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR == 1
-
-  If the DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR build parameter disappears, you might want to refactor this code
-  or continue to pass the DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR compile macro (which is different from the CMake
-  variable)     
-
-  What we are doing below:
-  - in older Emscripten, the registration functions will receive "mycanvas" and "#window" and the callbacks will receive 
-    the same std::string in their payload ("mycanvas" and "#window")
-
-  - in newer Emscripten, the registration functions will receive "#mycanvas" and EMSCRIPTEN_EVENT_TARGET_WINDOW, but 
-    the callbacks will receive "#mycanvas" and "#window" (since it is not possible to store the EMSCRIPTEN_EVENT_TARGET_WINDOW
-    magic value in an std::string, while we still want the callback to be able to change its behavior according to the
-    target element.
-  
-  */
-
-  void convertElementTarget(const char*& outCanvasCssSelectorSz, std::string& outCanvasCssSelector, const std::string& canvasId)
-  {
-    // only "#window" can start with a #
-    if (canvasId[0] == '#')
-    {
-      ORTHANC_ASSERT(canvasId == "#window");
-    }
-#if DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR == 1
-    if (canvasId == "#window")
-    {
-      // we store this in the payload so that the callback can 
-      outCanvasCssSelector = "#window";
-      outCanvasCssSelectorSz = EMSCRIPTEN_EVENT_TARGET_WINDOW;
-    }
-    else
-    {
-      outCanvasCssSelector = "#" + canvasId;
-      outCanvasCssSelectorSz = outCanvasCssSelector.c_str();
-    }
-#else
-    if (canvasId == "#window")
-    {
-      // we store this in the payload so that the callback can 
-      outCanvasCssSelector = "#window";
-      outCanvasCssSelectorSz = outCanvasCssSelector.c_str();;
-    }
-    else
-    {
-      outCanvasCssSelector = canvasId;
-      outCanvasCssSelectorSz = outCanvasCssSelector.c_str();;
-    }
-#endif
-  }
-
-  // resize: (const char* target, void* userData, EM_BOOL useCapture, em_ui_callback_func callback)
-  template<
-    typename GenericFunc,
-    typename GuiAdapterEvent,
-    typename EmscriptenEvent,
-    typename EmscriptenSetCallbackFunc>
-    static void SetCallback(
-      EmscriptenSetCallbackFunc emFunc,
-      std::string canvasId, void* userData, bool capture, GenericFunc func)
-  {
-    std::string canvasCssSelector;
-    const char* canvasCssSelectorSz = NULL;
-    convertElementTarget(canvasCssSelectorSz, canvasCssSelector, canvasId);
-
-    // TODO: write RemoveCallback with an int id that gets returned from here
-
-    // create userdata payload
-    std::unique_ptr<FuncAdapterPayload<GenericFunc> > payload(new FuncAdapterPayload<GenericFunc>());
-    payload->canvasCssSelector = canvasCssSelector;
-    payload->callback = func;
-    payload->userData = userData;
-    void* userDataRaw = reinterpret_cast<void*>(payload.release());
-
-    // call the registration function
-    (*emFunc)(
-      canvasCssSelectorSz,
-      userDataRaw,
-      static_cast<EM_BOOL>(capture),
-      &OnEventAdapterFunc<GenericFunc, GuiAdapterEvent, EmscriptenEvent>,
-      EM_CALLBACK_THREAD_CONTEXT_CALLING_THREAD);
-  }
-
-  template<
-    typename GenericFunc,
-    typename GuiAdapterEvent,
-    typename EmscriptenEvent,
-    typename EmscriptenSetCallbackFunc>
-    static void SetCallback2(
-      EmscriptenSetCallbackFunc emFunc,
-      std::string canvasId, void* userData, bool capture, GenericFunc func)
-  {
-    std::string canvasCssSelector;
-    const char* canvasCssSelectorSz = NULL;
-    convertElementTarget(canvasCssSelectorSz, canvasCssSelector, canvasId);
-
-    // TODO: write RemoveCallback with an int id that gets returned from here
-
-    // create userdata payload
-    std::unique_ptr<FuncAdapterPayload<GenericFunc> > payload(new FuncAdapterPayload<GenericFunc>());
-    payload->canvasCssSelector = canvasCssSelector;
-    payload->callback = func;
-    payload->userData = userData;
-    void* userDataRaw = reinterpret_cast<void*>(payload.release());
-
-    // call the registration function
-    (*emFunc)(
-      canvasCssSelectorSz,
-      userDataRaw,
-      static_cast<EM_BOOL>(capture),
-      &OnEventAdapterFunc2<GenericFunc, GuiAdapterEvent, EmscriptenEvent>,
-      EM_CALLBACK_THREAD_CONTEXT_CALLING_THREAD);
-  }
-
-  template<
-    typename GenericFunc,
-    typename EmscriptenSetCallbackFunc>
-    static void SetAnimationFrameCallback(
-      EmscriptenSetCallbackFunc emFunc,
-      void* userData, GenericFunc func)
-  {
-    std::unique_ptr<FuncAdapterPayload<GenericFunc> > payload(
-      new FuncAdapterPayload<GenericFunc>()
-    );
-    payload->canvasCssSelector = "UNDEFINED";
-    payload->callback = func;
-    payload->userData = userData;
-    void* userDataRaw = reinterpret_cast<void*>(payload.release());
-    (*emFunc)(
-      &OnEventAdapterFunc3<GenericFunc>,
-      userDataRaw);
-  }
-
-  void GuiAdapter::SetWheelCallback(
-    std::string canvasId, void* userData, bool capture, OnMouseWheelFunc func)
-  {
-    SetCallback<OnMouseWheelFunc, GuiAdapterWheelEvent, EmscriptenWheelEvent>(
-      &emscripten_set_wheel_callback_on_thread,
-      canvasId,
-      userData,
-      capture,
-      func);
-  }
-
-  
-  void GuiAdapter::SetMouseDblClickCallback(
-      std::string canvasId, void* userData, bool capture, OnMouseEventFunc func)
-  {
-    SetCallback<OnMouseEventFunc, GuiAdapterMouseEvent, EmscriptenMouseEvent>(
-      &emscripten_set_dblclick_callback_on_thread,
-      canvasId,
-      userData,
-      capture,
-      func);
-  }
-
-
-  void GuiAdapter::SetMouseDownCallback(
-    std::string canvasId, void* userData, bool capture, OnMouseEventFunc func)
-  {
-    SetCallback<OnMouseEventFunc, GuiAdapterMouseEvent, EmscriptenMouseEvent>(
-      &emscripten_set_mousedown_callback_on_thread,
-      canvasId,
-      userData,
-      capture,
-      func);
-  }
-
-  void GuiAdapter::SetMouseMoveCallback(
-    std::string canvasId, void* userData, bool capture, OnMouseEventFunc func)
-  {
-    // LOG(INFO) << "SetMouseMoveCallback -- " << "supplied userData: " << 
-    //   userData;
-
-    SetCallback<OnMouseEventFunc, GuiAdapterMouseEvent, EmscriptenMouseEvent>(
-      &emscripten_set_mousemove_callback_on_thread,
-      canvasId,
-      userData,
-      capture,
-      func);
-  }
-
-  void GuiAdapter::SetMouseUpCallback(
-    std::string canvasId, void* userData, bool capture, OnMouseEventFunc func)
-  {
-    SetCallback<OnMouseEventFunc, GuiAdapterMouseEvent, EmscriptenMouseEvent>(
-      &emscripten_set_mouseup_callback_on_thread,
-      canvasId,
-      userData,
-      capture,
-      func);
-  }
-
-  void GuiAdapter::SetKeyDownCallback(
-    std::string canvasId, void* userData, bool capture, OnKeyDownFunc func)
-  {
-    SetCallback2<OnKeyDownFunc, GuiAdapterKeyboardEvent, EmscriptenKeyboardEvent>(
-      &emscripten_set_keydown_callback_on_thread,
-      canvasId,
-      userData,
-      capture,
-      func);
-  }
-
-  void GuiAdapter::SetKeyUpCallback(
-    std::string canvasId, void* userData, bool capture, OnKeyUpFunc func)
-  {
-    SetCallback2<OnKeyUpFunc, GuiAdapterKeyboardEvent, EmscriptenKeyboardEvent>(
-      &emscripten_set_keyup_callback_on_thread,
-      canvasId,
-      userData,
-      capture,
-      func);
-  }
-
-#if 0
-  // useless under Wasm where canvas resize is handled automatically
-  void GuiAdapter::SetResizeCallback(
-    std::string canvasId, void* userData, bool capture, OnWindowResizeFunc func)
-  {
-    SetCallback<OnWindowResizeFunc, GuiAdapterUiEvent, EmscriptenUiEvent>(
-      &emscripten_set_resize_callback_on_thread,
-      canvasId,
-      userData,
-      capture,
-      func);
-  }
-#endif
-
-  void GuiAdapter::RequestAnimationFrame(
-    OnAnimationFrameFunc func, void* userData)
-  {
-    SetAnimationFrameCallback<OnAnimationFrameFunc>(
-      &emscripten_request_animation_frame_loop,
-      userData,
-      func);
-  }
-
-#if 0
-  void GuiAdapter::SetKeyDownCallback(
-    std::string canvasId, void* userData, bool capture, OnKeyDownFunc func)
-  {
-    emscripten_set_keydown_callback(canvasId.c_str(), userData, static_cast<EM_BOOL>(capture), func);
-  }
-  void GuiAdapter::SetKeyUpCallback(
-    std::string canvasId, void* userData, bool capture, OnKeyUpFunc func)
-  {
-    emscripten_set_keyup_callback(canvasId.c_str(), userData, static_cast<EM_BOOL>(capture), func);
-  }
-
-  // handled from within WebAssemblyViewport
-  //void GuiAdapter::SetResizeCallback(std::string canvasId, void* userData, bool capture, OnWindowResizeFunc func)
-  //{
-  //  emscripten_set_resize_callback(canvasId.c_str(), userData, static_cast<EM_BOOL>(capture), func);
-  //}
-
-  void GuiAdapter::RequestAnimationFrame(OnAnimationFrameFunc func, void* userData)
-  {
-    emscripten_request_animation_frame_loop(func, userData);
-  }
-#endif
-
-
-#else
-
-  // SDL ONLY
-  void ConvertFromPlatform(GuiAdapterMouseEvent& dest, bool ctrlPressed, bool shiftPressed, bool altPressed, const SDL_Event& source)
-  {
-    memset(&dest, 0, sizeof(GuiAdapterMouseEvent));
-    switch (source.type)
-    {
-    case SDL_MOUSEBUTTONDOWN:
-      if (source.button.clicks == 1) {
-        dest.type = GUIADAPTER_EVENT_MOUSEDOWN;
-      } else if (source.button.clicks == 2) {
-        dest.type = GUIADAPTER_EVENT_MOUSEDBLCLICK;
-      } else {
-        dest.type = GUIADAPTER_EVENT_MOUSEDBLCLICK;
-        LOG(WARNING) << "Multiple-click ignored.";
-      }
-      break;
-    case SDL_MOUSEMOTION:
-      dest.type = GUIADAPTER_EVENT_MOUSEMOVE;
-      break;
-    case SDL_MOUSEBUTTONUP:
-      dest.type = GUIADAPTER_EVENT_MOUSEUP;
-      break;
-    case SDL_MOUSEWHEEL:
-      dest.type = GUIADAPTER_EVENT_WHEEL;
-      break;
-    default:
-      LOG(ERROR) << "SDL event: " << source.type << " is not supported";
-      ORTHANC_ASSERT(false, "Not supported");
-    }
-    //dest.timestamp = src.timestamp;
-    //dest.screenX = src.screenX;
-    //dest.screenY = src.screenY;
-    //dest.clientX = src.clientX;
-    //dest.clientY = src.clientY;
-    dest.ctrlKey = ctrlPressed;
-    dest.shiftKey = shiftPressed;
-    dest.altKey = altPressed;
-    //dest.metaKey = src.metaKey;
-    switch (source.button.button)
-    {
-    case SDL_BUTTON_MIDDLE:
-      dest.button =GUIADAPTER_MOUSEBUTTON_MIDDLE;
-      break;
-
-    case SDL_BUTTON_RIGHT:
-      dest.button = GUIADAPTER_MOUSEBUTTON_RIGHT;
-      break;
-
-    case SDL_BUTTON_LEFT:
-      dest.button = GUIADAPTER_MOUSEBUTTON_LEFT;
-      break;
-
-    default:
-      break;
-    }
-    //dest.buttons = src.buttons;
-    //dest.movementX = src.movementX;
-    //dest.movementY = src.movementY;
-    dest.targetX = source.button.x;
-    dest.targetY = source.button.y;
-    //dest.canvasX = src.canvasX;
-    //dest.canvasY = src.canvasY;
-    //dest.padding = src.padding;
-  }
-
-  void ConvertFromPlatform(
-    GuiAdapterWheelEvent& dest,
-    bool ctrlPressed, bool shiftPressed, bool altPressed,
-    const SDL_Event& source)
-  {
-    ConvertFromPlatform(dest.mouse, ctrlPressed, shiftPressed, altPressed, source);
-    dest.deltaX = source.wheel.x;
-    dest.deltaY = source.wheel.y;
-  }
-
-  void ConvertFromPlatform(GuiAdapterKeyboardEvent& dest, const SDL_Event& src)
-  {
-    memset(&dest, 0, sizeof(GuiAdapterMouseEvent));
-    switch (src.type)
-    {
-    case SDL_KEYDOWN:
-      dest.type = GUIADAPTER_EVENT_KEYDOWN;
-      break;
-    case SDL_KEYUP:
-      dest.type = GUIADAPTER_EVENT_KEYUP;
-      break;
-    default:
-      LOG(ERROR) << "SDL event: " << src.type << " is not supported";
-      ORTHANC_ASSERT(false, "Not supported");
-    }
-    dest.sym[0] = src.key.keysym.sym;
-    dest.sym[1] = 0;
-
-    if (src.key.keysym.mod & KMOD_CTRL)
-      dest.ctrlKey = true;
-    else
-      dest.ctrlKey = false;
-
-    if (src.key.keysym.mod & KMOD_SHIFT)
-      dest.shiftKey = true;
-    else
-      dest.shiftKey = false;
-
-    if (src.key.keysym.mod & KMOD_ALT)
-      dest.altKey = true;
-    else
-      dest.altKey = false;
-  }
-
-  // SDL ONLY
-  void GuiAdapter::SetSdlResizeCallback(
-    std::string canvasId, void* userData, bool capture, OnSdlWindowResizeFunc func)
-  {
-    resizeHandlers_.push_back(EventHandlerData<OnSdlWindowResizeFunc>(canvasId, func, userData));
-  }
-
-  // SDL ONLY
-  void GuiAdapter::SetMouseDownCallback(
-    std::string canvasId, void* userData, bool capture, OnMouseEventFunc func)
-  {
-    mouseDownHandlers_.push_back(EventHandlerData<OnMouseEventFunc>(canvasId, func, userData));
-  }
-
-  // SDL ONLY
-  void GuiAdapter::SetMouseDblClickCallback(
-    std::string canvasId, void* userData, bool capture, OnMouseEventFunc func)
-  {
-    mouseDblCickHandlers_.push_back(EventHandlerData<OnMouseEventFunc>(canvasId, func, userData));
-  }
-
-  // SDL ONLY
-  void GuiAdapter::SetMouseMoveCallback(
-    std::string canvasId, void* userData, bool capture, OnMouseEventFunc  func)
-  {
-    mouseMoveHandlers_.push_back(EventHandlerData<OnMouseEventFunc>(canvasId, func, userData));
-  }
-
-  // SDL ONLY
-  void GuiAdapter::SetMouseUpCallback(
-    std::string canvasId, void* userData, bool capture, OnMouseEventFunc  func)
-  {
-    mouseUpHandlers_.push_back(EventHandlerData<OnMouseEventFunc>(canvasId, func, userData));
-  }
-
-  // SDL ONLY
-  void GuiAdapter::SetWheelCallback(
-    std::string canvasId, void* userData, bool capture, OnMouseWheelFunc  func)
-  {
-    mouseWheelHandlers_.push_back(EventHandlerData<OnMouseWheelFunc>(canvasId, func, userData));
-  }
-
-  // SDL ONLY
-  void GuiAdapter::SetKeyDownCallback(
-    std::string canvasId, void* userData, bool capture, OnKeyDownFunc   func)
-  {
-    keyDownHandlers_.push_back(EventHandlerData<OnKeyDownFunc>(canvasId, func, userData));
-  }
-
-  // SDL ONLY
-  void GuiAdapter::SetKeyUpCallback(
-    std::string canvasId, void* userData, bool capture, OnKeyUpFunc    func)
-  {
-    keyUpHandlers_.push_back(EventHandlerData<OnKeyUpFunc>(canvasId, func, userData));
-  }
-
-  // SDL ONLY
-  void GuiAdapter::SetGenericSdlEventCallback(
-    std::string canvasId, void* userData, bool capture, OnSdlEventCallback func)
-  {
-    sdlEventHandlers_.push_back(EventHandlerData<OnSdlEventCallback>(canvasId, func, userData));
-  }
-
-  // SDL ONLY
-  void GuiAdapter::OnAnimationFrame()
-  {
-    std::vector<size_t> disabledAnimationHandlers;
-    for (size_t i = 0; i < animationFrameHandlers_.size(); i++)
-    {
-      // TODO: fix time 
-      bool goOn = (*(animationFrameHandlers_[i].first))(0, animationFrameHandlers_[i].second);
-
-      // If the function returns false, we need to emulate what happens in Web 
-      // and remove the function from the handlers...
-      if (!goOn)
-        disabledAnimationHandlers.push_back(i);
-    }
-    for (size_t i = 0; i < disabledAnimationHandlers.size(); i++)
-    {
-      ORTHANC_ASSERT(animationFrameHandlers_.begin() + disabledAnimationHandlers[i] < animationFrameHandlers_.end());
-      animationFrameHandlers_.erase(animationFrameHandlers_.begin() + disabledAnimationHandlers[i]);
-    }
-  }
-
-  // SDL ONLY
-  void GuiAdapter::OnResize(unsigned int width, unsigned int height)
-  {
-    for (size_t i = 0; i < resizeHandlers_.size(); i++)
-    {
-      (*(resizeHandlers_[i].func))(
-        resizeHandlers_[i].canvasName, NULL, width, height, resizeHandlers_[i].userData);
-    }
-  }
-
-
-
-  void GuiAdapter::OnSdlGenericEvent(const SDL_Event& sdlEvent)
-  {
-    // Events related to a window are only sent to the related canvas
-    // User events are sent to everyone (we can't filter them here)
-    
-    /*
-    SDL_WindowEvent    SDL_WINDOWEVENT
-    SDL_KeyboardEvent     SDL_KEYDOWN
-                          SDL_KEYUP
-    SDL_TextEditingEvent  SDL_TEXTEDITING
-    SDL_TextInputEvent    SDL_TEXTINPUT
-    SDL_MouseMotionEvent  SDL_MOUSEMOTION
-    SDL_MouseButtonEvent  SDL_MOUSEBUTTONDOWN 
-                          SDL_MOUSEBUTTONUP
-    SDL_MouseWheelEvent   SDL_MOUSEWHEEL
-    SDL_UserEvent         SDL_USEREVENT through ::SDL_LASTEVENT-1
-    */
-
-    // if this string is left empty, it means the message will be sent to
-    // all widgets.
-    // otherwise, it contains the originating message window title
-
-    std::string windowTitle;
-    uint32_t windowId = 0;
-
-    if (sdlEvent.type == SDL_WINDOWEVENT)
-      windowId = sdlEvent.window.windowID;
-    else if (sdlEvent.type == SDL_KEYDOWN || sdlEvent.type == SDL_KEYUP)
-      windowId = sdlEvent.key.windowID;
-    else if (sdlEvent.type == SDL_TEXTEDITING)
-      windowId = sdlEvent.edit.windowID;
-    else if (sdlEvent.type == SDL_TEXTINPUT)
-      windowId = sdlEvent.text.windowID;
-    else if (sdlEvent.type == SDL_MOUSEMOTION)
-      windowId = sdlEvent.motion.windowID;
-    else if (sdlEvent.type == SDL_MOUSEBUTTONDOWN || sdlEvent.type == SDL_MOUSEBUTTONUP)
-      windowId = sdlEvent.button.windowID;
-    else if (sdlEvent.type == SDL_MOUSEWHEEL)
-      windowId = sdlEvent.wheel.windowID;
-    else if (sdlEvent.type >= SDL_USEREVENT && sdlEvent.type <= (SDL_LASTEVENT-1))
-      windowId = sdlEvent.user.windowID;
-
-    if (windowId != 0)
-    {
-      SDL_Window* sdlWindow = SDL_GetWindowFromID(windowId);
-      ORTHANC_ASSERT(sdlWindow != NULL, "Window ID \"" << windowId << "\" is not a valid SDL window ID!");
-      const char* windowTitleSz = SDL_GetWindowTitle(sdlWindow);
-      ORTHANC_ASSERT(windowTitleSz != NULL, "Window ID \"" << windowId << "\" has a NULL window title!");
-      windowTitle = windowTitleSz;
-      ORTHANC_ASSERT(windowTitle != "", "Window ID \"" << windowId << "\" has an empty window title!");
-    }
-
-    for (size_t i = 0; i < sdlEventHandlers_.size(); i++)
-    {
-      // normally, the handlers return a bool indicating whether they
-      // have handled the event or not, but we don't really care about this
-      std::string& canvasName = sdlEventHandlers_[i].canvasName;
-      
-      bool sendEvent = true;
-
-      if (windowTitle != "" && (canvasName != windowTitle))
-        sendEvent = false;
-
-      if (sendEvent)
-      {
-        OnSdlEventCallback func = sdlEventHandlers_[i].func;
-        (*func)(canvasName, sdlEvent, sdlEventHandlers_[i].userData);
-      }
-    }
-  }
-
-  // SDL ONLY
-  void GuiAdapter::OnMouseWheelEvent(uint32_t windowID, const GuiAdapterWheelEvent& event)
-  {
-    // the SDL window name IS the canvas name ("canvas" is used because this lib
-    // is designed for Wasm
-    SDL_Window* sdlWindow = SDL_GetWindowFromID(windowID);
-    ORTHANC_ASSERT(sdlWindow != NULL, "Window ID \"" << windowID << "\" is not a valid SDL window ID!");
-
-    const char* windowTitleSz = SDL_GetWindowTitle(sdlWindow);
-    ORTHANC_ASSERT(windowTitleSz != NULL, "Window ID \"" << windowID << "\" has a NULL window title!");
-
-    std::string windowTitle(windowTitleSz);
-    ORTHANC_ASSERT(windowTitle != "", "Window ID \"" << windowID << "\" has an empty window title!");
-
-    switch (event.mouse.type)
-    {
-    case GUIADAPTER_EVENT_WHEEL:
-      for (size_t i = 0; i < mouseWheelHandlers_.size(); i++)
-      {
-        if (mouseWheelHandlers_[i].canvasName == windowTitle)
-          (*(mouseWheelHandlers_[i].func))(windowTitle, &event, mouseWheelHandlers_[i].userData);
-      }
-      break;
-    default:
-      ORTHANC_ASSERT(false, "Wrong event.type: " << event.mouse.type << " in GuiAdapter::OnMouseWheelEvent(...)");
-      break;
-    }
-  }
-
-
-  void GuiAdapter::OnKeyboardEvent(uint32_t windowID, const GuiAdapterKeyboardEvent& event)
-  {
-    // only one-letter (ascii) keyboard events supported for now
-    ORTHANC_ASSERT(event.sym[0] != 0);
-    ORTHANC_ASSERT(event.sym[1] == 0);
-
-    SDL_Window* sdlWindow = SDL_GetWindowFromID(windowID);
-    ORTHANC_ASSERT(sdlWindow != NULL, "Window ID \"" << windowID << "\" is not a valid SDL window ID!");
-
-    const char* windowTitleSz = SDL_GetWindowTitle(sdlWindow);
-    ORTHANC_ASSERT(windowTitleSz != NULL, "Window ID \"" << windowID << "\" has a NULL window title!");
-
-    std::string windowTitle(windowTitleSz);
-    ORTHANC_ASSERT(windowTitle != "", "Window ID \"" << windowID << "\" has an empty window title!");
-
-    switch (event.type)
-    {
-    case GUIADAPTER_EVENT_KEYDOWN:
-      for (size_t i = 0; i < keyDownHandlers_.size(); i++)
-      {
-        (*(keyDownHandlers_[i].func))(windowTitle, &event, keyDownHandlers_[i].userData);
-      }
-      break;
-    case GUIADAPTER_EVENT_KEYUP:
-      for (size_t i = 0; i < keyUpHandlers_.size(); i++)
-      {
-        (*(keyUpHandlers_[i].func))(windowTitle, &event, keyUpHandlers_[i].userData);
-      }
-      break;
-    default:
-      ORTHANC_ASSERT(false, "Wrong event.type: " << event.type << " in GuiAdapter::OnKeyboardEvent(...)");
-      break;
-    }
-  }
-
-  // SDL ONLY
-  void GuiAdapter::OnMouseEvent(uint32_t windowID, const GuiAdapterMouseEvent& event)
-  {
-    if (windowID == 0)
-    {
-      LOG(WARNING) << "GuiAdapter::OnMouseEvent -- windowID == 0 and event won't be routed!";
-    }
-    else
-    {
-      // the SDL window name IS the canvas name ("canvas" is used because this lib
-      // is designed for Wasm
-      SDL_Window* sdlWindow = SDL_GetWindowFromID(windowID);
-
-      ORTHANC_ASSERT(sdlWindow != NULL, "Window ID \"" << windowID << "\" is not a valid SDL window ID!");
-
-      const char* windowTitleSz = SDL_GetWindowTitle(sdlWindow);
-      ORTHANC_ASSERT(windowTitleSz != NULL, "Window ID \"" << windowID << "\" has a NULL window title!");
-
-      std::string windowTitle(windowTitleSz);
-      ORTHANC_ASSERT(windowTitle != "", "Window ID \"" << windowID << "\" has an empty window title!");
-
-      switch (event.type)
-      {
-      case GUIADAPTER_EVENT_MOUSEDOWN:
-        for (size_t i = 0; i < mouseDownHandlers_.size(); i++)
-        {
-          if (mouseDownHandlers_[i].canvasName == windowTitle)
-            (*(mouseDownHandlers_[i].func))(windowTitle, &event, mouseDownHandlers_[i].userData);
-        }
-        break;
-      case GUIADAPTER_EVENT_MOUSEDBLCLICK:
-        for (size_t i = 0; i < mouseDblCickHandlers_.size(); i++)
-        {
-          if (mouseDblCickHandlers_[i].canvasName == windowTitle)
-            (*(mouseDblCickHandlers_[i].func))(windowTitle, &event, mouseDblCickHandlers_[i].userData);
-        }
-        break;
-      case GUIADAPTER_EVENT_MOUSEMOVE:
-        for (size_t i = 0; i < mouseMoveHandlers_.size(); i++)
-        {
-          if (mouseMoveHandlers_[i].canvasName == windowTitle)
-            (*(mouseMoveHandlers_[i].func))(windowTitle, &event, mouseMoveHandlers_[i].userData);
-        }
-        break;
-      case GUIADAPTER_EVENT_MOUSEUP:
-        for (size_t i = 0; i < mouseUpHandlers_.size(); i++)
-        {
-          if (mouseUpHandlers_[i].canvasName == windowTitle)
-            (*(mouseUpHandlers_[i].func))(windowTitle, &event, mouseUpHandlers_[i].userData);
-        }
-        break;
-      default:
-        ORTHANC_ASSERT(false, "Wrong event.type: " << event.type << " in GuiAdapter::OnMouseEvent(...)");
-        break;
-      }
-    }
-  }
-
-
-  // extern void Debug_SetContextToBeKilled(std::string title);
-  // extern void Debug_SetContextToBeRestored(std::string title);
-
-  // SDL ONLY
-  void GuiAdapter::RequestAnimationFrame(OnAnimationFrameFunc func, void* userData)
-  {
-    animationFrameHandlers_.push_back(std::make_pair(func, userData));
-  }
-
-# if ORTHANC_ENABLE_OPENGL == 1 && !defined(__APPLE__)   /* OpenGL debug is not available on OS X */
-
-  // SDL ONLY
-  static void GLAPIENTRY
-    OpenGLMessageCallback(GLenum source,
-      GLenum type,
-      GLuint id,
-      GLenum severity,
-      GLsizei length,
-      const GLchar * message,
-      const void* userParam)
-  {
-    if (severity != GL_DEBUG_SEVERITY_NOTIFICATION)
-    {
-      fprintf(stderr, "GL CALLBACK: %s type = 0x%x, severity = 0x%x, message = %s\n",
-        (type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : ""),
-        type, severity, message);
-    }
-  }
-# endif
-
-#if 0
-  // TODO: remove this when generic sdl event handlers are implemented in 
-  // the DoseView
-  // SDL ONLY
-  bool GuiAdapter::IsSdlViewPortRefreshEvent(const SDL_Event& event) const
-  {
-    SDL_Window* sdlWindow = SDL_GetWindowFromID(event.window.windowID);
-
-    ORTHANC_ASSERT(sdlWindow != NULL, "Window ID \"" << event.window.windowID << "\" is not a valid SDL window ID!");
-
-    const char* windowTitleSz = SDL_GetWindowTitle(sdlWindow);
-
-    // now we need to find the DoseView from from the canvas name!
-    // (and retrieve the SdlViewport)
-    boost::shared_ptr<IGuiAdapterWidget> foundWidget;
-    VisitWidgets([&foundWidget, windowTitleSz](auto widget)
-    {
-      if (widget->GetCanvasIdentifier() == std::string(windowTitleSz))
-        foundWidget = widget;
-    });
-    ORTHANC_ASSERT(foundWidget, "The window named: \"" << windowTitleSz << "\" was not found in the registered widgets!");
-    return foundWidget->GetSdlViewport().IsRefreshEvent(event);
-  }
-#endif
-
-  // SDL ONLY
-  void GuiAdapter::Run(GuiAdapterRunFunc func, void* cookie)
-  {
-#if 1
-    // TODO: MAKE THIS DYNAMIC !!! See SdlOpenGLViewport vs Cairo in ViewportWrapper
-# if ORTHANC_ENABLE_OPENGL == 1 && !defined(__APPLE__)
-    glEnable(GL_DEBUG_OUTPUT);
-    glDebugMessageCallback(OpenGLMessageCallback, 0);
-# endif
-#endif
-
-    // Uint32 SDL_GetWindowID(SDL_Window* window)
-    // SDL_Window* SDL_GetWindowFromID(Uint32 id)   // may return NULL
-
-    bool stop = false;
-    while (!stop)
-    {
-      {
-        // TODO: lock all viewports here! (use a scoped object)
-        if(func != NULL)
-          (*func)(cookie);
-        OnAnimationFrame(); // in SDL we must call it
-      }
-
-      while (!stop)
-      {
-        std::vector<SDL_Event> sdlEvents;
-        std::map<Uint32,SDL_Event> userEventsMap;
-        
-        SDL_Event sdlEvent;
-
-        // FIRST: collect all pending events
-        while (SDL_PollEvent(&sdlEvent) != 0)
-        {
-          if ( (sdlEvent.type >= SDL_USEREVENT) && 
-               (sdlEvent.type < SDL_LASTEVENT) )
-          {
-            // we don't want to have multiple events with the same event.type
-            userEventsMap[sdlEvent.type] = sdlEvent;
-          }
-          else
-          {
-            sdlEvents.push_back(sdlEvent);
-          }
-        }
-
-        // SECOND: collect all user events
-        for (std::map<Uint32,SDL_Event>::const_iterator it = userEventsMap.begin(); it != userEventsMap.end(); ++it)
-          sdlEvents.push_back(it->second);
-                
-        // now process the events
-        for (std::vector<SDL_Event>::const_iterator it = sdlEvents.begin(); it != sdlEvents.end(); ++it)
-        {
-          const SDL_Event& sdlEvent = *it;
-          // TODO: lock all viewports here! (use a scoped object)
-
-          if (sdlEvent.type == SDL_QUIT)
-          {
-            // TODO: call exit callbacks here
-            stop = true;
-            break;
-          }
-          else if ((sdlEvent.type == SDL_MOUSEMOTION) ||
-            (sdlEvent.type == SDL_MOUSEBUTTONDOWN) ||
-                   (sdlEvent.type == SDL_MOUSEBUTTONUP))
-          {
-            int scancodeCount = 0;
-            const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount);
-            bool ctrlPressed(false);
-            bool shiftPressed(false);
-            bool altPressed(false);
-
-            if (SDL_SCANCODE_LCTRL < scancodeCount && keyboardState[SDL_SCANCODE_LCTRL])
-              ctrlPressed = true;
-            if (SDL_SCANCODE_RCTRL < scancodeCount && keyboardState[SDL_SCANCODE_RCTRL])
-              ctrlPressed = true;
-            if (SDL_SCANCODE_LSHIFT < scancodeCount && keyboardState[SDL_SCANCODE_LSHIFT])
-              shiftPressed = true;
-            if (SDL_SCANCODE_RSHIFT < scancodeCount && keyboardState[SDL_SCANCODE_RSHIFT])
-              shiftPressed = true;
-            if (SDL_SCANCODE_LALT < scancodeCount && keyboardState[SDL_SCANCODE_LALT])
-              altPressed = true;
-
-            GuiAdapterMouseEvent dest;
-            ConvertFromPlatform(dest, ctrlPressed, shiftPressed, altPressed, sdlEvent);
-            OnMouseEvent(sdlEvent.window.windowID, dest);
-  #if 0
-            // for reference, how to create trackers
-            if (tracker)
-            {
-              PointerEvent e;
-              e.AddPosition(compositor.GetPixelCenterCoordinates(
-                sdlEvent.button.x, sdlEvent.button.y));
-              tracker->PointerMove(e);
-            }
-  #endif
-          }
-          else if (sdlEvent.type == SDL_MOUSEWHEEL)
-          {
-
-            int scancodeCount = 0;
-            const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount);
-            bool ctrlPressed(false);
-            bool shiftPressed(false);
-            bool altPressed(false);
-
-            if (SDL_SCANCODE_LCTRL < scancodeCount && keyboardState[SDL_SCANCODE_LCTRL])
-              ctrlPressed = true;
-            if (SDL_SCANCODE_RCTRL < scancodeCount && keyboardState[SDL_SCANCODE_RCTRL])
-              ctrlPressed = true;
-            if (SDL_SCANCODE_LSHIFT < scancodeCount && keyboardState[SDL_SCANCODE_LSHIFT])
-              shiftPressed = true;
-            if (SDL_SCANCODE_RSHIFT < scancodeCount && keyboardState[SDL_SCANCODE_RSHIFT])
-              shiftPressed = true;
-            if (SDL_SCANCODE_LALT < scancodeCount && keyboardState[SDL_SCANCODE_LALT])
-              altPressed = true;
-
-            GuiAdapterWheelEvent dest;
-            ConvertFromPlatform(dest, ctrlPressed, shiftPressed, altPressed, sdlEvent);
-            OnMouseWheelEvent(sdlEvent.window.windowID, dest);
-
-            //KeyboardModifiers modifiers = GetKeyboardModifiers(keyboardState, scancodeCount);
-
-            //int x, y;
-            //SDL_GetMouseState(&x, &y);
-
-            //if (sdlEvent.wheel.y > 0)
-            //{
-            //  locker.GetCentralViewport().MouseWheel(MouseWheelDirection_Up, x, y, modifiers);
-            //}
-            //else if (sdlEvent.wheel.y < 0)
-            //{
-            //  locker.GetCentralViewport().MouseWheel(MouseWheelDirection_Down, x, y, modifiers);
-            //}
-          }
-          else if (sdlEvent.type == SDL_WINDOWEVENT &&
-            (sdlEvent.window.event == SDL_WINDOWEVENT_RESIZED ||
-             sdlEvent.window.event == SDL_WINDOWEVENT_SIZE_CHANGED))
-          {
-  #if 0
-            tracker.reset();
-  #endif
-            OnResize(sdlEvent.window.data1, sdlEvent.window.data2);
-          }
-          else if (sdlEvent.type == SDL_KEYDOWN && sdlEvent.key.repeat == 0 /* Ignore key bounce */)
-          {
-            switch (sdlEvent.key.keysym.sym)
-            {
-            case SDLK_f:
-              // window.GetWindow().ToggleMaximize(); //TODO: move to particular handler
-              break;
-
-            // This commented out code was used to debug the context
-            // loss/restoring code (2019-08-10)
-            // case SDLK_k:
-            //   {
-            //     SDL_Window* window = SDL_GetWindowFromID(sdlEvent.window.windowID);
-            //     std::string windowTitle(SDL_GetWindowTitle(window));
-            //     Debug_SetContextToBeKilled(windowTitle);
-            //   }
-            //   break;
-            // case SDLK_l:
-            //   {
-            //     SDL_Window* window = SDL_GetWindowFromID(sdlEvent.window.windowID);
-            //     std::string windowTitle(SDL_GetWindowTitle(window));
-            //     Debug_SetContextToBeRestored(windowTitle);
-            //   }
-            //   break;
-
-            case SDLK_q:
-              stop = true;
-              break;
-
-            default:
-              GuiAdapterKeyboardEvent dest;
-              ConvertFromPlatform(dest, sdlEvent);
-              OnKeyboardEvent(sdlEvent.window.windowID, dest);
-              break;
-            }
-          }
-        
-          OnSdlGenericEvent(sdlEvent);
-        }
-        SDL_Delay(1);
-      }
-    }
-  }
-#endif
-}
-
--- a/OrthancStone/Sources/Deprecated/GuiAdapter.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,377 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-#pragma once
-
-#include <string>
-
-#if ORTHANC_ENABLE_WASM != 1
-# ifdef __EMSCRIPTEN__
-#   error __EMSCRIPTEN__ is defined and ORTHANC_ENABLE_WASM != 1
-# endif
-#endif
-
-#if ORTHANC_ENABLE_WASM == 1
-# ifndef __EMSCRIPTEN__
-#   error __EMSCRIPTEN__ is not defined and ORTHANC_ENABLE_WASM == 1
-# endif
-#endif
-
-#if ORTHANC_ENABLE_WASM == 1
-# include <emscripten/html5.h>
-#else
-# if ORTHANC_ENABLE_SDL == 1
-#   include <SDL.h>
-# endif
-#endif
-
-#include "../StoneException.h"
-
-#include <vector>
-#include <boost/shared_ptr.hpp>
-#include <boost/weak_ptr.hpp>
-
-namespace OrthancStone
-{
-#if ORTHANC_ENABLE_SDL == 1
-  class SdlViewport;
-#endif
-
-#if 0
-
-  /**
-  This interface is used to store the widgets that are controlled by the 
-  GuiAdapter and receive event callbacks.
-  The callbacks may possibly be downcast (using dynamic_cast, for safety) \
-  to the actual widget type
-  */
-  class IGuiAdapterWidget
-  {
-  public:
-    virtual ~IGuiAdapterWidget() {}
-    
-#if #if ORTHANC_ENABLE_SDL == 1
-    /**
-    Returns the SdlViewport that this widget contains. If the underlying 
-    viewport type is *not* SDL, then an error is returned.
-    */
-    virtual SdlViewport& GetSdlViewport() = 0;
-#endif
-  };
-
-#endif
-
-  enum GuiAdapterMouseButtonType
-  {
-    GUIADAPTER_MOUSEBUTTON_LEFT = 0,
-    GUIADAPTER_MOUSEBUTTON_MIDDLE = 1,
-    GUIADAPTER_MOUSEBUTTON_RIGHT = 2
-  };
-
-
-  enum GuiAdapterHidEventType
-  {
-    GUIADAPTER_EVENT_MOUSEDOWN      = 1973,
-    GUIADAPTER_EVENT_MOUSEMOVE      = 1974,
-    GUIADAPTER_EVENT_MOUSEDBLCLICK  = 1975,
-    GUIADAPTER_EVENT_MOUSEUP        = 1976,
-    GUIADAPTER_EVENT_WHEEL          = 1977,
-    GUIADAPTER_EVENT_KEYDOWN        = 1978,
-    GUIADAPTER_EVENT_KEYUP          = 1979,
-  };
-
-  const unsigned int GUIADAPTER_DELTA_PIXEL = 2973;
-  const unsigned int GUIADAPTER_DELTA_LINE  = 2974;
-  const unsigned int GUIADAPTER_DELTA_PAGE  = 2975;
-
-  struct GuiAdapterUiEvent;
-  struct GuiAdapterMouseEvent;
-  struct GuiAdapterWheelEvent;
-  struct GuiAdapterKeyboardEvent;
-
-#if 1
-  typedef bool (*OnMouseEventFunc)    (std::string canvasId, const GuiAdapterMouseEvent* mouseEvent, void* userData);
-  typedef bool (*OnMouseWheelFunc)    (std::string canvasId, const GuiAdapterWheelEvent* wheelEvent, void* userData);
-  typedef bool (*OnKeyDownFunc)       (std::string canvasId, const GuiAdapterKeyboardEvent*   keyEvent,   void* userData);
-  typedef bool (*OnKeyUpFunc)         (std::string canvasId, const GuiAdapterKeyboardEvent*   keyEvent,   void* userData);
-  typedef bool (*OnAnimationFrameFunc)(double time, void* userData);
-  
-#if ORTHANC_ENABLE_SDL == 1
-  typedef bool (*OnSdlEventCallback)  (std::string canvasId, const SDL_Event& sdlEvent, void* userData);
-
-  typedef bool (*OnSdlWindowResizeFunc)(std::string canvasId, 
-                                        const GuiAdapterUiEvent* uiEvent, 
-                                        unsigned int width, 
-                                        unsigned int height, 
-                                        void* userData);
-
-
-#endif
-
-#else
-
-#if ORTHANC_ENABLE_WASM == 1
-  typedef EM_BOOL (*OnMouseEventFunc)(int eventType, const EmscriptenMouseEvent* mouseEvent, void* userData);
-  typedef EM_BOOL (*OnMouseWheelFunc)(int eventType, const EmscriptenWheelEvent* wheelEvent, void* userData);
-  typedef EM_BOOL (*OnKeyDownFunc)   (int eventType, const EmscriptenKeyboardEvent* keyEvent, void* userData);
-  typedef EM_BOOL (*OnKeyUpFunc)     (int eventType, const EmscriptenKeyboardEvent* keyEvent, void* userData);
-
-  typedef EM_BOOL (*OnAnimationFrameFunc)(double time, void* userData);
-  typedef EM_BOOL (*OnWindowResizeFunc)(int eventType, const EmscriptenUiEvent* uiEvent, void* userData);
-#else
-  typedef bool    (*OnMouseEventFunc)(int eventType, const SDL_Event* mouseEvent, void* userData);
-  typedef bool    (*OnMouseWheelFunc)(int eventType, const SDL_Event* wheelEvent, void* userData);
-  typedef bool    (*OnKeyDownFunc)   (int eventType, const SDL_Event* keyEvent,   void* userData);
-  typedef bool    (*OnKeyUpFunc)     (int eventType, const SDL_Event* keyEvent,   void* userData);
-
-  typedef bool    (*OnAnimationFrameFunc)(double time, void* userData);
-  typedef bool    (*OnWindowResizeFunc)(int eventType, const GuiAdapterUiEvent* uiEvent, void* userData);
-#endif
-
-#endif
-  struct GuiAdapterMouseEvent
-  {
-    GuiAdapterHidEventType type;
-    //double                   timestamp;
-    //long                     screenX;
-    //long                     screenY;
-    //long                     clientX;
-    //long                     clientY;
-    bool                     ctrlKey;
-    bool                     shiftKey;
-    bool                     altKey;
-    //bool                     metaKey;
-    unsigned short           button;
-    //unsigned short           buttons;
-    //long                     movementX;
-    //long                     movementY;
-    long                     targetX;
-    long                     targetY;
-    // canvasX and canvasY are deprecated - there no longer exists a Module['canvas'] object, so canvasX/Y are no longer reported (register a listener on canvas directly to get canvas coordinates, or translate manually)
-    //long                     canvasX;
-    //long                     canvasY;
-    //long                     padding;
-
-  public:
-    GuiAdapterMouseEvent()
-      : ctrlKey(false),
-        shiftKey(false),
-        altKey(false)
-    {
-    }
-  };
-
-  struct GuiAdapterWheelEvent {
-    GuiAdapterMouseEvent mouse;
-    double deltaX;
-    double deltaY;
-    unsigned long deltaMode;
-  };
-
-  // we don't use any data now
-  struct GuiAdapterUiEvent {};
-
-  // EmscriptenKeyboardEvent
-  struct GuiAdapterKeyboardEvent
-  {
-    GuiAdapterHidEventType type;
-    char sym[32];
-    bool ctrlKey;
-    bool shiftKey;
-    bool altKey;
-  };
-
-  std::ostream& operator<<(std::ostream& os, const GuiAdapterKeyboardEvent& event);
-  std::ostream& operator<<(std::ostream& os, const GuiAdapterMouseEvent& event);
-
-  /*
-    Mousedown event trigger when either the left or right (or middle) mouse is pressed 
-    on the object;
-
-    Mouseup event trigger when either the left or right (or middle) mouse is released
-    above the object after triggered mousedown event and held.
-
-    Click event trigger when the only left mouse button is pressed and released on the
-    same object, requires the Mousedown and Mouseup event happened before Click event.
-
-    The normal expect trigger order: onMousedown >> onMouseup >> onClick
-
-    Testing in Chrome v58, the time between onMouseup and onClick events are around 
-    7ms to 15ms
-
-    FROM: https://codingrepo.com/javascript/2017/05/19/javascript-difference-mousedown-mouseup-click-events/
-  */
-#if ORTHANC_ENABLE_WASM == 1
-  void ConvertFromPlatform(GuiAdapterUiEvent& dest, int eventType, const EmscriptenUiEvent& src);
-
-  void ConvertFromPlatform(GuiAdapterMouseEvent& dest, int eventType, const EmscriptenMouseEvent& src);
-  
-  void ConvertFromPlatform(GuiAdapterWheelEvent& dest, int eventType, const EmscriptenWheelEvent& src);
-
-  void ConvertFromPlatform(GuiAdapterKeyboardEvent& dest, const EmscriptenKeyboardEvent& src);
-#else
-
-# if ORTHANC_ENABLE_SDL == 1
-  void ConvertFromPlatform(GuiAdapterMouseEvent& dest, bool ctrlPressed, bool shiftPressed, bool altPressed, const SDL_Event& source);
-
-  void ConvertFromPlatform(GuiAdapterWheelEvent& dest, bool ctrlPressed, bool shiftPressed, bool altPressed, const SDL_Event& source);
-
-  void ConvertFromPlatform(GuiAdapterKeyboardEvent& dest, const SDL_Event& source);
-
-# endif
-
-#endif
-
-  typedef void (*GuiAdapterRunFunc)(void*);
-
-  class GuiAdapter
-  {
-  public:
-    GuiAdapter()
-    {
-      ORTHANC_ASSERT(s_instanceCount == 0);
-      s_instanceCount = 1;
-    }
-
-    ~GuiAdapter()
-    {
-      s_instanceCount -= 1;
-    }
-
-    /**
-      emscripten_set_resize_callback("EMSCRIPTEN_EVENT_TARGET_WINDOW", NULL, false, OnWindowResize);
-
-      emscripten_set_wheel_callback("#mycanvas1", widget1_.get(), false, OnXXXMouseWheel);
-      emscripten_set_wheel_callback("#mycanvas2", widget2_.get(), false, OnXXXMouseWheel);
-      emscripten_set_wheel_callback("#mycanvas3", widget3_.get(), false, OnXXXMouseWheel);
-
-      emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, false, OnKeyDown); ---> NO!
-      emscripten_set_keyup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, false, OnKeyUp);
-
-      emscripten_request_animation_frame_loop(OnAnimationFrame, NULL);
-    
-      SDL:
-      see https://wiki.libsdl.org/SDL_CaptureMouse
-
-    */
-
-    void SetMouseDownCallback       (std::string canvasId, void* userData, bool capture, OnMouseEventFunc   func);
-    void SetMouseDblClickCallback   (std::string canvasId, void* userData, bool capture, OnMouseEventFunc   func);
-    void SetMouseMoveCallback       (std::string canvasId, void* userData, bool capture, OnMouseEventFunc   func);
-    void SetMouseUpCallback         (std::string canvasId, void* userData, bool capture, OnMouseEventFunc   func);
-    void SetWheelCallback           (std::string canvasId, void* userData, bool capture, OnMouseWheelFunc   func);
-    void SetKeyDownCallback         (std::string canvasId, void* userData, bool capture, OnKeyDownFunc      func);
-    void SetKeyUpCallback           (std::string canvasId, void* userData, bool capture, OnKeyUpFunc        func);
-
-#if ORTHANC_ENABLE_SDL == 1
-
-    void SetGenericSdlEventCallback (std::string canvasId, void* userData, bool capture, OnSdlEventCallback func);
-
-    typedef bool (*OnSdlEventCallback)  (std::string canvasId, const SDL_Event& sdlEvent, void* userData);
-
-    // if you pass "#window", then any Window resize will trigger the callback
-    // (this special string is converted to EMSCRIPTEN_EVENT_TARGET_WINDOW in DOM, when DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1)
-    void SetSdlResizeCallback(std::string canvasId, 
-                              void* userData, 
-                              bool capture, 
-                              OnSdlWindowResizeFunc func);
-#endif
-
-    void RequestAnimationFrame(OnAnimationFrameFunc func, void* userData);
-
-    // TODO: implement and call to remove canvases [in SDL, although code should be generic]
-    void SetOnExitCallback();
-
-    /**
-    Under SDL, this function does NOT return until all windows have been closed.
-    Under wasm, it returns without doing anything, since the event loop is managed
-    by the browser.
-    */
-    void Run(GuiAdapterRunFunc func = NULL, void* cookie = NULL);
-
-  private:
-
-#if ORTHANC_ENABLE_SDL == 1
-    /**
-    Gives observers a chance to react based on generic event handlers. This 
-    is used, for instance, when the viewport lock interface is invalidated.
-    */
-    void OnSdlGenericEvent(const SDL_Event& sdlEvent);
-#endif
-
-    /**
-    In SDL, this executes all the registered headers
-    */
-    void OnAnimationFrame();
-
-    //void RequestAnimationFrame(OnAnimationFrameFunc func, void* userData);
-    std::vector<std::pair<OnAnimationFrameFunc, void*> >  
-      animationFrameHandlers_;
-    
-    void OnResize(unsigned int width, unsigned int height);
-
-#if ORTHANC_ENABLE_SDL == 1
-    template<typename Func>
-    struct EventHandlerData
-    {
-      EventHandlerData(std::string canvasName, Func func, void* userData) 
-        : canvasName(canvasName)
-        , func(func)
-        , userData(userData)
-      {
-      }
-
-      std::string canvasName;
-      Func        func;
-      void*       userData;
-    };
-    std::vector<EventHandlerData<OnSdlWindowResizeFunc> > resizeHandlers_;
-    std::vector<EventHandlerData<OnMouseEventFunc  > >    mouseDownHandlers_;
-    std::vector<EventHandlerData<OnMouseEventFunc  > >    mouseDblCickHandlers_;
-    std::vector<EventHandlerData<OnMouseEventFunc  > >    mouseMoveHandlers_;
-    std::vector<EventHandlerData<OnMouseEventFunc  > >    mouseUpHandlers_;
-    std::vector<EventHandlerData<OnMouseWheelFunc  > >    mouseWheelHandlers_;
-    std::vector<EventHandlerData<OnKeyDownFunc > >        keyDownHandlers_;
-    std::vector<EventHandlerData<OnKeyUpFunc > >          keyUpHandlers_;
-    std::vector<EventHandlerData<OnSdlEventCallback > >   sdlEventHandlers_;
-
-    /**
-    This executes all the registered headers if needed (in wasm, the browser
-    deals with this)
-    */
-    void OnMouseEvent(uint32_t windowID, const GuiAdapterMouseEvent& event);
-
-    void OnKeyboardEvent(uint32_t windowID, const GuiAdapterKeyboardEvent& event);
-
-    /**
-    Same remark as OnMouseEvent
-    */
-    void OnMouseWheelEvent(uint32_t windowID, const GuiAdapterWheelEvent& event);
-
-#endif
-
-    /**
-    This executes all the registered headers if needed (in wasm, the browser
-    deals with this)
-    */
-    void ViewportsUpdateSize();
-
-    static int s_instanceCount;
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Layers/CircleMeasureTracker.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "CircleMeasureTracker.h"
-
-#include <stdio.h>
-#include <boost/math/constants/constants.hpp>
-
-namespace Deprecated
-{
-  CircleMeasureTracker::CircleMeasureTracker(IStatusBar* statusBar,
-                                             const OrthancStone::CoordinateSystem3D& slice,
-                                             double x, 
-                                             double y,
-                                             uint8_t red,
-                                             uint8_t green,
-                                             uint8_t blue,
-                                             const Orthanc::Font& font) :
-    statusBar_(statusBar),
-    slice_(slice),
-    x1_(x),
-    y1_(y),
-    x2_(x),
-    y2_(y),
-    font_(font)
-  {
-    color_[0] = red;
-    color_[1] = green;
-    color_[2] = blue;
-  }
-    
-
-  void CircleMeasureTracker::Render(OrthancStone::CairoContext& context,
-                                    double zoom)
-  {
-    double x = (x1_ + x2_) / 2.0;
-    double y = (y1_ + y2_) / 2.0;
-
-    OrthancStone::Vector tmp;
-    OrthancStone::LinearAlgebra::AssignVector(tmp, x2_ - x1_, y2_ - y1_);
-    double r = boost::numeric::ublas::norm_2(tmp) / 2.0;
-
-    context.SetSourceColor(color_[0], color_[1], color_[2]);
-
-    cairo_t* cr = context.GetObject();
-    cairo_save(cr);
-    cairo_set_line_width(cr, 2.0 / zoom);
-    cairo_translate(cr, x, y);
-    cairo_arc(cr, 0, 0, r, 0, 2.0 * boost::math::constants::pi<double>());
-    cairo_stroke_preserve(cr);
-    cairo_stroke(cr);
-    cairo_restore(cr);
-
-    context.DrawText(font_, FormatRadius(), x, y, OrthancStone::BitmapAnchor_Center);
-  }
-    
-
-  double CircleMeasureTracker::GetRadius() const  // In millimeters
-  {
-    OrthancStone::Vector a = slice_.MapSliceToWorldCoordinates(x1_, y1_);
-    OrthancStone::Vector b = slice_.MapSliceToWorldCoordinates(x2_, y2_);
-    return boost::numeric::ublas::norm_2(b - a) / 2.0;
-  }
-
-
-  std::string CircleMeasureTracker::FormatRadius() const
-  {
-    char buf[64];
-    sprintf(buf, "%0.01f cm", GetRadius() / 10.0);
-    return buf;
-  }
-
-  void CircleMeasureTracker::MouseMove(int displayX,
-                                       int displayY,
-                                       double x,
-                                       double y,
-                                       const std::vector<Touch>& displayTouches,
-                                       const std::vector<Touch>& sceneTouches)
-  {
-    x2_ = x;
-    y2_ = y;
-
-    if (statusBar_ != NULL)
-    {
-      statusBar_->SetMessage("Circle radius: " + FormatRadius());
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Layers/CircleMeasureTracker.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../Widgets/IWorldSceneMouseTracker.h"
-#include "../Viewport/IStatusBar.h"
-#include "../../Toolbox/CoordinateSystem3D.h"
-
-#include <Images/Font.h>
-
-namespace Deprecated
-{
-  class CircleMeasureTracker : public IWorldSceneMouseTracker
-  {
-  private:
-    IStatusBar*           statusBar_;
-    OrthancStone::CoordinateSystem3D    slice_;
-    double                x1_;
-    double                y1_;
-    double                x2_;
-    double                y2_;
-    uint8_t               color_[3];
-    const Orthanc::Font&  font_;
-
-  public:
-    CircleMeasureTracker(IStatusBar* statusBar,
-                         const OrthancStone::CoordinateSystem3D& slice,
-                         double x, 
-                         double y,
-                         uint8_t red,
-                         uint8_t green,
-                         uint8_t blue,
-                         const Orthanc::Font& font);
-    
-    virtual bool HasRender() const
-    {
-      return true;
-    }
-
-    virtual void Render(OrthancStone::CairoContext& context,
-                        double zoom);
-    
-    double GetRadius() const;  // In millimeters
-
-    std::string FormatRadius() const;
-
-    virtual void MouseUp()
-    {
-      // Possibly create a new landmark "volume" with the circle in subclasses
-    }
-
-    virtual void MouseMove(int displayX,
-                           int displayY,
-                           double x,
-                           double y,
-                           const std::vector<Touch>& displayTouches,
-                           const std::vector<Touch>& sceneTouches);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Layers/ColorFrameRenderer.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "ColorFrameRenderer.h"
-
-#include <OrthancException.h>
-#include <Images/Image.h>
-#include <Images/ImageProcessing.h>
-
-namespace Deprecated
-{
-  OrthancStone::CairoSurface* ColorFrameRenderer::GenerateDisplay(const RenderStyle& style)
-  {
-    std::unique_ptr<OrthancStone::CairoSurface> display
-      (new OrthancStone::CairoSurface(frame_->GetWidth(), frame_->GetHeight(), false /* no alpha */));
-
-    Orthanc::ImageAccessor target;
-    display->GetWriteableAccessor(target);
-    
-    Orthanc::ImageProcessing::Convert(target, *frame_);
-
-    return display.release();
-  }
-
-
-  ColorFrameRenderer::ColorFrameRenderer(const Orthanc::ImageAccessor& frame,
-                                         const OrthancStone::CoordinateSystem3D& framePlane,
-                                         double pixelSpacingX,
-                                         double pixelSpacingY,
-                                         bool isFullQuality) :
-    FrameRenderer(framePlane, pixelSpacingX, pixelSpacingY, isFullQuality),
-    frame_(Orthanc::Image::Clone(frame))
-  {
-    if (frame_.get() == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    if (frame_->GetFormat() != Orthanc::PixelFormat_RGB24)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat);
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Layers/ColorFrameRenderer.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "FrameRenderer.h"
-
-namespace Deprecated
-{
-  class ColorFrameRenderer : public FrameRenderer
-  {
-  private:
-    std::unique_ptr<Orthanc::ImageAccessor>   frame_;  // In RGB24
-
-  protected:
-    virtual OrthancStone::CairoSurface* GenerateDisplay(const RenderStyle& style);
-
-  public:
-    ColorFrameRenderer(const Orthanc::ImageAccessor& frame,
-                       const OrthancStone::CoordinateSystem3D& framePlane,
-                       double pixelSpacingX,
-                       double pixelSpacingY,
-                       bool isFullQuality);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Layers/DicomSeriesVolumeSlicer.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,181 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "DicomSeriesVolumeSlicer.h"
-
-#include "FrameRenderer.h"
-#include "../Toolbox/DicomFrameConverter.h"
-
-#include <Logging.h>
-#include <OrthancException.h>
-
-#include <boost/lexical_cast.hpp>
-
-namespace Deprecated
-{
-
-  void DicomSeriesVolumeSlicer::OnSliceGeometryReady(const OrthancSlicesLoader::SliceGeometryReadyMessage& message)
-  {
-    if (message.GetOrigin().GetSlicesCount() > 0)
-    {
-      BroadcastMessage(IVolumeSlicer::GeometryReadyMessage(*this));
-    }
-    else
-    {
-      BroadcastMessage(IVolumeSlicer::GeometryErrorMessage(*this));
-    }
-  }
-
-  void DicomSeriesVolumeSlicer::OnSliceGeometryError(const OrthancSlicesLoader::SliceGeometryErrorMessage& message)
-  {
-    BroadcastMessage(IVolumeSlicer::GeometryErrorMessage(*this));
-  }
-
-
-  class DicomSeriesVolumeSlicer::RendererFactory : public LayerReadyMessage::IRendererFactory
-  {
-  private:
-    const OrthancSlicesLoader::SliceImageReadyMessage&  message_;
-
-  public:
-    RendererFactory(const OrthancSlicesLoader::SliceImageReadyMessage& message) :
-      message_(message)
-    {
-    }
-
-    virtual ILayerRenderer* CreateRenderer() const
-    {
-      bool isFull = (message_.GetEffectiveQuality() == SliceImageQuality_FullPng ||
-                     message_.GetEffectiveQuality() == SliceImageQuality_FullPam);
-
-      return FrameRenderer::CreateRenderer(message_.GetImage(), message_.GetSlice(), isFull);
-    }
-  };
-
-  void DicomSeriesVolumeSlicer::OnSliceImageReady(const OrthancSlicesLoader::SliceImageReadyMessage& message)
-  {
-    // first notify that the pixel data of the frame is ready (targeted to, i.e: an image cache)
-    BroadcastMessage(FrameReadyMessage(*this, message.GetImage(), 
-                                  message.GetEffectiveQuality(), message.GetSlice()));
-
-    // then notify that the layer is ready for rendering
-    RendererFactory factory(message);
-    BroadcastMessage(IVolumeSlicer::LayerReadyMessage(*this, factory, message.GetSlice().GetGeometry()));
-  }
-
-  void DicomSeriesVolumeSlicer::OnSliceImageError(const OrthancSlicesLoader::SliceImageErrorMessage& message)
-  {
-    BroadcastMessage(IVolumeSlicer::LayerErrorMessage(*this, message.GetSlice().GetGeometry()));
-  }
-
-
-  DicomSeriesVolumeSlicer::DicomSeriesVolumeSlicer() :
-    quality_(SliceImageQuality_FullPng)
-  {
-  }
-
-  void DicomSeriesVolumeSlicer::Connect(boost::shared_ptr<OrthancApiClient> orthanc)
-  {
-    loader_.reset(new OrthancSlicesLoader(orthanc));
-    Register<OrthancSlicesLoader::SliceGeometryReadyMessage>(*loader_, &DicomSeriesVolumeSlicer::OnSliceGeometryReady);
-    Register<OrthancSlicesLoader::SliceGeometryErrorMessage>(*loader_, &DicomSeriesVolumeSlicer::OnSliceGeometryError);
-    Register<OrthancSlicesLoader::SliceImageReadyMessage>(*loader_, &DicomSeriesVolumeSlicer::OnSliceImageReady);
-    Register<OrthancSlicesLoader::SliceImageErrorMessage>(*loader_, &DicomSeriesVolumeSlicer::OnSliceImageError);
-  }
-  
-  void DicomSeriesVolumeSlicer::LoadSeries(const std::string& seriesId)
-  {
-    if (loader_.get() == NULL)
-    {
-      // Should have called "Connect()"
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-    
-    loader_->ScheduleLoadSeries(seriesId);
-  }
-
-
-  void DicomSeriesVolumeSlicer::LoadInstance(const std::string& instanceId)
-  {
-    if (loader_.get() == NULL)
-    {
-      // Should have called "Connect()"
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-    
-    loader_->ScheduleLoadInstance(instanceId);
-  }
-
-
-  void DicomSeriesVolumeSlicer::LoadFrame(const std::string& instanceId,
-                                          unsigned int frame)
-  {
-    if (loader_.get() == NULL)
-    {
-      // Should have called "Connect()"
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-    
-    loader_->ScheduleLoadFrame(instanceId, frame);
-  }
-
-
-  bool DicomSeriesVolumeSlicer::GetExtent(std::vector<OrthancStone::Vector>& points,
-                                          const OrthancStone::CoordinateSystem3D& viewportSlice)
-  {
-    if (loader_.get() == NULL)
-    {
-      // Should have called "Connect()"
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-    
-    size_t index;
-
-    if (loader_->IsGeometryReady() &&
-        loader_->LookupSlice(index, viewportSlice))
-    {
-      loader_->GetSlice(index).GetExtent(points);
-      return true;
-    }
-    else
-    {
-      return false;
-    }
-  }
-
-  
-  void DicomSeriesVolumeSlicer::ScheduleLayerCreation(const OrthancStone::CoordinateSystem3D& viewportSlice)
-  {
-    if (loader_.get() == NULL)
-    {
-      // Should have called "Connect()"
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-    
-    size_t index;
-
-    if (loader_->IsGeometryReady() &&
-        loader_->LookupSlice(index, viewportSlice))
-    {
-      loader_->ScheduleLoadSliceImage(index, quality_);
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Layers/DicomSeriesVolumeSlicer.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "IVolumeSlicer.h"
-#include "../../Messages/ObserverBase.h"
-#include "../Toolbox/IWebService.h"
-#include "../Toolbox/OrthancSlicesLoader.h"
-#include "../Toolbox/OrthancApiClient.h"
-
-namespace Deprecated
-{  
-  // this class is in charge of loading a Frame.
-  // once it's been loaded (first the geometry and then the image),
-  // messages are sent to observers so they can use it
-  class DicomSeriesVolumeSlicer :
-    public IVolumeSlicer,
-    public OrthancStone::ObserverBase<DicomSeriesVolumeSlicer>
-    //private OrthancSlicesLoader::ISliceLoaderObserver
-  {
-  public:
-    // TODO: Add "frame" and "instanceId"
-    class FrameReadyMessage : public OrthancStone::OriginMessage<DicomSeriesVolumeSlicer>
-    {
-      ORTHANC_STONE_MESSAGE(__FILE__, __LINE__);
-      
-    private:
-      const Orthanc::ImageAccessor&  frame_;
-      SliceImageQuality              imageQuality_;
-      const Slice&                   slice_;
-
-    public:
-      FrameReadyMessage(DicomSeriesVolumeSlicer& origin,
-                        const Orthanc::ImageAccessor& frame,
-                        SliceImageQuality imageQuality,
-                        const Slice& slice) :
-        OriginMessage(origin),
-        frame_(frame),
-        imageQuality_(imageQuality),
-        slice_(slice)
-      {
-      }
-
-      const Orthanc::ImageAccessor& GetFrame() const
-      {
-        return frame_;
-      }
-
-      SliceImageQuality GetImageQuality() const
-      {
-        return imageQuality_;
-      }
-
-      const Slice& GetSlice() const
-      {
-        return slice_;
-      }
-    };
-
-    
-  private:
-    class RendererFactory;
-    
-    boost::shared_ptr<OrthancSlicesLoader> loader_;
-    SliceImageQuality    quality_;
-
-  public:
-    DicomSeriesVolumeSlicer();
-
-    void Connect(boost::shared_ptr<OrthancApiClient> orthanc);
-    
-    void LoadSeries(const std::string& seriesId);
-
-    void LoadInstance(const std::string& instanceId);
-
-    void LoadFrame(const std::string& instanceId,
-                   unsigned int frame);
-
-    void SetImageQuality(SliceImageQuality quality)
-    {
-      quality_ = quality;
-    }
-
-    SliceImageQuality GetImageQuality() const
-    {
-      return quality_;
-    }
-
-    size_t GetSlicesCount() const
-    {
-      return loader_->GetSlicesCount();
-    }
-
-    const Slice& GetSlice(size_t slice) const 
-    {
-      return loader_->GetSlice(slice);
-    }
-
-    virtual bool GetExtent(std::vector<OrthancStone::Vector>& points,
-                           const OrthancStone::CoordinateSystem3D& viewportSlice);
-
-    virtual void ScheduleLayerCreation(const OrthancStone::CoordinateSystem3D& viewportSlice);
-
-protected:
-    void OnSliceGeometryReady(const OrthancSlicesLoader::SliceGeometryReadyMessage& message);
-    void OnSliceGeometryError(const OrthancSlicesLoader::SliceGeometryErrorMessage& message);
-    void OnSliceImageReady(const OrthancSlicesLoader::SliceImageReadyMessage& message);
-    void OnSliceImageError(const OrthancSlicesLoader::SliceImageErrorMessage& message);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Layers/DicomStructureSetSlicer.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,183 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "DicomStructureSetSlicer.h"
-
-#include "../../Toolbox/DicomStructureSet.h"
-
-namespace Deprecated
-{
-  class DicomStructureSetSlicer::Renderer : public ILayerRenderer
-  {
-  private:
-    class Structure
-    {
-    private:
-      bool         visible_;
-      uint8_t      red_;
-      uint8_t      green_;
-      uint8_t      blue_;
-      std::string  name_;
-
-#if USE_BOOST_UNION_FOR_POLYGONS == 1
-      std::vector< std::vector<OrthancStone::Point2D> > polygons_;
-#else
-      std::vector< std::pair<OrthancStone::Point2D, OrthancStone::Point2D> > segments_;
-#endif
-      
-    public:
-      Structure(OrthancStone::DicomStructureSet& structureSet,
-                const OrthancStone::CoordinateSystem3D& plane,
-                size_t index) :
-        name_(structureSet.GetStructureName(index))
-      {
-        structureSet.GetStructureColor(red_, green_, blue_, index);
-
-#if USE_BOOST_UNION_FOR_POLYGONS == 1
-        visible_ = structureSet.ProjectStructure(polygons_, index, plane);
-#else
-        visible_ = structureSet.ProjectStructure(segments_, index, plane);
-#endif
-      }
-
-      void Render(OrthancStone::CairoContext& context)
-      {
-        if (visible_)
-        {
-          cairo_t* cr = context.GetObject();
-        
-          context.SetSourceColor(red_, green_, blue_);
-
-#if USE_BOOST_UNION_FOR_POLYGONS == 1
-          for (size_t i = 0; i < polygons_.size(); i++)
-          {
-            cairo_move_to(cr, polygons_[i][0].x, polygons_[i][0].y);
-            for (size_t j = 0; j < polygons_[i].size(); j++)
-            {
-              cairo_line_to(cr, polygons_[i][j].x, polygons_[i][j].y);
-            }
-            cairo_line_to(cr, polygons_[i][0].x, polygons_[i][0].y);
-            cairo_stroke(cr);
-          }
-#else
-          for (size_t i = 0; i < segments_.size(); i++)
-          {
-            cairo_move_to(cr, segments_[i].first.x, segments_[i].first.y);
-            cairo_line_to(cr, segments_[i].second.x, segments_[i].second.y);
-            cairo_stroke(cr);
-          }
-#endif
-        }
-      }
-    };
-
-    typedef std::list<Structure*>  Structures;
-    
-    OrthancStone::CoordinateSystem3D  plane_;
-    Structures          structures_;
-    
-  public:
-    Renderer(OrthancStone::DicomStructureSet& structureSet,
-             const OrthancStone::CoordinateSystem3D& plane) :
-      plane_(plane)
-    {
-      for (size_t k = 0; k < structureSet.GetStructuresCount(); k++)
-      {
-        structures_.push_back(new Structure(structureSet, plane, k));
-      }
-    }
-
-    virtual ~Renderer()
-    {
-      for (Structures::iterator it = structures_.begin();
-           it != structures_.end(); ++it)
-      {
-        delete *it;
-      }
-    }
-
-    virtual bool RenderLayer(OrthancStone::CairoContext& context,
-                             const ViewportGeometry& view)
-    {
-      cairo_set_line_width(context.GetObject(), 2.0f / view.GetZoom());
-
-      for (Structures::const_iterator it = structures_.begin();
-           it != structures_.end(); ++it)
-      {
-        assert(*it != NULL);
-        (*it)->Render(context);
-      }
-
-      return true;
-    }
-
-    virtual const OrthancStone::CoordinateSystem3D& GetLayerPlane()
-    {
-      return plane_;
-    }
-
-    virtual void SetLayerStyle(const RenderStyle& style)
-    {
-    }
-    
-    virtual bool IsFullQuality()
-    {
-      return true;
-    }
-  };
-
-
-  class DicomStructureSetSlicer::RendererFactory : public LayerReadyMessage::IRendererFactory
-  {
-  private:
-    OrthancStone::DicomStructureSet&         structureSet_;
-    const OrthancStone::CoordinateSystem3D&  plane_;
-
-  public:
-    RendererFactory(OrthancStone::DicomStructureSet& structureSet,
-                    const OrthancStone::CoordinateSystem3D&  plane) :
-      structureSet_(structureSet),
-      plane_(plane)
-    {
-    }
-
-    virtual ILayerRenderer* CreateRenderer() const
-    {
-      return new Renderer(structureSet_, plane_);
-    }
-  };
-  
-
-  DicomStructureSetSlicer::DicomStructureSetSlicer(StructureSetLoader& loader) :
-    loader_(loader)
-  {
-    Register<StructureSetLoader::ContentChangedMessage>(loader_, &DicomStructureSetSlicer::OnStructureSetLoaded);
-  }
-
-
-  void DicomStructureSetSlicer::ScheduleLayerCreation(const OrthancStone::CoordinateSystem3D& viewportPlane)
-  {
-    if (loader_.HasStructureSet())
-    {
-      RendererFactory factory(loader_.GetStructureSet(), viewportPlane);
-      BroadcastMessage(IVolumeSlicer::LayerReadyMessage(*this, factory, viewportPlane));
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Layers/DicomStructureSetSlicer.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "IVolumeSlicer.h"
-#include "../Volumes/StructureSetLoader.h"
-
-namespace Deprecated
-{
-  class DicomStructureSetSlicer :
-    public IVolumeSlicer,
-    public OrthancStone::ObserverBase<DicomStructureSetSlicer>
-  {
-  private:
-    class Renderer;
-    class RendererFactory;
-
-    StructureSetLoader& loader_;
-
-    void OnStructureSetLoaded(const IVolumeLoader::ContentChangedMessage& message)
-    {
-      BroadcastMessage(IVolumeSlicer::ContentChangedMessage(*this));
-    }
-
-  public:
-    DicomStructureSetSlicer(StructureSetLoader& loader);
-
-    virtual bool GetExtent(std::vector<OrthancStone::Vector>& points,
-                           const OrthancStone::CoordinateSystem3D& viewportPlane)
-    {
-      return false;
-    }
-
-    virtual void ScheduleLayerCreation(const OrthancStone::CoordinateSystem3D& viewportPlane);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Layers/FrameRenderer.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "FrameRenderer.h"
-
-#include "GrayscaleFrameRenderer.h"
-#include "ColorFrameRenderer.h"
-
-#include <OrthancException.h>
-
-namespace Deprecated
-{
-  FrameRenderer::FrameRenderer(const OrthancStone::CoordinateSystem3D& framePlane,
-                               double pixelSpacingX,
-                               double pixelSpacingY,
-                               bool isFullQuality) :
-    framePlane_(framePlane),
-    pixelSpacingX_(pixelSpacingX),
-    pixelSpacingY_(pixelSpacingY),
-    isFullQuality_(isFullQuality)
-  {
-  }
-
-
-  bool FrameRenderer::RenderLayer(OrthancStone::CairoContext& context,
-                                  const ViewportGeometry& view)
-  {    
-    if (!style_.visible_)
-    {
-      return true;
-    }
-
-    if (display_.get() == NULL)
-    {
-      display_.reset(GenerateDisplay(style_));
-    }
-
-    assert(display_.get() != NULL);
-
-    cairo_t *cr = context.GetObject();
-
-    cairo_save(cr);
-
-    cairo_matrix_t transform;
-    cairo_matrix_init_identity(&transform);
-    cairo_matrix_scale(&transform, pixelSpacingX_, pixelSpacingY_);
-    cairo_matrix_translate(&transform, -0.5, -0.5);
-    cairo_transform(cr, &transform);
-
-    //cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
-    cairo_set_source_surface(cr, display_->GetObject(), 0, 0);
-
-    switch (style_.interpolation_)
-    {
-      case OrthancStone::ImageInterpolation_Nearest:
-        cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_NEAREST);
-        break;
-
-      case OrthancStone::ImageInterpolation_Bilinear:
-        cairo_pattern_set_filter(cairo_get_source(cr), CAIRO_FILTER_BILINEAR);
-        break;
-
-      default:
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    cairo_paint_with_alpha(cr, style_.alpha_);
-
-    if (style_.drawGrid_)
-    {
-      context.SetSourceColor(style_.drawColor_);
-      cairo_set_line_width(cr, 0.5 / view.GetZoom());
-
-      for (unsigned int x = 0; x <= display_->GetWidth(); x++)
-      {
-        cairo_move_to(cr, x, 0);
-        cairo_line_to(cr, x, display_->GetHeight());
-      }
-
-      for (unsigned int y = 0; y <= display_->GetHeight(); y++)
-      {
-        cairo_move_to(cr, 0, y);
-        cairo_line_to(cr, display_->GetWidth(), y);
-      }
-
-      cairo_stroke(cr);
-    }
-
-    cairo_restore(cr);
-
-    return true;
-  }
-
-
-  void FrameRenderer::SetLayerStyle(const RenderStyle& style)
-  {
-    style_ = style;
-    display_.reset(NULL);
-  }
-
-
-  ILayerRenderer* FrameRenderer::CreateRenderer(const Orthanc::ImageAccessor& frame,
-                                                const Deprecated::Slice& framePlane,
-                                                bool isFullQuality)
-  {
-    if (frame.GetFormat() == Orthanc::PixelFormat_RGB24)
-    {
-      return new ColorFrameRenderer(frame,
-                                    framePlane.GetGeometry(), 
-                                    framePlane.GetPixelSpacingX(),
-                                    framePlane.GetPixelSpacingY(), isFullQuality);
-    }
-    else
-    {
-      return new GrayscaleFrameRenderer(frame,
-                                        framePlane.GetConverter(),
-                                        framePlane.GetGeometry(), 
-                                        framePlane.GetPixelSpacingX(),
-                                        framePlane.GetPixelSpacingY(), isFullQuality);
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Layers/FrameRenderer.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "ILayerRenderer.h"
-
-#include "../Toolbox/Slice.h"
-
-namespace Deprecated
-{
-  class FrameRenderer : public ILayerRenderer
-  {
-  private:
-    OrthancStone::CoordinateSystem3D            framePlane_;
-    double                        pixelSpacingX_;
-    double                        pixelSpacingY_;
-    RenderStyle                   style_;
-    bool                          isFullQuality_;
-    std::unique_ptr<OrthancStone::CairoSurface>   display_;
-
-  protected:
-    virtual OrthancStone::CairoSurface* GenerateDisplay(const RenderStyle& style) = 0;
-
-  public:
-    FrameRenderer(const OrthancStone::CoordinateSystem3D& framePlane,
-                  double pixelSpacingX,
-                  double pixelSpacingY,
-                  bool isFullQuality);
-
-    virtual bool RenderLayer(OrthancStone::CairoContext& context,
-                             const ViewportGeometry& view);
-
-    virtual const OrthancStone::CoordinateSystem3D& GetLayerPlane()
-    {
-      return framePlane_;
-    }
-
-    virtual void SetLayerStyle(const RenderStyle& style);
-
-    virtual bool IsFullQuality() 
-    {
-      return isFullQuality_;
-    }
-
-    // TODO: Avoid cloning the "frame"
-    static ILayerRenderer* CreateRenderer(const Orthanc::ImageAccessor& frame,
-                                          const Deprecated::Slice& framePlane,
-                                          bool isFullQuality);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Layers/GrayscaleFrameRenderer.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,141 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "GrayscaleFrameRenderer.h"
-
-#include <Images/Image.h>
-#include <OrthancException.h>
-
-namespace Deprecated
-{
-  OrthancStone::CairoSurface* GrayscaleFrameRenderer::GenerateDisplay(const RenderStyle& style)
-  {
-    assert(frame_->GetFormat() == Orthanc::PixelFormat_Float32);
-
-    std::unique_ptr<OrthancStone::CairoSurface> result;
-
-    float windowCenter, windowWidth;
-    style.ComputeWindowing(windowCenter, windowWidth,
-                           defaultWindowCenter_, defaultWindowWidth_);
-
-    float x0 = windowCenter - windowWidth / 2.0f;
-    float x1 = windowCenter + windowWidth / 2.0f;
-
-    //LOG(INFO) << "Window: " << x0 << " => " << x1;
-
-    result.reset(new OrthancStone::CairoSurface(frame_->GetWidth(), frame_->GetHeight(), false /* no alpha */));
-
-    const uint8_t* lut = NULL;
-    if (style.applyLut_)
-    {
-      if (Orthanc::EmbeddedResources::GetFileResourceSize(style.lut_) != 3 * 256)
-      {
-        // Invalid colormap
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-      }
-
-      lut = reinterpret_cast<const uint8_t*>(Orthanc::EmbeddedResources::GetFileResourceBuffer(style.lut_));
-    }
-
-    Orthanc::ImageAccessor target;
-    result->GetWriteableAccessor(target);
-    
-    const unsigned int width = target.GetWidth();
-    const unsigned int height = target.GetHeight();
-    
-    for (unsigned int y = 0; y < height; y++)
-    {
-      const float* p = reinterpret_cast<const float*>(frame_->GetConstRow(y));
-      uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
-
-      for (unsigned int x = 0; x < width; x++, p++, q += 4)
-      {
-        uint8_t v = 0;
-        if (windowWidth >= 0.001f)  // Avoid division by zero
-        {
-          if (*p >= x1)
-          {
-            v = 255;
-          }
-          else if (*p <= x0)
-          {
-            v = 0;
-          }
-          else
-          {
-            // https://en.wikipedia.org/wiki/Linear_interpolation
-            v = static_cast<uint8_t>(255.0f * (*p - x0) / (x1 - x0));
-          }
-
-          if (style.reverse_ ^ (photometric_ == Orthanc::PhotometricInterpretation_Monochrome1))
-          {
-            v = 255 - v;
-          }
-        }
-
-        if (style.applyLut_)
-        {
-          assert(lut != NULL);
-          q[3] = 255;
-          q[2] = lut[3 * v];
-          q[1] = lut[3 * v + 1];
-          q[0] = lut[3 * v + 2];
-        }
-        else
-        {
-          q[3] = 255;
-          q[2] = v;
-          q[1] = v;
-          q[0] = v;
-        }
-      }
-    }
-
-    return result.release();
-  }
-
-
-  GrayscaleFrameRenderer::GrayscaleFrameRenderer(const Orthanc::ImageAccessor& frame,
-                                                 const Deprecated::DicomFrameConverter& converter,
-                                                 const OrthancStone::CoordinateSystem3D& framePlane,
-                                                 double pixelSpacingX,
-                                                 double pixelSpacingY,
-                                                 bool isFullQuality) :
-    FrameRenderer(framePlane, pixelSpacingX, pixelSpacingY, isFullQuality),
-    frame_(Orthanc::Image::Clone(frame)),
-    defaultWindowCenter_(static_cast<float>(converter.GetDefaultWindowCenter())),
-    defaultWindowWidth_(static_cast<float>(converter.GetDefaultWindowWidth())),
-    photometric_(converter.GetPhotometricInterpretation())
-  {
-    if (frame_.get() == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    converter.ConvertFrameInplace(frame_);
-    assert(frame_.get() != NULL);
-
-    if (frame_->GetFormat() != Orthanc::PixelFormat_Float32)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat);
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Layers/GrayscaleFrameRenderer.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "FrameRenderer.h"
-#include "../Toolbox/DicomFrameConverter.h"
-
-namespace Deprecated
-{
-  class GrayscaleFrameRenderer : public FrameRenderer
-  {
-  private:
-    std::unique_ptr<Orthanc::ImageAccessor>   frame_;  // In Float32
-    float                                   defaultWindowCenter_;
-    float                                   defaultWindowWidth_;
-    Orthanc::PhotometricInterpretation      photometric_;
-
-  protected:
-    virtual OrthancStone::CairoSurface* GenerateDisplay(const RenderStyle& style);
-
-  public:
-    GrayscaleFrameRenderer(const Orthanc::ImageAccessor& frame,
-                           const Deprecated::DicomFrameConverter& converter,
-                           const OrthancStone::CoordinateSystem3D& framePlane,
-                           double pixelSpacingX,
-                           double pixelSpacingY,
-                           bool isFullQuality);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Layers/ILayerRenderer.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Wrappers/CairoContext.h"
-#include "../../Toolbox/CoordinateSystem3D.h"
-#include "../Toolbox/ViewportGeometry.h"
-#include "RenderStyle.h"
-
-namespace Deprecated
-{
-  class ILayerRenderer : public boost::noncopyable
-  {
-  public:
-    virtual ~ILayerRenderer()
-    {
-    }
-    
-    virtual bool RenderLayer(OrthancStone::CairoContext& context,
-                             const ViewportGeometry& view) = 0;
-
-    virtual void SetLayerStyle(const RenderStyle& style) = 0;
-
-    virtual const OrthancStone::CoordinateSystem3D& GetLayerPlane() = 0;
-    
-    virtual bool IsFullQuality() = 0;
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Layers/IVolumeSlicer.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "ILayerRenderer.h"
-#include "../Toolbox/Slice.h"
-#include "../../Messages/IObservable.h"
-#include "../../Messages/IMessage.h"
-#include "Images/Image.h"
-#include <boost/shared_ptr.hpp>
-
-namespace Deprecated
-{
-  class IVolumeSlicer : public OrthancStone::IObservable
-  {
-  public:
-    ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, GeometryReadyMessage, IVolumeSlicer);
-    ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, GeometryErrorMessage, IVolumeSlicer);
-    ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, ContentChangedMessage, IVolumeSlicer);
-
-    class SliceContentChangedMessage : public OrthancStone::OriginMessage<IVolumeSlicer>
-    {
-      ORTHANC_STONE_MESSAGE(__FILE__, __LINE__);
-      
-    private:
-      const Deprecated::Slice& slice_;
-
-    public:
-      SliceContentChangedMessage(IVolumeSlicer& origin,
-                                 const Deprecated::Slice& slice) :
-        OriginMessage(origin),
-        slice_(slice)
-      {
-      }
-
-      const Deprecated::Slice& GetSlice() const
-      {
-        return slice_;
-      }
-    };
-    
-
-    class LayerReadyMessage : public OrthancStone::OriginMessage<IVolumeSlicer>
-    {
-      ORTHANC_STONE_MESSAGE(__FILE__, __LINE__);
-      
-    public:
-      class IRendererFactory : public boost::noncopyable
-      {
-      public:
-        virtual ~IRendererFactory()
-        {
-        }
-
-        virtual ILayerRenderer* CreateRenderer() const = 0;
-      };
-    
-    private:
-      const IRendererFactory&    factory_;
-      const OrthancStone::CoordinateSystem3D&  slice_;
-
-    public:
-      LayerReadyMessage(IVolumeSlicer& origin,
-                        const IRendererFactory& rendererFactory,
-                        const OrthancStone::CoordinateSystem3D& slice) :
-        OriginMessage(origin),
-        factory_(rendererFactory),
-        slice_(slice)
-      {
-      }
-
-      ILayerRenderer* CreateRenderer() const
-      {
-        return factory_.CreateRenderer();
-      }
-
-      const OrthancStone::CoordinateSystem3D& GetSlice() const
-      {
-        return slice_;
-      }
-    };
-
-
-    class LayerErrorMessage : public OrthancStone::OriginMessage<IVolumeSlicer>
-    {
-      ORTHANC_STONE_MESSAGE(__FILE__, __LINE__);
-      
-    private:
-      const OrthancStone::CoordinateSystem3D&  slice_;
-
-    public:
-      LayerErrorMessage(IVolumeSlicer& origin,
-                        const OrthancStone::CoordinateSystem3D& slice) :
-        OriginMessage(origin),
-        slice_(slice)
-      {
-      }
-
-      const OrthancStone::CoordinateSystem3D& GetSlice() const
-      {
-        return slice_;
-      }
-    };
-
-
-    virtual ~IVolumeSlicer()
-    {
-    }
-
-    virtual bool GetExtent(std::vector<OrthancStone::Vector>& points,
-                           const OrthancStone::CoordinateSystem3D& viewportSlice) = 0;
-
-    virtual void ScheduleLayerCreation(const OrthancStone::CoordinateSystem3D& viewportSlice) = 0;
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Layers/LineLayerRenderer.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "LineLayerRenderer.h"
-
-namespace Deprecated
-{
-  LineLayerRenderer::LineLayerRenderer(double x1,
-                                       double y1,
-                                       double x2,
-                                       double y2,
-                                       const OrthancStone::CoordinateSystem3D& plane) : 
-    x1_(x1),
-    y1_(y1),
-    x2_(x2),
-    y2_(y2),
-    plane_(plane)
-  {
-    RenderStyle style;
-    SetLayerStyle(style);
-  }
-
-
-  bool LineLayerRenderer::RenderLayer(OrthancStone::CairoContext& context,
-                                      const ViewportGeometry& view)
-  {
-    if (visible_)
-    {
-      context.SetSourceColor(color_);
-
-      cairo_t *cr = context.GetObject();
-      cairo_set_line_width(cr, 1.0 / view.GetZoom());
-      cairo_move_to(cr, x1_, y1_);
-      cairo_line_to(cr, x2_, y2_);
-      cairo_stroke(cr);
-    }
-
-    return true;
-  }
-
-
-  void LineLayerRenderer::SetLayerStyle(const RenderStyle& style)
-  {
-    visible_ = style.visible_;
-    color_[0] = style.drawColor_[0];
-    color_[1] = style.drawColor_[1];
-    color_[2] = style.drawColor_[2];
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Layers/LineLayerRenderer.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "ILayerRenderer.h"
-
-namespace Deprecated
-{
-  class LineLayerRenderer : public ILayerRenderer
-  {
-  private:
-    double              x1_;
-    double              y1_;
-    double              x2_;
-    double              y2_;
-    OrthancStone::CoordinateSystem3D  plane_;
-    bool                visible_;
-    uint8_t             color_[3];
-
-  public:
-    LineLayerRenderer(double x1,
-                      double y1,
-                      double x2,
-                      double y2,
-                      const OrthancStone::CoordinateSystem3D& plane);
-
-    virtual bool RenderLayer(OrthancStone::CairoContext& context,
-                             const ViewportGeometry& view);
-
-    virtual void SetLayerStyle(const RenderStyle& style);
-
-    virtual const OrthancStone::CoordinateSystem3D& GetLayerPlane()
-    {
-      return plane_;
-    }
-    
-    virtual bool IsFullQuality()
-    {
-      return true;
-    }
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Layers/LineMeasureTracker.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "LineMeasureTracker.h"
-
-#include <stdio.h>
-
-namespace Deprecated
-{
-  LineMeasureTracker::LineMeasureTracker(IStatusBar* statusBar,
-                                         const OrthancStone::CoordinateSystem3D& slice,
-                                         double x, 
-                                         double y,
-                                         uint8_t red,
-                                         uint8_t green,
-                                         uint8_t blue,
-                                         const Orthanc::Font& font) :
-    statusBar_(statusBar),
-    slice_(slice),
-    x1_(x),
-    y1_(y),
-    x2_(x),
-    y2_(y),
-    font_(font)
-  {
-    color_[0] = red;
-    color_[1] = green;
-    color_[2] = blue;
-  }
-    
-
-  void LineMeasureTracker::Render(OrthancStone::CairoContext& context,
-                                  double zoom)
-  {
-    context.SetSourceColor(color_[0], color_[1], color_[2]);
-
-    cairo_t* cr = context.GetObject();
-    cairo_set_line_width(cr, 2.0 / zoom);
-    cairo_move_to(cr, x1_, y1_);
-    cairo_line_to(cr, x2_, y2_);
-    cairo_stroke(cr);
-
-    if (y2_ - y1_ < 0)
-    {
-      context.DrawText(font_, FormatLength(), x2_, y2_ - 5, OrthancStone::BitmapAnchor_BottomCenter);
-    }
-    else
-    {
-      context.DrawText(font_, FormatLength(), x2_, y2_ + 5, OrthancStone::BitmapAnchor_TopCenter);
-    }
-  }
-    
-
-  double LineMeasureTracker::GetLength() const  // In millimeters
-  {
-    OrthancStone::Vector a = slice_.MapSliceToWorldCoordinates(x1_, y1_);
-    OrthancStone::Vector b = slice_.MapSliceToWorldCoordinates(x2_, y2_);
-    return boost::numeric::ublas::norm_2(b - a);
-  }
-
-
-  std::string LineMeasureTracker::FormatLength() const
-  {
-    char buf[64];
-    sprintf(buf, "%0.01f cm", GetLength() / 10.0);
-    return buf;
-  }
-
-  void LineMeasureTracker::MouseMove(int displayX,
-                                     int displayY,
-                                     double x,
-                                     double y,
-                                     const std::vector<Touch>& displayTouches,
-                                     const std::vector<Touch>& sceneTouches)
-  {
-    x2_ = x;
-    y2_ = y;
-
-    if (statusBar_ != NULL)
-    {
-      statusBar_->SetMessage("Line length: " + FormatLength());
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Layers/LineMeasureTracker.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../Widgets/IWorldSceneMouseTracker.h"
-
-#include "../Viewport/IStatusBar.h"
-#include "../../Toolbox/CoordinateSystem3D.h"
-
-namespace Deprecated
-{
-  class LineMeasureTracker : public IWorldSceneMouseTracker
-  {
-  private:
-    IStatusBar*           statusBar_;
-    OrthancStone::CoordinateSystem3D    slice_;
-    double                x1_;
-    double                y1_;
-    double                x2_;
-    double                y2_;
-    uint8_t               color_[3];
-    unsigned int          fontSize_;
-    const Orthanc::Font&  font_;
-
-  public:
-    LineMeasureTracker(IStatusBar* statusBar,
-                       const OrthancStone::CoordinateSystem3D& slice,
-                       double x, 
-                       double y,
-                       uint8_t red,
-                       uint8_t green,
-                       uint8_t blue,
-                       const Orthanc::Font& font);
-
-    virtual bool HasRender() const
-    {
-      return true;
-    }
-
-    virtual void Render(OrthancStone::CairoContext& context,
-                        double zoom);
-    
-    double GetLength() const;  // In millimeters
-
-    std::string FormatLength() const;
-
-    virtual void MouseUp()
-    {
-      // Possibly create a new landmark "volume" with the line in subclasses
-    }
-
-    virtual void MouseMove(int displayX,
-                           int displayY,
-                           double x,
-                           double y,
-                           const std::vector<Touch>& displayTouches,
-                           const std::vector<Touch>& sceneTouches);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Layers/RenderStyle.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "RenderStyle.h"
-
-#include "../../Volumes/ImageBuffer3D.h"
-#include "../Toolbox/DicomFrameConverter.h"
-
-#include <OrthancException.h>
-
-namespace Deprecated
-{
-  RenderStyle::RenderStyle()
-  {
-    visible_ = true;
-    reverse_ = false;
-    windowing_ = OrthancStone::ImageWindowing_Custom;
-    alpha_ = 1;
-    applyLut_ = false;
-    lut_ = Orthanc::EmbeddedResources::COLORMAP_HOT;
-    drawGrid_ = false;
-    drawColor_[0] = 255;
-    drawColor_[1] = 255;
-    drawColor_[2] = 255;
-    customWindowCenter_ = 128;
-    customWindowWidth_ = 256;
-    interpolation_ = OrthancStone::ImageInterpolation_Nearest;
-    fontSize_ = 14;
-  }
-
-
-  void RenderStyle::ComputeWindowing(float& targetCenter,
-                                     float& targetWidth,
-                                     float defaultCenter,
-                                     float defaultWidth) const
-  {
-    if (windowing_ == OrthancStone::ImageWindowing_Custom)
-    {
-      targetCenter = customWindowCenter_;
-      targetWidth = customWindowWidth_;
-    }
-    else
-    {
-      return ::OrthancStone::ComputeWindowing
-        (targetCenter, targetWidth, windowing_, defaultCenter, defaultWidth);
-    }
-  }
-
-  
-  void RenderStyle::SetColor(uint8_t red,
-                             uint8_t green,
-                             uint8_t blue)
-  {
-    drawColor_[0] = red;
-    drawColor_[1] = green;
-    drawColor_[2] = blue;
-  }
-
-
-  bool RenderStyle::FitRange(const OrthancStone::ImageBuffer3D& image,
-                             const DicomFrameConverter& converter)
-  {
-    float minValue, maxValue;
-
-    windowing_ = OrthancStone::ImageWindowing_Custom;
-
-    if (image.GetRange(minValue, maxValue))
-    {  
-      // casting the narrower type to wider before calling the + operator
-      // will prevent overflowing (this is why the cast to double is only 
-      // done on the first operand)
-      customWindowCenter_ = static_cast<float>(
-        converter.Apply((static_cast<double>(minValue) + maxValue) / 2.0));
-      
-      customWindowWidth_ = static_cast<float>(
-        converter.Apply(static_cast<double>(maxValue) - minValue));
-      
-      if (customWindowWidth_ > 1)
-      {
-        return true;
-      }
-    }
-
-    customWindowCenter_ = 128.0;
-    customWindowWidth_ = 256.0;
-    return false;
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Layers/RenderStyle.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../StoneEnumerations.h"
-#include "../../Volumes/ImageBuffer3D.h"
-#include "../Toolbox/DicomFrameConverter.h"
-
-#include <EmbeddedResources.h>
-
-#include <stdint.h>
-
-namespace Deprecated
-{
-  struct RenderStyle
-  {
-    bool visible_;
-    bool reverse_;
-    OrthancStone::ImageWindowing windowing_;
-    float alpha_;   // In [0,1]
-    bool applyLut_;
-    Orthanc::EmbeddedResources::FileResourceId  lut_;
-    bool drawGrid_;
-    uint8_t drawColor_[3];
-    float customWindowCenter_;
-    float customWindowWidth_;
-    OrthancStone::ImageInterpolation interpolation_;
-    unsigned int fontSize_;
-    
-    RenderStyle();
-
-    void ComputeWindowing(float& targetCenter,
-                          float& targetWidth,
-                          float defaultCenter,
-                          float defaultWidth) const;
-
-    void SetColor(uint8_t red,
-                  uint8_t green,
-                  uint8_t blue);
-
-    bool FitRange(const OrthancStone::ImageBuffer3D& image,
-                  const DicomFrameConverter& converter);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Layers/SeriesFrameRendererFactory.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,177 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "SeriesFrameRendererFactory.h"
-
-#include "FrameRenderer.h"
-
-#include <OrthancException.h>
-#include <Logging.h>
-#include <Toolbox.h>
-#include <OrthancPluginException.h>
-#include <DicomDatasetReader.h>
-
-
-namespace Deprecated
-{
-  void SeriesFrameRendererFactory::ReadCurrentFrameDataset(size_t frame)
-  {
-    if (currentDataset_.get() != NULL &&
-        (fast_ || currentFrame_ == frame))
-    {
-      // The frame has not changed since the previous call, no need to
-      // update the DICOM dataset
-      return; 
-    }
-      
-    currentDataset_.reset(loader_->DownloadDicom(frame));
-    currentFrame_ = frame;
-
-    if (currentDataset_.get() == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-    }
-  }
-
-
-  void SeriesFrameRendererFactory::GetCurrentPixelSpacing(double& spacingX,
-                                                          double& spacingY) const
-  {
-    if (currentDataset_.get() == NULL)
-    {
-      // There was no previous call "ReadCurrentFrameDataset()"
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-    }
-    
-    GeometryToolbox::GetPixelSpacing(spacingX, spacingY, *currentDataset_);
-  }
-
-
-  double SeriesFrameRendererFactory::GetCurrentSliceThickness() const
-  {
-    if (currentDataset_.get() == NULL)
-    {
-      // There was no previous call "ReadCurrentFrameDataset()"
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-    }
-    
-    try
-    {
-      OrthancPlugins::DicomDatasetReader reader(*currentDataset_);
-
-      double thickness;
-      if (reader.GetDoubleValue(thickness, OrthancPlugins::DICOM_TAG_SLICE_THICKNESS))
-      {
-        return thickness;
-      }
-    }
-    catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e)
-    {
-    }
-
-    // Some arbitrary large slice thickness
-    return std::numeric_limits<double>::infinity();
-  }
-
-
-  SeriesFrameRendererFactory::SeriesFrameRendererFactory(ISeriesLoader* loader,   // Takes ownership
-                                                         bool fast) :
-    loader_(loader),
-    currentFrame_(0),
-    fast_(fast)
-  {
-    if (loader == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-    }
-  }
-
-
-  bool SeriesFrameRendererFactory::GetExtent(double& x1,
-                                             double& y1,
-                                             double& x2,
-                                             double& y2,
-                                             const SliceGeometry& viewportSlice)
-  {
-    if (currentDataset_.get() == NULL)
-    {
-      // There has been no previous call to
-      // "CreateLayerRenderer". Read some arbitrary DICOM frame, the
-      // one at the middle of the series.
-      unsigned int depth = loader_->GetGeometry().GetSliceCount();
-      ReadCurrentFrameDataset(depth / 2);
-    }
-
-    double spacingX, spacingY;
-    GetCurrentPixelSpacing(spacingX, spacingY);
-
-    return FrameRenderer::ComputeFrameExtent(x1, y1, x2, y2, 
-                                             viewportSlice, 
-                                             loader_->GetGeometry().GetSlice(0), 
-                                             loader_->GetWidth(), 
-                                             loader_->GetHeight(),
-                                             spacingX, spacingY);
-  }
-
-
-  ILayerRenderer* SeriesFrameRendererFactory::CreateLayerRenderer(const SliceGeometry& viewportSlice)
-  {
-    size_t closest;
-    double distance;
-
-    bool isOpposite;
-    if (!GeometryToolbox::IsParallelOrOpposite(isOpposite, loader_->GetGeometry().GetNormal(), viewportSlice.GetNormal()) ||
-        !loader_->GetGeometry().ComputeClosestSlice(closest, distance, viewportSlice.GetOrigin()))
-    {
-      // Unable to compute the slice in the series that is the
-      // closest to the slice displayed by the viewport
-      return NULL;
-    }
-
-    ReadCurrentFrameDataset(closest);
-    assert(currentDataset_.get() != NULL);
-        
-    double spacingX, spacingY;
-    GetCurrentPixelSpacing(spacingX, spacingY);
-
-    if (distance <= GetCurrentSliceThickness() / 2.0)
-    {
-      SliceGeometry frameSlice(*currentDataset_);
-      return FrameRenderer::CreateRenderer(loader_->DownloadFrame(closest), 
-                                           frameSlice,
-                                           *currentDataset_, 
-                                           spacingX, spacingY,
-                                           true);
-    }
-    else
-    {
-      // The closest slice of the series is too far away from the
-      // slice displayed by the viewport
-      return NULL;
-    }
-  }
-
-
-  ISliceableVolume& SeriesFrameRendererFactory::GetSourceVolume() const
-  {
-    throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Layers/SeriesFrameRendererFactory.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "ILayerRendererFactory.h"
-
-#include "../Toolbox/ISeriesLoader.h"
-
-namespace Deprecated
-{
-  class SeriesFrameRendererFactory : public ILayerRendererFactory
-  {
-  private:
-    std::unique_ptr<ISeriesLoader>  loader_;
-    size_t                        currentFrame_;
-    bool                          fast_;
-
-    std::unique_ptr<OrthancPlugins::IDicomDataset>  currentDataset_;
-
-    void ReadCurrentFrameDataset(size_t frame);
-
-    void GetCurrentPixelSpacing(double& spacingX,
-                                double& spacingY) const;
-
-    double GetCurrentSliceThickness() const;
-
-  public:
-    SeriesFrameRendererFactory(ISeriesLoader* loader,   // Takes ownership
-                               bool fast);
-
-    virtual bool GetExtent(double& x1,
-                           double& y1,
-                           double& x2,
-                           double& y2,
-                           const SliceGeometry& viewportSlice);
-
-    virtual ILayerRenderer* CreateLayerRenderer(const SliceGeometry& viewportSlice);
-
-    virtual bool HasSourceVolume() const
-    {
-      return false;
-    }
-
-    virtual ISliceableVolume& GetSourceVolume() const;
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Layers/SingleFrameRendererFactory.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "SingleFrameRendererFactory.h"
-
-#include "FrameRenderer.h"
-#include "../Toolbox/MessagingToolbox.h"
-#include "../Toolbox/DicomFrameConverter.h"
-
-#include <OrthancException.h>
-#include <FullOrthancDataset.h>
-#include <DicomDatasetReader.h>
-
-namespace Deprecated
-{
-  SingleFrameRendererFactory::SingleFrameRendererFactory(OrthancPlugins::IOrthancConnection& orthanc,
-                                                         const std::string& instanceId,
-                                                         unsigned int frame) :
-    orthanc_(orthanc),
-    instance_(instanceId),
-    frame_(frame)
-  {
-    dicom_.reset(new OrthancPlugins::FullOrthancDataset(orthanc, "/instances/" + instanceId + "/tags"));
-
-    DicomFrameConverter converter;
-    converter.ReadParameters(*dicom_);
-    format_ = converter.GetExpectedPixelFormat();
-  }
-
-
-  bool SingleFrameRendererFactory::GetExtent(double& x1,
-                                             double& y1,
-                                             double& x2,
-                                             double& y2,
-                                             const SliceGeometry& viewportSlice)
-  {
-    // Assume that PixelSpacingX == PixelSpacingY == 1
-
-    OrthancPlugins::DicomDatasetReader reader(*dicom_);
-
-    unsigned int width, height;
-
-    if (!reader.GetUnsignedIntegerValue(width, OrthancPlugins::DICOM_TAG_COLUMNS) ||
-        !reader.GetUnsignedIntegerValue(height, OrthancPlugins::DICOM_TAG_ROWS))
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
-    }
-
-    x1 = 0;
-    y1 = 0;
-    x2 = static_cast<double>(width);
-    y2 = static_cast<double>(height);
-
-    return true;
-  }
-
-
-  ILayerRenderer* SingleFrameRendererFactory::CreateLayerRenderer(const SliceGeometry& viewportSlice)
-  {
-    SliceGeometry frameSlice(*dicom_);
-    return FrameRenderer::CreateRenderer(MessagingToolbox::DecodeFrame(orthanc_, instance_, frame_, format_), 
-                                         frameSlice, *dicom_, 1, 1, true);
-  }
-
-
-  ISliceableVolume& SingleFrameRendererFactory::GetSourceVolume() const
-  {
-    throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Layers/SingleFrameRendererFactory.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "ILayerRendererFactory.h"
-#include <IOrthancConnection.h>
-
-namespace Deprecated
-{
-  class SingleFrameRendererFactory : public ILayerRendererFactory
-  {
-  private:
-    OrthancPlugins::IOrthancConnection&           orthanc_;
-    std::unique_ptr<OrthancPlugins::IDicomDataset>  dicom_;
-
-    std::string           instance_;
-    unsigned int          frame_;
-    Orthanc::PixelFormat  format_;
-
-  public:
-    SingleFrameRendererFactory(OrthancPlugins::IOrthancConnection& orthanc,
-                               const std::string& instanceId,
-                               unsigned int frame);
-
-    const OrthancPlugins::IDicomDataset& GetDataset() const
-    {
-      return *dicom_;
-    }
-
-    SliceGeometry GetSliceGeometry()
-    {
-      return SliceGeometry(*dicom_);
-    }
-
-    virtual bool GetExtent(double& x1,
-                           double& y1,
-                           double& x2,
-                           double& y2,
-                           const SliceGeometry& viewportSlice);
-
-    virtual ILayerRenderer* CreateLayerRenderer(const SliceGeometry& viewportSlice);
-
-    virtual bool HasSourceVolume() const
-    {
-      return false;
-    }
-
-    virtual ISliceableVolume& GetSourceVolume() const;
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Layers/SliceOutlineRenderer.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "SliceOutlineRenderer.h"
-
-namespace Deprecated
-{
-  bool SliceOutlineRenderer::RenderLayer(OrthancStone::CairoContext& context,
-                                         const ViewportGeometry& view)
-  {
-    if (style_.visible_)
-    {
-      cairo_t *cr = context.GetObject();
-      cairo_save(cr);
-
-      context.SetSourceColor(style_.drawColor_);
-
-      double x1 = -0.5 * pixelSpacingX_;
-      double y1 = -0.5 * pixelSpacingY_;
-        
-      cairo_set_line_width(cr, 1.0 / view.GetZoom());
-      cairo_rectangle(cr, x1, y1,
-                      static_cast<double>(width_) * pixelSpacingX_,
-                      static_cast<double>(height_) * pixelSpacingY_);
-
-      double handleSize = 10.0f / view.GetZoom();
-      cairo_move_to(cr, x1 + handleSize, y1);
-      cairo_line_to(cr, x1, y1 + handleSize);
-
-      cairo_stroke(cr);
-      cairo_restore(cr);
-    }
-
-    return true;
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Layers/SliceOutlineRenderer.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "ILayerRenderer.h"
-#include "../Toolbox/Slice.h"
-
-namespace Deprecated
-{
-  class SliceOutlineRenderer : public ILayerRenderer
-  {
-  private:
-    OrthancStone::CoordinateSystem3D  geometry_;
-    double              pixelSpacingX_;
-    double              pixelSpacingY_;
-    unsigned int        width_;
-    unsigned int        height_;
-    RenderStyle         style_;
-
-  public:
-    SliceOutlineRenderer(const Slice& slice) :
-      geometry_(slice.GetGeometry()),
-      pixelSpacingX_(slice.GetPixelSpacingX()),
-      pixelSpacingY_(slice.GetPixelSpacingY()),
-      width_(slice.GetWidth()),
-      height_(slice.GetHeight())
-    {
-    }
-
-    virtual bool RenderLayer(OrthancStone::CairoContext& context,
-                             const ViewportGeometry& view);
-
-    virtual void SetLayerStyle(const RenderStyle& style)
-    {
-      style_ = style;
-    }
-
-    virtual const OrthancStone::CoordinateSystem3D& GetLayerSlice()
-    {
-      return geometry_;
-    }
-
-    virtual bool IsFullQuality()
-    {
-      return true;
-    }
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Loaders/DicomStructureSetLoader2.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#ifdef BGO_ENABLE_DICOMSTRUCTURESETLOADER2
-
-#include "DicomStructureSetLoader2.h"
-
-#include "../Messages/IObservable.h"
-#include "../Oracle/IOracle.h"
-#include "../Oracle/OracleCommandExceptionMessage.h"
-
-namespace Deprecated
-{
-
-  DicomStructureSetLoader2::DicomStructureSetLoader2(
-    DicomStructureSet2& structureSet
-    , IOracle& oracle
-    , IObservable& oracleObservable)
-    : IObserver(oracleObservable.GetBroker())
-    , IObservable(oracleObservable.GetBroker())
-    , structureSet_(structureSet)
-    , oracle_(oracle)
-    , oracleObservable_(oracleObservable)
-    , structuresReady_(false)
-  {
-    LOG(TRACE) << "DicomStructureSetLoader2(" << std::hex << this << std::dec << ")::DicomStructureSetLoader2()";
-
-    oracleObservable.RegisterObserverCallback(
-      new Callable<DicomStructureSetLoader2, OrthancRestApiCommand::SuccessMessage>
-      (*this, &DicomStructureSetLoader2::HandleSuccessMessage));
-
-    oracleObservable.RegisterObserverCallback(
-      new Callable<DicomStructureSetLoader2, OracleCommandExceptionMessage>
-      (*this, &DicomStructureSetLoader2::HandleExceptionMessage));
-  }
-
-  DicomStructureSetLoader2::~DicomStructureSetLoader2()
-  {
-    LOG(TRACE) << "DicomStructureSetLoader2(" << std::hex << this << std::dec << ")::~DicomStructureSetLoader2()";
-    oracleObservable_.Unregister(this);
-  }
-
-  void DicomStructureSetLoader2::LoadInstanceFromString(const std::string& body)
-  {
-    OrthancPlugins::FullOrthancDataset dicom(body);
-    //loader.content_.reset(new DicomStructureSet(dicom));
-    structureSet_.Clear();
-    structureSet_.SetContents(dicom);
-    SetStructuresReady();
-  }
-
-  void DicomStructureSetLoader2::HandleSuccessMessage(const OrthancRestApiCommand::SuccessMessage& message)
-  {
-    const std::string& body = message.GetAnswer();
-    LoadInstanceFromString(body);
-  }
-
-  void DicomStructureSetLoader2::HandleExceptionMessage(const OracleCommandExceptionMessage& message)
-  {
-    LOG(ERROR) << "DicomStructureSetLoader2::HandleExceptionMessage: error when trying to load data. "
-      << "Error: " << message.GetException().What() << " Details: "
-      << message.GetException().GetDetails();
-  }
-
-  void DicomStructureSetLoader2::LoadInstance(const std::string& instanceId)
-  {
-    std::unique_ptr<OrthancRestApiCommand> command(new OrthancRestApiCommand);
-    command->SetHttpHeader("Accept-Encoding", "gzip");
-
-    std::string uri = "/instances/" + instanceId + "/tags?ignore-length=3006-0050";
-
-    command->SetUri(uri);
-    oracle_.Schedule(*this, command.release());
-  }
-
-  void DicomStructureSetLoader2::SetStructuresReady()
-  {
-    structuresReady_ = true;
-  }
-
-  bool DicomStructureSetLoader2::AreStructuresReady() const
-  {
-    return structuresReady_;
-  }
-
-  /*
-
-    void LoaderStateMachine::HandleExceptionMessage(const OracleCommandExceptionMessage& message)
-    {
-      LOG(ERROR) << "LoaderStateMachine::HandleExceptionMessage: error in the state machine, stopping all processing";
-      LOG(ERROR) << "Error: " << message.GetException().What() << " Details: " <<
-        message.GetException().GetDetails();
-        Clear();
-    }
-
-    LoaderStateMachine::~LoaderStateMachine()
-    {
-      Clear();
-    }
-
-
-  */
-
-}
-
-#endif 
-// BGO_ENABLE_DICOMSTRUCTURESETLOADER2
-
--- a/OrthancStone/Sources/Deprecated/Loaders/DicomStructureSetLoader2.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#pragma once
-
-#ifdef BGO_ENABLE_DICOMSTRUCTURESETLOADER2
-
-#include "../Toolbox/DicomStructureSet2.h"
-#include "../Messages/IMessage.h"
-#include "../Messages/IObserver.h"
-#include "../Messages/IObservable.h"
-#include "../Oracle/OrthancRestApiCommand.h"
-
-#include <boost/noncopyable.hpp>
-
-namespace Deprecated
-{
-  class IOracle;
-  class IObservable;
-  class OrthancRestApiCommand;
-  class OracleCommandExceptionMessage;
-
-  class DicomStructureSetLoader2 : public IObserver, public IObservable
-  {
-  public:
-    ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, StructuresReady, DicomStructureSetLoader2);
-
-    /**
-    Warning: the structureSet, oracle and oracleObservable objects must live
-    at least as long as this object (TODO: shared_ptr?)
-    */
-    DicomStructureSetLoader2(DicomStructureSet2& structureSet, IOracle& oracle, IObservable& oracleObservable);
-
-    ~DicomStructureSetLoader2();
-
-    void LoadInstance(const std::string& instanceId);
-
-    /** Internal use */
-    void LoadInstanceFromString(const std::string& body);
-
-    void SetStructuresReady();
-    bool AreStructuresReady() const;
-  
-  private:
-    /**
-    Called back by the oracle when data is ready!
-    */
-    void HandleSuccessMessage(const OrthancRestApiCommand::SuccessMessage& message);
-
-    /**
-    Called back by the oracle when shit hits the fan
-    */
-    void HandleExceptionMessage(const OracleCommandExceptionMessage& message);
-
-    /**
-    The structure set that will be (cleared and) filled with data from the 
-    loader
-    */
-    DicomStructureSet2& structureSet_;
-
-    IOracle&            oracle_;
-    IObservable&        oracleObservable_;
-    bool                structuresReady_;
-  };
-}
-
-#endif 
-// BGO_ENABLE_DICOMSTRUCTURESETLOADER2
-
-
--- a/OrthancStone/Sources/Deprecated/Messages/LockingEmitter.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "LockingEmitter.h"
-
-#include <OrthancException.h>
-
-namespace Deprecated
-{
-  void LockingEmitter::EmitMessage(boost::weak_ptr<OrthancStone::IObserver> observer,
-                                   const OrthancStone::IMessage& message)
-  {
-    try
-    {
-      boost::unique_lock<boost::shared_mutex>  lock(mutex_);
-      oracleObservable_.EmitMessage(observer, message);
-    }
-    catch (Orthanc::OrthancException& e)
-    {
-      LOG(ERROR) << "Exception while emitting a message: " << e.What();
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Messages/LockingEmitter.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#pragma once
-
-#include <Enumerations.h>
-#include <OrthancException.h>
-
-#include "../../Messages/IMessageEmitter.h"
-#include "../../Messages/IObservable.h"
-
-#include <boost/thread/shared_mutex.hpp>
-
-namespace Deprecated
-{
-  /**
-   * This class is used when using the ThreadedOracle : since messages
-   * can be sent from multiple Oracle threads, this IMessageEmitter
-   * implementation serializes the callbacks.
-   * 
-   * The internal mutex used in Oracle messaging can also be used to 
-   * protect the application data. Thus, this class can be used as a single
-   * application-wide mutex.
-   */
-  class LockingEmitter : public OrthancStone::IMessageEmitter
-  {
-  private:
-    boost::shared_mutex        mutex_;
-    OrthancStone::IObservable  oracleObservable_;
-
-  public:
-    virtual void EmitMessage(boost::weak_ptr<OrthancStone::IObserver> observer,
-                             const OrthancStone::IMessage& message) ORTHANC_OVERRIDE;
-
-
-    class ReaderLock : public boost::noncopyable
-    {
-    private:
-      LockingEmitter& that_;
-      boost::shared_lock<boost::shared_mutex>  lock_;
-
-    public:
-      ReaderLock(LockingEmitter& that) :
-        that_(that),
-        lock_(that.mutex_)
-      {
-      }
-    };
-
-
-    class WriterLock : public boost::noncopyable
-    {
-    private:
-      LockingEmitter& that_;
-      boost::unique_lock<boost::shared_mutex>  lock_;
-
-    public:
-      WriterLock(LockingEmitter& that) :
-        that_(that),
-        lock_(that.mutex_)
-      {
-      }
-
-      OrthancStone::IObservable& GetOracleObservable()
-      {
-        return that_.oracleObservable_;
-      }
-    };
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyAlphaLayer.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,152 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "RadiographyAlphaLayer.h"
-
-#include "RadiographyScene.h"
-#include "../Toolbox/ImageGeometry.h"
-
-#include <Compatibility.h>
-#include <Images/Image.h>
-#include <OrthancException.h>
-
-
-namespace OrthancStone
-{
-
-  void RadiographyAlphaLayer::SetAlpha(Orthanc::ImageAccessor* image)
-  {
-    std::unique_ptr<Orthanc::ImageAccessor> raii(image);
-
-    if (image == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
-    }
-
-    if (image->GetFormat() != Orthanc::PixelFormat_Grayscale8)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat);
-    }
-
-    SetSize(image->GetWidth(), image->GetHeight());
-
-#if __cplusplus < 201103L
-    alpha_.reset(raii.release());
-#else
-    alpha_ = std::move(raii);
-#endif
-
-    BroadcastMessage(RadiographyLayer::LayerEditedMessage(*this));
-  }
-
-  void RadiographyAlphaLayer::Render(Orthanc::ImageAccessor& buffer,
-                                     const AffineTransform2D& viewTransform,
-                                     ImageInterpolation interpolation,
-                                     float windowCenter,
-                                     float windowWidth,
-                                     bool applyWindowing) const
-  {
-    if (alpha_.get() == NULL)
-    {
-      return;
-    }
-
-    if (buffer.GetFormat() != Orthanc::PixelFormat_Float32)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat);
-    }
-
-    unsigned int cropX, cropY, cropWidth, cropHeight;
-    GetCrop(cropX, cropY, cropWidth, cropHeight);
-
-    const AffineTransform2D t = AffineTransform2D::Combine(
-          viewTransform, GetTransform(),
-          AffineTransform2D::CreateOffset(cropX, cropY));
-
-    Orthanc::ImageAccessor cropped;
-    alpha_->GetRegion(cropped, cropX, cropY, cropWidth, cropHeight);
-
-    Orthanc::Image tmp(Orthanc::PixelFormat_Grayscale8, buffer.GetWidth(), buffer.GetHeight(), false);
-
-    unsigned int x1, y1, x2, y2;
-
-    if (!OrthancStone::GetProjectiveTransformExtent(x1, y1, x2, y2,
-                                                    t.GetHomogeneousMatrix(),
-                                                    cropped.GetWidth(),
-                                                    cropped.GetHeight(),
-                                                    buffer.GetWidth(),
-                                                    buffer.GetHeight()))
-    {
-      return;  // layer is outside the buffer
-    }
-
-    t.Apply(tmp, cropped, interpolation, true /* clear */);
-
-    float value = foreground_;
-
-    if (!applyWindowing) // if applying the windowing, it means we are ie rendering the image for a realtime visualization -> the foreground_ value is the value we want to see on the screen -> don't change it
-    {
-      // if not applying the windowing, it means ie that we are saving a dicom image to file and the windowing will be applied by a viewer later on -> we want the "foreground" value to be correct once the windowing will be applied
-      value = windowCenter - windowWidth/2 + (foreground_ / 65535.0f) * windowWidth;
-
-      if (value < 0.0f)
-      {
-        value = 0.0f;
-      }
-      if (value > 65535.0f)
-      {
-        value = 65535.0f;
-      }
-    }
-
-    for (unsigned int y = y1; y <= y2; y++)
-    {
-      float *q = reinterpret_cast<float*>(buffer.GetRow(y)) + x1;
-      const uint8_t *p = reinterpret_cast<uint8_t*>(tmp.GetRow(y)) + x1;
-
-      for (unsigned int x = x1; x <= x2; x++, p++, q++)
-      {
-        float a = static_cast<float>(*p) / 255.0f;
-
-        *q = (a * value + (1.0f - a) * (*q));
-      }
-    }
-  }
-
-  bool RadiographyAlphaLayer::GetRange(float& minValue,
-                                       float& maxValue) const
-  {
-    minValue = 0;
-    maxValue = 0;
-
-    if (foreground_ < 0)
-    {
-      minValue = foreground_;
-    }
-
-    if (foreground_ > 0)
-    {
-      maxValue = foreground_;
-    }
-
-    return true;
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyAlphaLayer.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "RadiographyLayer.h"
-
-#include <Compatibility.h>
-
-namespace OrthancStone
-{
-  class RadiographyScene;
-
-  // creates a transparent layer whose alpha channel is provided as a UINT8 image to SetAlpha.
-  // The color of the "mask" is either defined by a ForegroundValue or by the center value of the
-  // windowing from the scene.
-  class RadiographyAlphaLayer : public RadiographyLayer
-  {
-  private:
-    std::unique_ptr<Orthanc::ImageAccessor>  alpha_;       // Grayscale8 in the range [0, 255]  0 = transparent, 255 = opaque -> the foreground value will be displayed
-    float                                  foreground_;  // in the range [0.0, 65535.0]
-
-  public:
-    RadiographyAlphaLayer(const RadiographyScene& scene) :
-      RadiographyLayer(scene),
-      foreground_(0)
-    {
-    }
-
-
-    void SetForegroundValue(float foreground)
-    {
-      foreground_ = foreground;
-    }
-
-    float GetForegroundValue() const
-    {
-      return foreground_;
-    }
-
-    void SetAlpha(Orthanc::ImageAccessor* image);
-
-    virtual bool GetDefaultWindowing(float& center,
-                                     float& width) const
-    {
-      return false;
-    }
-
-
-    virtual void Render(Orthanc::ImageAccessor& buffer,
-                        const AffineTransform2D& viewTransform,
-                        ImageInterpolation interpolation,
-                        float windowCenter,
-                        float windowWidth,
-                        bool applyWindowing) const;
-
-    virtual bool GetRange(float& minValue,
-                          float& maxValue) const;
-
-    const Orthanc::ImageAccessor& GetAlpha() const
-    {
-      return *(alpha_.get());
-    }
-
-
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyDicomLayer.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,264 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "RadiographyDicomLayer.h"
-
-#include "RadiographyScene.h"
-#include "../Deprecated/Toolbox/DicomFrameConverter.h"
-#include "../Toolbox/ImageGeometry.h"
-
-#include <OrthancException.h>
-#include <Images/Image.h>
-#include <Images/ImageProcessing.h>
-#include <DicomDatasetReader.h>
-
-static OrthancPlugins::DicomTag  ConvertTag(const Orthanc::DicomTag& tag)
-{
-  return OrthancPlugins::DicomTag(tag.GetGroup(), tag.GetElement());
-}
-
-namespace OrthancStone
-{
-
-  void RadiographyDicomLayer::ApplyConverter()
-  {
-    if (source_.get() != NULL &&
-        converter_.get() != NULL)
-    {
-      converted_.reset(converter_->ConvertFrame(*source_));
-    }
-  }
-
-
-  RadiographyDicomLayer::RadiographyDicomLayer(const RadiographyScene& scene) :
-    RadiographyLayer(scene)
-  {
-
-  }
-
-  void RadiographyDicomLayer::SetDicomTags(const OrthancPlugins::FullOrthancDataset& dataset)
-  {
-    converter_.reset(new Deprecated::DicomFrameConverter);
-    converter_->ReadParameters(dataset);
-    ApplyConverter();
-
-    std::string tmp;
-    Vector pixelSpacing;
-
-    if (dataset.GetStringValue(tmp, ConvertTag(Orthanc::DICOM_TAG_PIXEL_SPACING)) &&
-        LinearAlgebra::ParseVector(pixelSpacing, tmp) &&
-        pixelSpacing.size() == 2)
-    {
-      SetPixelSpacing(pixelSpacing[0], pixelSpacing[1]);
-    }
-
-    OrthancPlugins::DicomDatasetReader reader(dataset);
-
-    unsigned int width, height;
-    if (!reader.GetUnsignedIntegerValue(width, ConvertTag(Orthanc::DICOM_TAG_COLUMNS)) ||
-        !reader.GetUnsignedIntegerValue(height, ConvertTag(Orthanc::DICOM_TAG_ROWS)))
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
-    }
-    else
-    {
-      SetSize(width, height);
-    }
-
-    if (dataset.GetStringValue(tmp, ConvertTag(Orthanc::DICOM_TAG_PHOTOMETRIC_INTERPRETATION)))
-    {
-      if (tmp == "MONOCHROME1")
-      {
-        SetPreferredPhotomotricDisplayMode(RadiographyPhotometricDisplayMode_Monochrome1);
-      }
-      else if (tmp == "MONOCHROME2")
-      {
-        SetPreferredPhotomotricDisplayMode(RadiographyPhotometricDisplayMode_Monochrome2);
-      }
-    }
-  }
-
-  void RadiographyDicomLayer::SetSourceImage(Orthanc::ImageAccessor* image)   // Takes ownership
-  {
-    std::unique_ptr<Orthanc::ImageAccessor> raii(image);
-
-    if (image == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
-    }
-
-    SetSize(image->GetWidth(), image->GetHeight());
-
-#if __cplusplus < 201103L
-      source_.reset(raii.release());
-#else
-      source_ = std::move(raii);
-#endif
-
-    ApplyConverter();
-
-    BroadcastMessage(RadiographyLayer::LayerEditedMessage(*this));
-  }
-
-  void RadiographyDicomLayer::SetSourceImage(Orthanc::ImageAccessor* image, double newPixelSpacingX, double newPixelSpacingY, bool emitLayerEditedEvent)   // Takes ownership
-  {
-    std::unique_ptr<Orthanc::ImageAccessor> raii(image);
-
-    if (image == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
-    }
-
-    SetSize(image->GetWidth(), image->GetHeight(), false);
-
-#if __cplusplus < 201103L
-    source_.reset(raii.release());
-#else
-    source_ = std::move(raii);
-#endif
-
-    ApplyConverter();
-
-    SetPixelSpacing(newPixelSpacingX, newPixelSpacingY, false);
-
-    if (emitLayerEditedEvent)
-    {
-      BroadcastMessage(RadiographyLayer::LayerEditedMessage(*this));
-    }
-  }
-
-
-  void RadiographyDicomLayer::SetDicomFrameConverter(Deprecated::DicomFrameConverter* converter)
-  {
-    converter_.reset(converter);
-  }
-
-  void RadiographyDicomLayer::Render(Orthanc::ImageAccessor& buffer,
-                                     const AffineTransform2D& viewTransform,
-                                     ImageInterpolation interpolation,
-                                     float windowCenter,
-                                     float windowWidth,
-                                     bool applyWindowing) const
-  {
-    if (converted_.get() != NULL)
-    {
-      if (converted_->GetFormat() != Orthanc::PixelFormat_Float32)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-      }
-
-      unsigned int cropX, cropY, cropWidth, cropHeight;
-      GetCrop(cropX, cropY, cropWidth, cropHeight);
-
-      AffineTransform2D t = AffineTransform2D::Combine(
-            viewTransform, GetTransform(),
-            AffineTransform2D::CreateOffset(cropX, cropY));
-
-      Orthanc::ImageAccessor cropped;
-      converted_->GetRegion(cropped, cropX, cropY, cropWidth, cropHeight);
-
-      unsigned int x1, y1, x2, y2;
-      if (!OrthancStone::GetProjectiveTransformExtent(x1, y1, x2, y2,
-                                                      t.GetHomogeneousMatrix(),
-                                                      cropped.GetWidth(),
-                                                      cropped.GetHeight(),
-                                                      buffer.GetWidth(),
-                                                      buffer.GetHeight()))
-      {
-        return;  // layer is outside the buffer
-      }
-
-      t.Apply(buffer, cropped, interpolation, false);
-
-      if (applyWindowing)
-      {
-        // apply windowing but stay in the range [0.0, 65535.0]
-        float w0 = windowCenter - windowWidth / 2.0f;
-        float w1 = windowCenter + windowWidth / 2.0f;
-
-        if (windowWidth >= 0.001f)  // Avoid division by zero at (*)
-        {
-          float scaling = 1.0f / (w1 - w0) * 65535.0f;
-          for (unsigned int y = y1; y <= y2; y++)
-          {
-            float* p = reinterpret_cast<float*>(buffer.GetRow(y)) + x1;
-
-            for (unsigned int x = x1; x <= x2; x++, p++)
-            {
-              if (*p >= w1)
-              {
-                *p = 65535.0;
-              }
-              else if (*p <= w0)
-              {
-                *p = 0;
-              }
-              else
-              {
-                // https://en.wikipedia.org/wiki/Linear_interpolation
-                *p = scaling * (*p - w0);  // (*)
-              }
-            }
-          }
-        }
-      }
-
-    }
-  }
-
-
-  bool RadiographyDicomLayer::GetDefaultWindowing(float& center,
-                                                  float& width) const
-  {
-    if (converter_.get() != NULL &&
-        converter_->HasDefaultWindow())
-    {
-      center = static_cast<float>(converter_->GetDefaultWindowCenter());
-      width = static_cast<float>(converter_->GetDefaultWindowWidth());
-      return true;
-    }
-    else
-    {
-      return false;
-    }
-  }
-
-
-  bool RadiographyDicomLayer::GetRange(float& minValue,
-                                       float& maxValue) const
-  {
-    if (converted_.get() != NULL)
-    {
-      if (converted_->GetFormat() != Orthanc::PixelFormat_Float32)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-      }
-
-      Orthanc::ImageProcessing::GetMinMaxFloatValue(minValue, maxValue, *converted_);
-      return true;
-    }
-    else
-    {
-      return false;
-    }
-  }
-
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyDicomLayer.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../Deprecated/Toolbox/DicomFrameConverter.h"
-#include "RadiographyLayer.h"
-
-#include <FullOrthancDataset.h>
-
-namespace OrthancStone
-{
-  class RadiographyScene;
-
-  class RadiographyDicomLayer : public RadiographyLayer
-  {
-  private:
-    std::unique_ptr<Orthanc::ImageAccessor>  source_;  // Content of PixelData
-    std::unique_ptr<Deprecated::DicomFrameConverter>     converter_;
-    std::unique_ptr<Orthanc::ImageAccessor>  converted_;  // Float32
-    std::string                            instanceId_;
-    unsigned int                           frame_;
-
-    void ApplyConverter();
-
-  public:
-    RadiographyDicomLayer(const RadiographyScene& scene);
-
-    void SetInstance(const std::string& instanceId, unsigned int frame)
-    {
-      instanceId_ = instanceId;
-      frame_ = frame;
-    }
-
-    std::string GetInstanceId() const
-    {
-      return instanceId_;
-    }
-
-    unsigned int GetFrame() const
-    {
-      return frame_;
-    }
-
-    virtual size_t GetApproximateMemoryUsage() const
-    {
-      size_t size = 0;
-      if (source_.get() != NULL)
-      {
-        size += source_->GetPitch() * source_->GetHeight();
-      }
-      if (converted_.get() != NULL)
-      {
-        size += converted_->GetPitch() * converted_->GetHeight();
-      }
-
-      return size;
-    }
-
-
-    void SetDicomTags(const OrthancPlugins::FullOrthancDataset& dataset);
-
-    void SetSourceImage(Orthanc::ImageAccessor* image);   // Takes ownership
-
-    void SetSourceImage(Orthanc::ImageAccessor* image, double newPixelSpacingX, double newPixelSpacingY, bool emitLayerEditedEvent = true);   // Takes ownership
-
-    const Orthanc::ImageAccessor* GetSourceImage() const {return source_.get();}  // currently need this access to serialize scene in plain old data to send to a WASM worker
-
-    const Deprecated::DicomFrameConverter& GetDicomFrameConverter() const {return *converter_;} // currently need this access to serialize scene in plain old data to send to a WASM worker
-    
-     // Takes ownership
-    void SetDicomFrameConverter(Deprecated::DicomFrameConverter* converter);
-
-    virtual void Render(Orthanc::ImageAccessor& buffer,
-                        const AffineTransform2D& viewTransform,
-                        ImageInterpolation interpolation,
-                        float windowCenter,
-                        float windowWidth,
-                        bool applyWindowing) const;
-
-    virtual bool GetDefaultWindowing(float& center,
-                                     float& width) const;
-
-    virtual bool GetRange(float& minValue,
-                          float& maxValue) const;
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyLayer.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,402 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "RadiographyLayer.h"
-
-#include <OrthancException.h>
-
-
-namespace OrthancStone
-{
-  static double Square(double x)
-  {
-    return x * x;
-  }
-
-
-  RadiographyLayer::Geometry::Geometry() :
-    hasCrop_(false),
-    flipVertical_(false),
-    flipHorizontal_(false),
-    panX_(0),
-    panY_(0),
-    angle_(0),
-    resizeable_(false),
-    pixelSpacingX_(1),
-    pixelSpacingY_(1)
-  {
-
-  }
-
-  void RadiographyLayer::Geometry::GetCrop(unsigned int &x, unsigned int &y, unsigned int &width, unsigned int &height) const
-  {
-    if (!hasCrop_)
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);  // you should probably use RadiographyLayer::GetCrop() or at least call HasCrop() before
-
-    x = cropX_;
-    y = cropY_;
-    width = cropWidth_;
-    height = cropHeight_;
-  }
-
-  void RadiographyLayer::UpdateTransform()
-  {
-    // important to update transform_ before getting the center to use the right scaling !!!
-    transform_ = AffineTransform2D::CreateScaling(geometry_.GetScalingX(), geometry_.GetScalingY());
-
-    double centerX, centerY;
-    GetCenter(centerX, centerY);
-
-    transform_ = AffineTransform2D::Combine(
-          AffineTransform2D::CreateOffset(geometry_.GetPanX(), geometry_.GetPanY()),
-          AffineTransform2D::CreateRotation(geometry_.GetAngle(), centerX, centerY),
-          transform_);
-
-    transformInverse_ = AffineTransform2D::Invert(transform_);
-  }
-
-
-  void RadiographyLayer::AddToExtent(Extent2D& extent,
-                                     double x,
-                                     double y) const
-  {
-    GetTransform().Apply(x, y);
-    extent.AddPoint(x, y);
-  }
-
-  bool RadiographyLayer::Contains(double x,
-                                  double y) const
-  {
-    GetTransformInverse().Apply(x, y);
-
-    unsigned int cropX, cropY, cropWidth, cropHeight;
-    GetCrop(cropX, cropY, cropWidth, cropHeight);
-
-    return (x >= cropX && x <= cropX + cropWidth &&
-            y >= cropY && y <= cropY + cropHeight);
-  }
-
-
-  void RadiographyLayer::DrawBorders(CairoContext& context,
-                                     double zoom)
-  {
-    if (GetControlPointCount() < 3 )
-      return;
-
-    cairo_t* cr = context.GetObject();
-    cairo_set_line_width(cr, 2.0 / zoom);
-
-    ControlPoint cp;
-    GetControlPoint(cp, 0);
-    cairo_move_to(cr, cp.x, cp.y);
-
-    for (size_t i = 0; i < GetControlPointCount(); i++)
-    {
-      GetControlPoint(cp, i);
-      cairo_line_to(cr, cp.x, cp.y);
-    }
-
-    cairo_close_path(cr);
-    cairo_stroke(cr);
-  }
-
-
-  RadiographyLayer::RadiographyLayer(const RadiographyScene& scene) :
-    index_(0),
-    hasSize_(false),
-    width_(0),
-    height_(0),
-    prefferedPhotometricDisplayMode_(RadiographyPhotometricDisplayMode_Default),
-    scene_(scene)
-  {
-    UpdateTransform();
-  }
-
-  void RadiographyLayer::ResetCrop()
-  {
-    geometry_.ResetCrop();
-    UpdateTransform();
-  }
-
-  void RadiographyLayer::SetPreferredPhotomotricDisplayMode(RadiographyPhotometricDisplayMode  prefferedPhotometricDisplayMode)
-  {
-    prefferedPhotometricDisplayMode_ = prefferedPhotometricDisplayMode;
-
-    BroadcastMessage(RadiographyLayer::LayerEditedMessage(*this));
-  }
-
-  void RadiographyLayer::SetCrop(unsigned int x,
-                                 unsigned int y,
-                                 unsigned int width,
-                                 unsigned int height)
-  {
-    if (!hasSize_)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-
-    if (x + width > width_ ||
-        y + height > height_)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    geometry_.SetCrop(x, y, width, height);
-    UpdateTransform();
-
-    BroadcastMessage(RadiographyLayer::LayerEditedMessage(*this));
-  }
-
-  void RadiographyLayer::SetGeometry(const Geometry& geometry)
-  {
-    geometry_ = geometry;
-
-    if (hasSize_)
-    {
-      UpdateTransform();
-    }
-
-    BroadcastMessage(RadiographyLayer::LayerEditedMessage(*this));
-  }
-
-
-  void RadiographyLayer::GetCrop(unsigned int& x,
-                                 unsigned int& y,
-                                 unsigned int& width,
-                                 unsigned int& height) const
-  {
-    if (GetGeometry().HasCrop())
-    {
-      GetGeometry().GetCrop(x, y, width, height);
-    }
-    else
-    {
-      x = 0;
-      y = 0;
-      width = width_;
-      height = height_;
-    }
-  }
-
-  
-  void RadiographyLayer::SetAngle(double angle)
-  {
-    geometry_.SetAngle(angle);
-    UpdateTransform();
-
-    BroadcastMessage(RadiographyLayer::LayerEditedMessage(*this));
-  }
-
-  void RadiographyLayer::SetFlipVertical(bool flip)
-  {
-    geometry_.SetFlipVertical(flip);
-    UpdateTransform();
-
-    BroadcastMessage(RadiographyLayer::LayerEditedMessage(*this));
-  }
-
-  void RadiographyLayer::SetFlipHorizontal(bool flip)
-  {
-    geometry_.SetFlipHorizontal(flip);
-    UpdateTransform();
-
-    BroadcastMessage(RadiographyLayer::LayerEditedMessage(*this));
-  }
-
-  void RadiographyLayer::SetSize(unsigned int width,
-                                 unsigned int height,
-                                 bool emitLayerEditedEvent)
-  {
-    hasSize_ = true;
-    width_ = width;
-    height_ = height;
-
-    UpdateTransform();
-
-    if (emitLayerEditedEvent)
-    {
-      BroadcastMessage(RadiographyLayer::LayerEditedMessage(*this));
-    }
-  }
-
-  Extent2D RadiographyLayer::GetSceneExtent(bool /*minimal*/) const
-  {
-    Extent2D extent;
-
-    unsigned int x, y, width, height;
-    GetCrop(x, y, width, height);
-
-    double dx = static_cast<double>(x);
-    double dy = static_cast<double>(y);
-    double dwidth = static_cast<double>(width);
-    double dheight = static_cast<double>(height);
-
-    // AddToExtent transforms the coordinates from image to scene
-    AddToExtent(extent, dx, dy);
-    AddToExtent(extent, dx + dwidth, dy);
-    AddToExtent(extent, dx, dy + dheight);
-    AddToExtent(extent, dx + dwidth, dy + dheight);
-
-    return extent;
-  }
-
-
-  bool RadiographyLayer::GetPixel(unsigned int& imageX,
-                                  unsigned int& imageY,
-                                  double sceneX,
-                                  double sceneY) const
-  {
-    if (width_ == 0 ||
-        height_ == 0)
-    {
-      return false;
-    }
-    else
-    {
-      GetTransformInverse().Apply(sceneX, sceneY);
-
-      int x = static_cast<int>(std::floor(sceneX));
-      int y = static_cast<int>(std::floor(sceneY));
-
-      if (x < 0)
-      {
-        imageX = 0;
-      }
-      else if (x >= static_cast<int>(width_))
-      {
-        imageX = width_;
-      }
-      else
-      {
-        imageX = static_cast<unsigned int>(x);
-      }
-
-      if (y < 0)
-      {
-        imageY = 0;
-      }
-      else if (y >= static_cast<int>(height_))
-      {
-        imageY = height_;
-      }
-      else
-      {
-        imageY = static_cast<unsigned int>(y);
-      }
-
-      return true;
-    }
-  }
-
-
-  void RadiographyLayer::SetPan(double x,
-                                double y)
-  {
-    geometry_.SetPan(x, y);
-    UpdateTransform();
-    BroadcastMessage(RadiographyLayer::LayerEditedMessage(*this));
-  }
-
-
-  void RadiographyLayer::SetPixelSpacing(double x,
-                                         double y,
-                                         bool emitLayerEditedEvent)
-  {
-    geometry_.SetPixelSpacing(x, y);
-    UpdateTransform();
-    if (emitLayerEditedEvent)
-    {
-      BroadcastMessage(RadiographyLayer::LayerEditedMessage(*this));
-    }
-  }
-
-
-  void RadiographyLayer::GetCenter(double& centerX,
-                                   double& centerY) const
-  {
-    centerX = static_cast<double>(width_) / 2.0;
-    centerY = static_cast<double>(height_) / 2.0;
-    GetTransform().Apply(centerX, centerY);
-  }
-
-
-
-  size_t RadiographyLayer::GetControlPointCount() const {return 4;}
-
-  void RadiographyLayer::GetControlPoint(ControlPoint& cpScene /* out in scene coordinates */,
-                                         size_t index) const
-  {
-    unsigned int cropX, cropY, cropWidth, cropHeight;
-    GetCrop(cropX, cropY, cropWidth, cropHeight);
-
-    ControlPoint cp;
-    switch (index)
-    {
-      case RadiographyControlPointType_TopLeftCorner:
-        cp = ControlPoint(cropX, cropY, RadiographyControlPointType_TopLeftCorner);
-        break;
-
-      case RadiographyControlPointType_TopRightCorner:
-        cp = ControlPoint(cropX + cropWidth, cropY, RadiographyControlPointType_TopRightCorner);
-        break;
-
-      case RadiographyControlPointType_BottomLeftCorner:
-        cp = ControlPoint(cropX, cropY + cropHeight, RadiographyControlPointType_BottomLeftCorner);
-        break;
-
-      case RadiographyControlPointType_BottomRightCorner:
-        cp = ControlPoint(cropX + cropWidth, cropY + cropHeight, RadiographyControlPointType_BottomRightCorner);
-        break;
-
-    default:
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    // transforms image coordinates into scene coordinates
-    GetTransform().Apply(cp.x, cp.y);
-    cpScene = cp;
-  }
-
-  bool RadiographyLayer::LookupControlPoint(ControlPoint& cpScene /* out */,
-                                            double x,
-                                            double y,
-                                            double zoom,
-                                            double viewportDistance) const
-  {
-    double threshold = Square(viewportDistance / zoom);
-
-    for (size_t i = 0; i < GetControlPointCount(); i++)
-    {
-      ControlPoint cp;
-      GetControlPoint(cp, i);
-
-      double d = Square(cp.x - x) + Square(cp.y - y);
-
-      if (d <= threshold)
-      {
-        cpScene = cp;
-        return true;
-      }
-    }
-
-    return false;
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyLayer.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,395 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include <algorithm>
-
-#include "../Toolbox/AffineTransform2D.h"
-#include "../Toolbox/Extent2D.h"
-#include "../Wrappers/CairoContext.h"
-#include "../Messages/IMessage.h"
-#include "../Messages/IObservable.h"
-
-namespace OrthancStone
-{
-  class RadiographyScene;
-
-  enum RadiographyControlPointType
-  {
-    RadiographyControlPointType_TopLeftCorner = 0,
-    RadiographyControlPointType_TopRightCorner = 1,
-    RadiographyControlPointType_BottomRightCorner = 2,
-    RadiographyControlPointType_BottomLeftCorner = 3
-  };
-
-  enum RadiographyPhotometricDisplayMode
-  {
-    RadiographyPhotometricDisplayMode_Default,
-
-    RadiographyPhotometricDisplayMode_Monochrome1,
-    RadiographyPhotometricDisplayMode_Monochrome2
-  };
-
-  
-  struct ControlPoint
-  {
-    double x;
-    double y;
-    size_t index;
-
-    ControlPoint(double x, double y, size_t index)
-      : x(x),
-        y(y),
-        index(index)
-    {}
-
-    ControlPoint()
-      : x(0),
-        y(0),
-        index(std::numeric_limits<size_t>::max())
-    {}
-  };
-
-  class RadiographyLayer : public IObservable
-  {
-    friend class RadiographyScene;
-
-  public:
-    ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, LayerEditedMessage, RadiographyLayer);
-
-    class Geometry
-    {
-      bool               hasCrop_;
-      unsigned int       cropX_;
-      unsigned int       cropY_;
-      unsigned int       cropWidth_;
-      unsigned int       cropHeight_;
-      bool               flipVertical_;
-      bool               flipHorizontal_;
-      double             panX_;
-      double             panY_;
-      double             angle_;
-      bool               resizeable_;
-      double             pixelSpacingX_;
-      double             pixelSpacingY_;
-
-    public:
-      Geometry();
-
-      void ResetCrop()
-      {
-        hasCrop_ = false;
-      }
-
-      void SetCrop(unsigned int x,
-                   unsigned int y,
-                   unsigned int width,
-                   unsigned int height)
-      {
-        hasCrop_ = true;
-        cropX_ = x;
-        cropY_ = y;
-        cropWidth_ = width;
-        cropHeight_ = height;
-      }
-
-      bool HasCrop() const
-      {
-        return hasCrop_;
-      }
-
-      void GetCrop(unsigned int& x,
-                   unsigned int& y,
-                   unsigned int& width,
-                   unsigned int& height) const;
-
-      void SetAngle(double angle)
-      {
-        angle_ = angle;
-      }
-
-      double GetAngle() const
-      {
-        return angle_;
-      }
-
-      void SetPan(double x,
-                  double y)
-      {
-        panX_ = x;
-        panY_ = y;
-      }
-
-      double GetPanX() const
-      {
-        return panX_;
-      }
-
-      double GetPanY() const
-      {
-        return panY_;
-      }
-
-      bool IsResizeable() const
-      {
-        return resizeable_;
-      }
-
-      void SetResizeable(bool resizeable)
-      {
-        resizeable_ = resizeable;
-      }
-
-      void SetPixelSpacing(double x,
-                           double y)
-      {
-        pixelSpacingX_ = x;
-        pixelSpacingY_ = y;
-      }
-
-      double GetPixelSpacingX() const
-      {
-        return pixelSpacingX_;
-      }
-
-      double GetPixelSpacingY() const
-      {
-        return pixelSpacingY_;
-      }
-
-      void SetFlipVertical(bool flip) //  mirrors image around an horizontal axis (note: flip is applied before the rotation !)
-      {
-        flipVertical_ = flip;
-      }
-
-      void SetFlipHorizontal(bool flip) //  mirrors image around a vertical axis (note: flip is applied before the rotation !)
-      {
-        flipHorizontal_ = flip;
-      }
-
-      bool GetFlipVertical() const
-      {
-        return flipVertical_;
-      }
-
-      bool GetFlipHorizontal() const
-      {
-        return flipHorizontal_;
-      }
-
-      double GetScalingX() const
-      {
-        return (flipHorizontal_ ? - pixelSpacingX_: pixelSpacingX_);
-      }
-
-      double GetScalingY() const
-      {
-        return (flipVertical_ ? - pixelSpacingY_: pixelSpacingY_);
-      }
-    };
-
-  private:
-    size_t             index_;
-    bool               hasSize_;
-    unsigned int       width_;
-    unsigned int       height_;
-    AffineTransform2D  transform_;
-    AffineTransform2D  transformInverse_;
-    Geometry           geometry_;
-    RadiographyPhotometricDisplayMode  prefferedPhotometricDisplayMode_;
-    const RadiographyScene&   scene_;
-
-  protected:
-    void SetPreferredPhotomotricDisplayMode(RadiographyPhotometricDisplayMode  prefferedPhotometricDisplayMode);
-
-  private:
-    void UpdateTransform();
-
-    void AddToExtent(Extent2D& extent,
-                     double x,
-                     double y) const;
-
-    void SetIndex(size_t index)
-    {
-      index_ = index;
-    }
-
-    bool Contains(double x,
-                  double y) const;
-
-    void DrawBorders(CairoContext& context,
-                     double zoom);
-
-  public:
-    RadiographyLayer(const RadiographyScene& scene);
-
-    virtual ~RadiographyLayer()
-    {
-    }
-
-    virtual const AffineTransform2D& GetTransform() const
-    {
-      return transform_;
-    }
-
-    virtual const AffineTransform2D& GetTransformInverse() const
-    {
-      return transformInverse_;
-    }
-
-    size_t GetIndex() const
-    {
-      return index_;
-    }
-
-    const RadiographyScene& GetScene() const
-    {
-      return scene_;
-    }
-
-    const Geometry& GetGeometry() const
-    {
-      return geometry_;
-    }
-
-    void SetGeometry(const Geometry& geometry);
-
-    void ResetCrop();
-
-    void SetCrop(unsigned int x,       // those are pixel coordinates/size
-                 unsigned int y,
-                 unsigned int width,
-                 unsigned int height);
-
-    void SetCrop(const Extent2D& sceneExtent)
-    {
-      Extent2D imageCrop;
-
-      {
-        double x = sceneExtent.GetX1();
-        double y = sceneExtent.GetY1();
-        GetTransformInverse().Apply(x, y);
-        imageCrop.AddPoint(x, y);
-      }
-
-      {
-        double x = sceneExtent.GetX2();
-        double y = sceneExtent.GetY2();
-        GetTransformInverse().Apply(x, y);
-        imageCrop.AddPoint(x, y);
-      }
-
-      SetCrop(static_cast<unsigned int>(std::max(0.0, std::floor(imageCrop.GetX1()))),
-              static_cast<unsigned int>(std::max(0.0, std::floor(imageCrop.GetY1()))),
-              std::min(width_, static_cast<unsigned int>(std::ceil(imageCrop.GetWidth()))),
-              std::min(height_, static_cast<unsigned int>(std::ceil(imageCrop.GetHeight())))
-              );
-    }
-
-
-    void GetCrop(unsigned int& x,
-                 unsigned int& y,
-                 unsigned int& width,
-                 unsigned int& height) const;
-
-    void SetAngle(double angle);
-
-    void SetPan(double x,
-                double y);
-
-    void SetFlipVertical(bool flip); //  mirrors image around an horizontal axis (note: flip is applied before the rotation !)
-
-    void SetFlipHorizontal(bool flip); //  mirrors image around a vertical axis (note: flip is applied before the rotation !)
-
-    void SetResizeable(bool resizeable)
-    {
-      geometry_.SetResizeable(resizeable);
-    }
-
-    void SetSize(unsigned int width,
-                 unsigned int height,
-                 bool emitLayerEditedEvent = true);
-
-    bool HasSize() const
-    {
-      return hasSize_;
-    }
-
-    unsigned int GetWidth() const
-    {
-      return width_;
-    }
-
-    unsigned int GetHeight() const
-    {
-      return height_;
-    }
-
-    virtual Extent2D GetSceneExtent(bool minimal) const;
-
-    virtual bool GetPixel(unsigned int& imageX,
-                          unsigned int& imageY,
-                          double sceneX,
-                          double sceneY) const;
-
-    void SetPixelSpacing(double x,
-                         double y,
-                         bool emitLayerEditedEvent = true);
-
-    void GetCenter(double& centerX,
-                   double& centerY) const;
-
-    virtual void GetControlPoint(ControlPoint& cpScene /* out in scene coordinates */,
-                                 size_t index) const;
-
-    virtual size_t GetControlPointCount() const;
-
-    bool LookupControlPoint(ControlPoint& cpScene /* out */,
-                            double x,
-                            double y,
-                            double zoom,
-                            double viewportDistance) const;
-
-    virtual bool GetDefaultWindowing(float& center,
-                                     float& width) const = 0;
-
-    RadiographyPhotometricDisplayMode GetPreferredPhotomotricDisplayMode() const
-    {
-      return prefferedPhotometricDisplayMode_;
-    }
-
-    virtual void Render(Orthanc::ImageAccessor& buffer,
-                        const AffineTransform2D& viewTransform,
-                        ImageInterpolation interpolation,
-                        float windowCenter,
-                        float windowWidth,
-                        bool applyWindowing) const = 0;
-
-    virtual bool GetRange(float& minValue,
-                          float& maxValue) const = 0;
-
-    virtual size_t GetApproximateMemoryUsage() const // this is used to limit the number of scenes loaded in RAM when resources are limited (we actually only count the size used by the images, not the C structs)
-    {
-      return 0;
-    }
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyLayerCropTracker.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,145 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "RadiographyLayerCropTracker.h"
-
-#include "RadiographySceneCommand.h"
-
-#include <OrthancException.h>
-
-namespace OrthancStone
-{
-  class RadiographyLayerCropTracker::UndoRedoCommand : public RadiographySceneCommand
-  {
-  private:
-    unsigned int  sourceCropX_;
-    unsigned int  sourceCropY_;
-    unsigned int  sourceCropWidth_;
-    unsigned int  sourceCropHeight_;
-    unsigned int  targetCropX_;
-    unsigned int  targetCropY_;
-    unsigned int  targetCropWidth_;
-    unsigned int  targetCropHeight_;
-
-  protected:
-    virtual void UndoInternal(RadiographyLayer& layer) const
-    {
-      layer.SetCrop(sourceCropX_, sourceCropY_, sourceCropWidth_, sourceCropHeight_);
-    }
-
-    virtual void RedoInternal(RadiographyLayer& layer) const
-    {
-      layer.SetCrop(targetCropX_, targetCropY_, targetCropWidth_, targetCropHeight_);
-    }
-
-  public:
-    UndoRedoCommand(const RadiographyLayerCropTracker& tracker) :
-      RadiographySceneCommand(tracker.accessor_),
-      sourceCropX_(tracker.cropX_),
-      sourceCropY_(tracker.cropY_),
-      sourceCropWidth_(tracker.cropWidth_),
-      sourceCropHeight_(tracker.cropHeight_)
-    {
-      tracker.accessor_.GetLayer().GetCrop(targetCropX_, targetCropY_,
-                                           targetCropWidth_, targetCropHeight_);
-    }
-  };
-
-
-  RadiographyLayerCropTracker::RadiographyLayerCropTracker(UndoRedoStack& undoRedoStack,
-                                                           RadiographyScene& scene,
-                                                           const Deprecated::ViewportGeometry& view,
-                                                           size_t layer,
-                                                           const ControlPoint& startControlPoint) :
-    undoRedoStack_(undoRedoStack),
-    accessor_(scene, layer),
-    startControlPoint_(startControlPoint)
-  {
-    if (accessor_.IsValid())
-    {
-      accessor_.GetLayer().GetCrop(cropX_, cropY_, cropWidth_, cropHeight_);
-    }
-  }
-
-
-  void RadiographyLayerCropTracker::Render(CairoContext& context,
-                                           double zoom)
-  {
-    throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-  }
-
-
-  void RadiographyLayerCropTracker::MouseUp()
-  {
-    if (accessor_.IsValid())
-    {
-      undoRedoStack_.Add(new UndoRedoCommand(*this));
-    }
-  }
-
-  
-  void RadiographyLayerCropTracker::MouseMove(int displayX,
-                                              int displayY,
-                                              double sceneX,
-                                              double sceneY,
-                                              const std::vector<Deprecated::Touch>& displayTouches,
-                                              const std::vector<Deprecated::Touch>& sceneTouches)
-  {
-    if (accessor_.IsValid())
-    {
-      unsigned int x, y;
-        
-      RadiographyLayer& layer = accessor_.GetLayer();
-      if (layer.GetPixel(x, y, sceneX, sceneY))
-      {
-        unsigned int targetX, targetWidth;
-
-        if (startControlPoint_.index == RadiographyControlPointType_TopLeftCorner ||
-            startControlPoint_.index == RadiographyControlPointType_BottomLeftCorner)
-        {
-          targetX = std::min(x, cropX_ + cropWidth_);
-          targetWidth = cropX_ + cropWidth_ - targetX;
-        }
-        else
-        {
-          targetX = cropX_;
-          targetWidth = std::max(x, cropX_) - cropX_;
-        }
-
-        unsigned int targetY, targetHeight;
-
-        if (startControlPoint_.index == RadiographyControlPointType_TopLeftCorner ||
-            startControlPoint_.index == RadiographyControlPointType_TopRightCorner)
-        {
-          targetY = std::min(y, cropY_ + cropHeight_);
-          targetHeight = cropY_ + cropHeight_ - targetY;
-        }
-        else
-        {
-          targetY = cropY_;
-          targetHeight = std::max(y, cropY_) - cropY_;
-        }
-
-        layer.SetCrop(targetX, targetY, targetWidth, targetHeight);
-      }
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyLayerCropTracker.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../Toolbox/UndoRedoStack.h"
-#include "../Deprecated/Toolbox/ViewportGeometry.h"
-#include "../Deprecated/Widgets/IWorldSceneMouseTracker.h"
-#include "RadiographyScene.h"
-
-namespace OrthancStone
-{
-  class RadiographyLayerCropTracker : public Deprecated::IWorldSceneMouseTracker
-  {
-  private:
-    class UndoRedoCommand;
-
-    UndoRedoStack&                   undoRedoStack_;
-    RadiographyScene::LayerAccessor  accessor_;
-    ControlPoint                     startControlPoint_;
-    unsigned int                     cropX_;
-    unsigned int                     cropY_;
-    unsigned int                     cropWidth_;
-    unsigned int                     cropHeight_;
-
-  public:
-    RadiographyLayerCropTracker(UndoRedoStack& undoRedoStack,
-                                RadiographyScene& scene,
-                                const Deprecated::ViewportGeometry& view,
-                                size_t layer,
-                                const ControlPoint& startControlPoint);
-
-    virtual bool HasRender() const
-    {
-      return false;
-    }
-
-    virtual void Render(CairoContext& context,
-                        double zoom);
-
-    virtual void MouseUp();
-
-    virtual void MouseMove(int displayX,
-                           int displayY,
-                           double sceneX,
-                           double sceneY,
-                           const std::vector<Deprecated::Touch>& displayTouches,
-                           const std::vector<Deprecated::Touch>& sceneTouches);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyLayerMaskTracker.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "RadiographyLayerMaskTracker.h"
-#include "RadiographyMaskLayer.h"
-
-#include "RadiographySceneCommand.h"
-
-#include <OrthancException.h>
-
-namespace OrthancStone
-{
-  class RadiographyLayerMaskTracker::UndoRedoCommand : public RadiographySceneCommand
-  {
-  private:
-    ControlPoint sourceSceneCp_;
-    ControlPoint targetSceneCp_;
-
-  protected:
-    virtual void UndoInternal(RadiographyLayer& layer) const
-    {
-      RadiographyMaskLayer* maskLayer = dynamic_cast<RadiographyMaskLayer*>(&layer);
-      if (maskLayer == NULL)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-      }
-      unsigned int ix, iy; // image coordinates
-      if (maskLayer->GetPixel(ix, iy, sourceSceneCp_.x, sourceSceneCp_.y))
-      {
-        maskLayer->SetCorner(Orthanc::ImageProcessing::ImagePoint((int32_t)ix, (int32_t)iy), sourceSceneCp_.index);
-      }
-    }
-
-    virtual void RedoInternal(RadiographyLayer& layer) const
-    {
-      RadiographyMaskLayer* maskLayer = dynamic_cast<RadiographyMaskLayer*>(&layer);
-      if (maskLayer == NULL)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-      }
-      unsigned int ix, iy; // image coordinates
-      if (maskLayer->GetPixel(ix, iy, targetSceneCp_.x, targetSceneCp_.y))
-      {
-        maskLayer->SetCorner(Orthanc::ImageProcessing::ImagePoint((int32_t)ix, (int32_t)iy), targetSceneCp_.index);
-      }
-    }
-
-  public:
-    UndoRedoCommand(const RadiographyLayerMaskTracker& tracker) :
-      RadiographySceneCommand(tracker.accessor_),
-      sourceSceneCp_(tracker.startSceneCp_),
-      targetSceneCp_(tracker.endSceneCp_)
-    {
-      RadiographyMaskLayer* maskLayer = dynamic_cast<RadiographyMaskLayer*>(&(tracker.accessor_.GetLayer()));
-      if (maskLayer == NULL)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-      }
-      unsigned int ix, iy; // image coordinates
-      if (maskLayer->GetPixel(ix, iy, targetSceneCp_.x, targetSceneCp_.y))
-      {
-        maskLayer->SetCorner(Orthanc::ImageProcessing::ImagePoint((int32_t)ix, (int32_t)iy), targetSceneCp_.index);
-      }
-    }
-  };
-
-
-  RadiographyLayerMaskTracker::RadiographyLayerMaskTracker(UndoRedoStack& undoRedoStack,
-                                                           RadiographyScene& scene,
-                                                           const Deprecated::ViewportGeometry& view,
-                                                           size_t layer,
-                                                           const ControlPoint& startSceneControlPoint) :
-    undoRedoStack_(undoRedoStack),
-    accessor_(scene, layer),
-    startSceneCp_(startSceneControlPoint),
-    endSceneCp_(startSceneControlPoint)
-  {
-  }
-
-
-  void RadiographyLayerMaskTracker::Render(CairoContext& context,
-                                           double zoom)
-  {
-    throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-  }
-
-
-  void RadiographyLayerMaskTracker::MouseUp()
-  {
-    if (accessor_.IsValid() && startSceneCp_.x != endSceneCp_.x && startSceneCp_.y != endSceneCp_.y)
-    {
-      undoRedoStack_.Add(new UndoRedoCommand(*this));
-    }
-  }
-
-  
-  void RadiographyLayerMaskTracker::MouseMove(int displayX,
-                                              int displayY,
-                                              double sceneX,
-                                              double sceneY,
-                                              const std::vector<Deprecated::Touch>& displayTouches,
-                                              const std::vector<Deprecated::Touch>& sceneTouches)
-  {
-    if (accessor_.IsValid())
-    {
-      unsigned int ix, iy; // image coordinates
-
-      RadiographyLayer& layer = accessor_.GetLayer();
-      if (layer.GetPixel(ix, iy, sceneX, sceneY))
-      {
-        endSceneCp_ = ControlPoint(sceneX, sceneY, startSceneCp_.index);
-
-        RadiographyMaskLayer* maskLayer = dynamic_cast<RadiographyMaskLayer*>(&layer);
-        if (maskLayer == NULL)
-        {
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-        }
-        maskLayer->SetCorner(Orthanc::ImageProcessing::ImagePoint((int32_t)ix, (int32_t)iy), startSceneCp_.index);
-      }
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyLayerMaskTracker.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../Toolbox/UndoRedoStack.h"
-#include "../Deprecated/Toolbox/ViewportGeometry.h"
-#include "../Deprecated/Widgets/IWorldSceneMouseTracker.h"
-#include "RadiographyScene.h"
-
-namespace OrthancStone
-{
-  class RadiographyLayerMaskTracker : public Deprecated::IWorldSceneMouseTracker
-  {
-  private:
-    class UndoRedoCommand;
-
-    UndoRedoStack&                   undoRedoStack_;
-    RadiographyScene::LayerAccessor  accessor_;
-    ControlPoint                     startSceneCp_;
-    ControlPoint                     endSceneCp_;
-
-  public:
-    RadiographyLayerMaskTracker(UndoRedoStack& undoRedoStack,
-                                RadiographyScene& scene,
-                                const Deprecated::ViewportGeometry& view,
-                                size_t layer,
-                                const ControlPoint& startSceneControlPoint);
-
-    virtual bool HasRender() const
-    {
-      return false;
-    }
-
-    virtual void Render(CairoContext& context,
-                        double zoom);
-
-    virtual void MouseUp();
-
-    virtual void MouseMove(int displayX,
-                           int displayY,
-                           double sceneX,
-                           double sceneY,
-                           const std::vector<Deprecated::Touch>& displayTouches,
-                           const std::vector<Deprecated::Touch>& sceneTouches);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyLayerMoveTracker.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "RadiographyLayerMoveTracker.h"
-
-#include "RadiographySceneCommand.h"
-
-#include <OrthancException.h>
-
-namespace OrthancStone
-{
-  class RadiographyLayerMoveTracker::UndoRedoCommand : public RadiographySceneCommand
-  {
-  private:
-    double  sourceX_;
-    double  sourceY_;
-    double  targetX_;
-    double  targetY_;
-
-  protected:
-    virtual void UndoInternal(RadiographyLayer& layer) const
-    {
-      layer.SetPan(sourceX_, sourceY_);
-    }
-
-    virtual void RedoInternal(RadiographyLayer& layer) const
-    {
-      layer.SetPan(targetX_, targetY_);
-    }
-
-  public:
-    UndoRedoCommand(const RadiographyLayerMoveTracker& tracker) :
-      RadiographySceneCommand(tracker.accessor_),
-      sourceX_(tracker.panX_),
-      sourceY_(tracker.panY_),
-      targetX_(tracker.accessor_.GetLayer().GetGeometry().GetPanX()),
-      targetY_(tracker.accessor_.GetLayer().GetGeometry().GetPanY())
-    {
-    }
-  };
-
-
-  RadiographyLayerMoveTracker::RadiographyLayerMoveTracker(UndoRedoStack& undoRedoStack,
-                                                           RadiographyScene& scene,
-                                                           size_t layer,
-                                                           double x,
-                                                           double y,
-                                                           bool oneAxis) :
-    undoRedoStack_(undoRedoStack),
-    accessor_(scene, layer),
-    clickX_(x),
-    clickY_(y),
-    oneAxis_(oneAxis)
-  {
-    if (accessor_.IsValid())
-    {
-      panX_ = accessor_.GetLayer().GetGeometry().GetPanX();
-      panY_ = accessor_.GetLayer().GetGeometry().GetPanY();
-    }
-  }
-
-
-  void RadiographyLayerMoveTracker::Render(CairoContext& context,
-                                           double zoom)
-  {
-    throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-  }
-
-  
-  void RadiographyLayerMoveTracker::MouseUp()
-  {
-    if (accessor_.IsValid())
-    {
-      undoRedoStack_.Add(new UndoRedoCommand(*this));
-    }
-  }
-
-  
-  void RadiographyLayerMoveTracker::MouseMove(int displayX,
-                                              int displayY,
-                                              double sceneX,
-                                              double sceneY,
-                                              const std::vector<Deprecated::Touch>& displayTouches,
-                                              const std::vector<Deprecated::Touch>& sceneTouches)
-  {
-    if (accessor_.IsValid())
-    {
-      double dx = sceneX - clickX_;
-      double dy = sceneY - clickY_;
-
-      if (oneAxis_)
-      {
-        if (fabs(dx) > fabs(dy))
-        {
-          accessor_.GetLayer().SetPan(dx + panX_, panY_);
-        }
-        else
-        {
-          accessor_.GetLayer().SetPan(panX_, dy + panY_);
-        }
-      }
-      else
-      {
-        accessor_.GetLayer().SetPan(dx + panX_, dy + panY_);
-      }
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyLayerMoveTracker.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../Toolbox/UndoRedoStack.h"
-#include "../Deprecated/Widgets/IWorldSceneMouseTracker.h"
-#include "RadiographyScene.h"
-
-namespace OrthancStone
-{
-  class RadiographyLayerMoveTracker : public Deprecated::IWorldSceneMouseTracker
-  {
-  private:
-    class UndoRedoCommand;
-    
-    UndoRedoStack&                   undoRedoStack_;
-    RadiographyScene::LayerAccessor  accessor_;
-    double                           clickX_;
-    double                           clickY_;
-    double                           panX_;
-    double                           panY_;
-    bool                             oneAxis_;
-
-  public:
-    RadiographyLayerMoveTracker(UndoRedoStack& undoRedoStack,
-                                RadiographyScene& scene,
-                                size_t layer,
-                                double x,
-                                double y,
-                                bool oneAxis);
-
-    virtual bool HasRender() const
-    {
-      return false;
-    }
-
-    virtual void Render(CairoContext& context,
-                        double zoom);
-
-    virtual void MouseUp();
-
-    virtual void MouseMove(int displayX,
-                           int displayY,
-                           double sceneX,
-                           double sceneY,
-                           const std::vector<Deprecated::Touch>& displayTouches,
-                           const std::vector<Deprecated::Touch>& sceneTouches);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyLayerResizeTracker.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,188 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "RadiographyLayerResizeTracker.h"
-
-#include "RadiographySceneCommand.h"
-
-#include <OrthancException.h>
-
-#include <boost/math/special_functions/round.hpp>
-
-
-namespace OrthancStone
-{
-  static double ComputeDistance(double x1,
-                                double y1,
-                                double x2,
-                                double y2)
-  {
-    double dx = x1 - x2;
-    double dy = y1 - y2;
-    return sqrt(dx * dx + dy * dy);
-  }
-      
-
-  class RadiographyLayerResizeTracker::UndoRedoCommand : public RadiographySceneCommand
-  {
-  private:
-    double   sourceSpacingX_;
-    double   sourceSpacingY_;
-    double   sourcePanX_;
-    double   sourcePanY_;
-    double   targetSpacingX_;
-    double   targetSpacingY_;
-    double   targetPanX_;
-    double   targetPanY_;
-
-  protected:
-    virtual void UndoInternal(RadiographyLayer& layer) const
-    {
-      layer.SetPixelSpacing(sourceSpacingX_, sourceSpacingY_);
-      layer.SetPan(sourcePanX_, sourcePanY_);
-    }
-
-    virtual void RedoInternal(RadiographyLayer& layer) const
-    {
-      layer.SetPixelSpacing(targetSpacingX_, targetSpacingY_);
-      layer.SetPan(targetPanX_, targetPanY_);
-    }
-
-  public:
-    UndoRedoCommand(const RadiographyLayerResizeTracker& tracker) :
-      RadiographySceneCommand(tracker.accessor_),
-      sourceSpacingX_(tracker.originalSpacingX_),
-      sourceSpacingY_(tracker.originalSpacingY_),
-      sourcePanX_(tracker.originalPanX_),
-      sourcePanY_(tracker.originalPanY_),
-      targetSpacingX_(tracker.accessor_.GetLayer().GetGeometry().GetPixelSpacingX()),
-      targetSpacingY_(tracker.accessor_.GetLayer().GetGeometry().GetPixelSpacingY()),
-      targetPanX_(tracker.accessor_.GetLayer().GetGeometry().GetPanX()),
-      targetPanY_(tracker.accessor_.GetLayer().GetGeometry().GetPanY())
-    {
-    }
-  };
-
-
-  RadiographyLayerResizeTracker::RadiographyLayerResizeTracker(UndoRedoStack& undoRedoStack,
-                                                               RadiographyScene& scene,
-                                                               size_t layer,
-                                                               const ControlPoint& startControlPoint,
-                                                               bool roundScaling) :
-    undoRedoStack_(undoRedoStack),
-    accessor_(scene, layer),
-    roundScaling_(roundScaling)
-  {
-    if (accessor_.IsValid() &&
-        accessor_.GetLayer().GetGeometry().IsResizeable())
-    {
-      originalSpacingX_ = accessor_.GetLayer().GetGeometry().GetPixelSpacingX();
-      originalSpacingY_ = accessor_.GetLayer().GetGeometry().GetPixelSpacingY();
-      originalPanX_ = accessor_.GetLayer().GetGeometry().GetPanX();
-      originalPanY_ = accessor_.GetLayer().GetGeometry().GetPanY();
-
-      size_t oppositeControlPointType;
-      switch (startControlPoint.index)
-      {
-        case RadiographyControlPointType_TopLeftCorner:
-          oppositeControlPointType = RadiographyControlPointType_BottomRightCorner;
-          break;
-
-        case RadiographyControlPointType_TopRightCorner:
-          oppositeControlPointType = RadiographyControlPointType_BottomLeftCorner;
-          break;
-
-        case RadiographyControlPointType_BottomLeftCorner:
-          oppositeControlPointType = RadiographyControlPointType_TopRightCorner;
-          break;
-
-        case RadiographyControlPointType_BottomRightCorner:
-          oppositeControlPointType = RadiographyControlPointType_TopLeftCorner;
-          break;
-
-        default:
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-      }
-
-      accessor_.GetLayer().GetControlPoint(startOppositeControlPoint_, oppositeControlPointType);
-
-      double d = ComputeDistance(startControlPoint.x, startControlPoint.y, startOppositeControlPoint_.x, startOppositeControlPoint_.y);
-      if (d >= std::numeric_limits<float>::epsilon())
-      {
-        baseScaling_ = 1.0 / d;
-      }
-      else
-      {
-        // Avoid division by zero in extreme cases
-        accessor_.Invalidate();
-      }
-    }
-  }
-
-
-  void RadiographyLayerResizeTracker::Render(CairoContext& context,
-                                             double zoom)
-  {
-    throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-  }
-
-
-  void RadiographyLayerResizeTracker::MouseUp()
-  {
-    if (accessor_.IsValid() &&
-        accessor_.GetLayer().GetGeometry().IsResizeable())
-    {
-      undoRedoStack_.Add(new UndoRedoCommand(*this));
-    }
-  }
-
-  
-  void RadiographyLayerResizeTracker::MouseMove(int displayX,
-                                                int displayY,
-                                                double sceneX,
-                                                double sceneY,
-                                                const std::vector<Deprecated::Touch>& displayTouches,
-                                                const std::vector<Deprecated::Touch>& sceneTouches)
-  {
-    static const double ROUND_SCALING = 0.1;
-        
-    if (accessor_.IsValid() &&
-        accessor_.GetLayer().GetGeometry().IsResizeable())
-    {
-      double scaling = ComputeDistance(startOppositeControlPoint_.x, startOppositeControlPoint_.y, sceneX, sceneY) * baseScaling_;
-
-      if (roundScaling_)
-      {
-        scaling = boost::math::round<double>((scaling / ROUND_SCALING) * ROUND_SCALING);
-      }
-          
-      RadiographyLayer& layer = accessor_.GetLayer();
-      layer.SetPixelSpacing(scaling * originalSpacingX_,
-                            scaling * originalSpacingY_);
-
-      // Keep the opposite corner at a fixed location
-      ControlPoint currentOppositeCorner;
-      layer.GetControlPoint(currentOppositeCorner, startOppositeControlPoint_.index);
-      layer.SetPan(layer.GetGeometry().GetPanX() + startOppositeControlPoint_.x - currentOppositeCorner.x,
-                   layer.GetGeometry().GetPanY() + startOppositeControlPoint_.y - currentOppositeCorner.y);
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyLayerResizeTracker.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../Toolbox/UndoRedoStack.h"
-#include "../Deprecated/Widgets/IWorldSceneMouseTracker.h"
-#include "RadiographyScene.h"
-
-namespace OrthancStone
-{
-  class RadiographyLayerResizeTracker : public Deprecated::IWorldSceneMouseTracker
-  {
-  private:
-    class UndoRedoCommand;
-
-    UndoRedoStack&                   undoRedoStack_;
-    RadiographyScene::LayerAccessor  accessor_;
-    bool                             roundScaling_;
-    double                           originalSpacingX_;
-    double                           originalSpacingY_;
-    double                           originalPanX_;
-    double                           originalPanY_;
-    ControlPoint                     startOppositeControlPoint_;
-    double                           baseScaling_;
-
-  public:
-    RadiographyLayerResizeTracker(UndoRedoStack& undoRedoStack,
-                                  RadiographyScene& scene,
-                                  size_t layer,
-                                  const ControlPoint& startControlPoint,
-                                  bool roundScaling);
-
-    virtual bool HasRender() const
-    {
-      return false;
-    }
-
-    virtual void Render(CairoContext& context,
-                        double zoom);
-
-    virtual void MouseUp();
-
-    virtual void MouseMove(int displayX,
-                           int displayY,
-                           double sceneX,
-                           double sceneY,
-                           const std::vector<Deprecated::Touch>& displayTouches,
-                           const std::vector<Deprecated::Touch>& sceneTouches);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyLayerRotateTracker.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,156 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "RadiographyLayerRotateTracker.h"
-
-#include "RadiographySceneCommand.h"
-
-#include <OrthancException.h>
-
-#include <boost/math/constants/constants.hpp>
-#include <boost/math/special_functions/round.hpp>
-
-namespace OrthancStone
-{
-  class RadiographyLayerRotateTracker::UndoRedoCommand : public RadiographySceneCommand
-  {
-  private:
-    double  sourceAngle_;
-    double  targetAngle_;
-
-    static int ToDegrees(double angle)
-    {
-      return boost::math::iround(angle * 180.0 / boost::math::constants::pi<double>());
-    }
-      
-  protected:
-    virtual void UndoInternal(RadiographyLayer& layer) const
-    {
-      LOG(INFO) << "Undo - Set angle to " << ToDegrees(sourceAngle_) << " degrees";
-      layer.SetAngle(sourceAngle_);
-    }
-
-    virtual void RedoInternal(RadiographyLayer& layer) const
-    {
-      LOG(INFO) << "Redo - Set angle to " << ToDegrees(sourceAngle_) << " degrees";
-      layer.SetAngle(targetAngle_);
-    }
-
-  public:
-    UndoRedoCommand(const RadiographyLayerRotateTracker& tracker) :
-      RadiographySceneCommand(tracker.accessor_),
-      sourceAngle_(tracker.originalAngle_),
-      targetAngle_(tracker.accessor_.GetLayer().GetGeometry().GetAngle())
-    {
-    }
-  };
-
-
-  bool RadiographyLayerRotateTracker::ComputeAngle(double& angle /* out */,
-                                                   double sceneX,
-                                                   double sceneY) const
-  {
-    Vector u;
-    LinearAlgebra::AssignVector(u, sceneX - centerX_, sceneY - centerY_);
-
-    double nu = boost::numeric::ublas::norm_2(u);
-
-    if (!LinearAlgebra::IsCloseToZero(nu))
-    {
-      u /= nu;
-      angle = atan2(u[1], u[0]);
-      return true;
-    }
-    else
-    {
-      return false;
-    }
-  }
-
-
-  RadiographyLayerRotateTracker::RadiographyLayerRotateTracker(UndoRedoStack& undoRedoStack,
-                                                               RadiographyScene& scene,
-                                                               const Deprecated::ViewportGeometry& view,
-                                                               size_t layer,
-                                                               double x,
-                                                               double y,
-                                                               bool roundAngles) :
-    undoRedoStack_(undoRedoStack),
-    accessor_(scene, layer),
-    roundAngles_(roundAngles)
-  {
-    if (accessor_.IsValid())
-    {
-      accessor_.GetLayer().GetCenter(centerX_, centerY_);
-      originalAngle_ = accessor_.GetLayer().GetGeometry().GetAngle();
-
-      double sceneX, sceneY;
-      view.MapDisplayToScene(sceneX, sceneY, x, y);
-
-      if (!ComputeAngle(clickAngle_, x, y))
-      {
-        accessor_.Invalidate();
-      }
-    }
-  }
-
-
-  void RadiographyLayerRotateTracker::Render(CairoContext& context,
-                                             double zoom)
-  {
-    throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-  }
-
-
-  void RadiographyLayerRotateTracker::MouseUp()
-  {
-    if (accessor_.IsValid())
-    {
-      undoRedoStack_.Add(new UndoRedoCommand(*this));
-    }
-  }
-
-  
-  void RadiographyLayerRotateTracker::MouseMove(int displayX,
-                                                int displayY,
-                                                double sceneX,
-                                                double sceneY,
-                                                const std::vector<Deprecated::Touch>& displayTouches,
-                                                const std::vector<Deprecated::Touch>& sceneTouches)
-  {
-    static const double ROUND_ANGLE = 15.0 / 180.0 * boost::math::constants::pi<double>(); 
-        
-    double angle;
-        
-    if (accessor_.IsValid() &&
-        ComputeAngle(angle, sceneX, sceneY))
-    {
-      angle = angle - clickAngle_ + originalAngle_;
-
-      if (roundAngles_)
-      {
-        angle = boost::math::round<double>((angle / ROUND_ANGLE) * ROUND_ANGLE);
-      }
-          
-      accessor_.GetLayer().SetAngle(angle);
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyLayerRotateTracker.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../Toolbox/UndoRedoStack.h"
-#include "../Deprecated/Toolbox/ViewportGeometry.h"
-#include "../Deprecated/Widgets/IWorldSceneMouseTracker.h"
-#include "RadiographyScene.h"
-
-
-namespace OrthancStone
-{
-  class RadiographyLayerRotateTracker : public Deprecated::IWorldSceneMouseTracker
-  {
-  private:
-    class UndoRedoCommand;
-
-    UndoRedoStack&                   undoRedoStack_;
-    RadiographyScene::LayerAccessor  accessor_;
-    double                           centerX_;
-    double                           centerY_;
-    double                           originalAngle_;
-    double                           clickAngle_;
-    bool                             roundAngles_;
-
-    bool ComputeAngle(double& angle /* out */,
-                      double sceneX,
-                      double sceneY) const;
-
-  public:
-    RadiographyLayerRotateTracker(UndoRedoStack& undoRedoStack,
-                                  RadiographyScene& scene,
-                                  const Deprecated::ViewportGeometry& view,
-                                  size_t layer,
-                                  double x,
-                                  double y,
-                                  bool roundAngles);
-
-    virtual bool HasRender() const
-    {
-      return false;
-    }
-
-    virtual void Render(CairoContext& context,
-                        double zoom);
-
-    virtual void MouseUp();
-
-    virtual void MouseMove(int displayX,
-                           int displayY,
-                           double sceneX,
-                           double sceneY,
-                           const std::vector<Deprecated::Touch>& displayTouches,
-                           const std::vector<Deprecated::Touch>& sceneTouches);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyMaskLayer.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,200 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "RadiographyMaskLayer.h"
-#include "RadiographyDicomLayer.h"
-
-#include "RadiographyScene.h"
-#include "../Toolbox/ImageGeometry.h"
-
-#include <Images/Image.h>
-#include <Images/ImageProcessing.h>
-#include <OrthancException.h>
-
-namespace OrthancStone
-{
-  const unsigned char IN_MASK_VALUE = 0x77;
-  const unsigned char OUT_MASK_VALUE = 0xFF;
-
-  const AffineTransform2D& RadiographyMaskLayer::GetTransform() const
-  {
-    return dicomLayer_.GetTransform();
-  }
-
-  const AffineTransform2D& RadiographyMaskLayer::GetTransformInverse() const
-  {
-    return dicomLayer_.GetTransformInverse();
-  }
-
-  bool RadiographyMaskLayer::GetPixel(unsigned int& imageX,
-                        unsigned int& imageY,
-                        double sceneX,
-                        double sceneY) const
-  {
-    return dicomLayer_.GetPixel(imageX, imageY, sceneX, sceneY);
-  }
-
-  std::string RadiographyMaskLayer::GetInstanceId() const
-  {
-    return dicomLayer_.GetInstanceId();
-  }
-
-  void RadiographyMaskLayer::SetCorner(const Orthanc::ImageProcessing::ImagePoint& corner, size_t index)
-  {
-    if (index < corners_.size())
-      corners_[index] = corner;
-    else
-      corners_.push_back(corner);
-    invalidated_ = true;
-
-    BroadcastMessage(RadiographyLayer::LayerEditedMessage(*this));
-  }
-
-  void RadiographyMaskLayer::SetCorners(const std::vector<Orthanc::ImageProcessing::ImagePoint>& corners)
-  {
-    corners_ = corners;
-    invalidated_ = true;
-
-    BroadcastMessage(RadiographyLayer::LayerEditedMessage(*this));
-  }
-
-  Extent2D RadiographyMaskLayer::GetSceneExtent(bool minimal) const
-  {
-    if (!minimal)
-    {
-      return RadiographyLayer::GetSceneExtent(minimal);
-    }
-    else
-    { // get the extent of the in-mask area
-      Extent2D sceneExtent;
-
-      for (std::vector<Orthanc::ImageProcessing::ImagePoint>::const_iterator corner = corners_.begin(); corner != corners_.end(); ++corner)
-      {
-        double x = static_cast<double>(corner->GetX());
-        double y = static_cast<double>(corner->GetY());
-
-        dicomLayer_.GetTransform().Apply(x, y);
-        sceneExtent.AddPoint(x, y);
-      }
-      return sceneExtent;
-    }
-  }
-
-
-
-  void RadiographyMaskLayer::Render(Orthanc::ImageAccessor& buffer,
-                                    const AffineTransform2D& viewTransform,
-                                    ImageInterpolation interpolation,
-                                    float windowCenter,
-                                    float windowWidth,
-                                    bool applyWindowing) const
-  {
-    if (dicomLayer_.GetWidth() == 0 || dicomLayer_.GetSourceImage() == NULL) // nothing to do if the DICOM layer is not displayed (or not loaded)
-      return;
-
-    if (invalidated_)
-    {
-      mask_.reset(new Orthanc::Image(Orthanc::PixelFormat_Grayscale8, dicomLayer_.GetWidth(), dicomLayer_.GetHeight(), false));
-
-      DrawMask();
-
-      invalidated_ = false;
-    }
-
-    {// rendering
-      if (buffer.GetFormat() != Orthanc::PixelFormat_Float32)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat);
-      }
-
-      unsigned int cropX, cropY, cropWidth, cropHeight;
-      dicomLayer_.GetCrop(cropX, cropY, cropWidth, cropHeight);
-
-      const AffineTransform2D t = AffineTransform2D::Combine(
-            viewTransform, dicomLayer_.GetTransform(),
-            AffineTransform2D::CreateOffset(cropX, cropY));
-
-      Orthanc::ImageAccessor cropped;
-      mask_->GetRegion(cropped, cropX, cropY, cropWidth, cropHeight);
-
-      Orthanc::Image tmp(Orthanc::PixelFormat_Grayscale8, buffer.GetWidth(), buffer.GetHeight(), false);
-
-
-      unsigned int x1, y1, x2, y2;
-      if (!OrthancStone::GetProjectiveTransformExtent(x1, y1, x2, y2,
-                                                      t.GetHomogeneousMatrix(),
-                                                      cropped.GetWidth(),
-                                                      cropped.GetHeight(),
-                                                      buffer.GetWidth(),
-                                                      buffer.GetHeight()))
-      {
-        return;  // layer is outside the buffer
-      }
-
-      t.Apply(tmp, cropped, ImageInterpolation_Nearest, true /* clear */);
-
-      // we have observed vertical lines at the image border (probably due to bilinear filtering of the DICOM image when it is not aligned with the buffer pixels)
-      // -> draw the mask one line further on each side
-      if (x1 >= 1)
-      {
-        x1 = x1 - 1;
-      }
-      if (x2 < buffer.GetWidth() - 2)
-      {
-        x2 = x2 + 1;
-      }
-
-      // Blit
-      for (unsigned int y = y1; y <= y2; y++)
-      {
-        float *q = reinterpret_cast<float*>(buffer.GetRow(y)) + x1;
-        const uint8_t *p = reinterpret_cast<uint8_t*>(tmp.GetRow(y)) + x1;
-
-        for (unsigned int x = x1; x <= x2; x++, p++, q++)
-        {
-          if (*p != IN_MASK_VALUE)
-            *q = foreground_;
-          // else keep the underlying pixel value
-        }
-      }
-
-    }
-  }
-
-  void RadiographyMaskLayer::DrawMask() const
-  {
-    // first fill the complete image
-    Orthanc::ImageProcessing::Set(*mask_, OUT_MASK_VALUE);
-
-    // clip corners
-    std::vector<Orthanc::ImageProcessing::ImagePoint> clippedCorners;
-    for (size_t i = 0; i < corners_.size(); i++)
-    {
-      clippedCorners.push_back(corners_[i]);
-      clippedCorners[i].ClipTo(0, mask_->GetWidth() - 1, 0, mask_->GetHeight() - 1);
-    }
-
-    // fill mask
-    Orthanc::ImageProcessing::FillPolygon(*mask_, clippedCorners, IN_MASK_VALUE);
-
-  }
-
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyMaskLayer.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,146 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "RadiographyLayer.h"
-
-#include <Compatibility.h>
-#include <Images/Image.h>
-#include <Images/ImageProcessing.h>
-
-namespace OrthancStone
-{
-  class RadiographyScene;
-  class RadiographyDicomLayer;
-
-  class RadiographyMaskLayer : public RadiographyLayer
-  {
-  private:
-    std::vector<Orthanc::ImageProcessing::ImagePoint>            corners_;
-    const RadiographyDicomLayer&      dicomLayer_;
-    mutable bool                      invalidated_;
-    float                             foreground_;
-
-    mutable std::unique_ptr<Orthanc::ImageAccessor>  mask_;
-  public:
-    RadiographyMaskLayer(const RadiographyScene& scene, const RadiographyDicomLayer& dicomLayer,
-                         float foreground) :
-      RadiographyLayer(scene),
-      dicomLayer_(dicomLayer),
-      invalidated_(true),
-      foreground_(foreground)
-    {
-    }
-
-    virtual size_t GetApproximateMemoryUsage() const
-    {
-      size_t size = 0;
-      if (mask_.get() != NULL)
-      {
-        size += mask_->GetPitch() * mask_->GetHeight();
-      }
-
-      return size;
-    }
-
-
-    void SetCorners(const std::vector<Orthanc::ImageProcessing::ImagePoint>& corners);
-    void SetCorner(const Orthanc::ImageProcessing::ImagePoint& corner, size_t index);
-
-    const std::vector<Orthanc::ImageProcessing::ImagePoint>& GetCorners() const
-    {
-      return corners_;
-    }
-
-    float GetForeground() const
-    {
-      return foreground_;
-    }
-
-    virtual void Render(Orthanc::ImageAccessor& buffer,
-                        const AffineTransform2D& viewTransform,
-                        ImageInterpolation interpolation,
-                        float windowCenter,
-                        float windowWidth,
-                        bool applyWindowing) const;
-
-    std::string GetInstanceId() const;
-
-    virtual size_t GetControlPointCount() const
-    {
-      return corners_.size();
-    }
-
-    virtual void GetControlPoint(ControlPoint& cpScene,
-                                         size_t index) const
-    {
-      ControlPoint cp(corners_[index].GetX(), corners_[index].GetY(), index);
-
-      // transforms image coordinates into scene coordinates
-      GetTransform().Apply(cp.x, cp.y);
-      cpScene = cp;
-    }
-
-    virtual Extent2D GetSceneExtent(bool minimal) const;
-
-    virtual bool GetDefaultWindowing(float& center,
-                                     float& width) const
-    {
-      return false;
-    }
-
-    virtual bool GetRange(float& minValue,
-                          float& maxValue) const
-    {
-      minValue = 0;
-      maxValue = 0;
-
-      if (foreground_ < 0)
-      {
-        minValue = foreground_;
-      }
-
-      if (foreground_ > 0)
-      {
-        maxValue = foreground_;
-      }
-
-      return true;
-
-    }
-
-    virtual bool GetPixel(unsigned int& imageX,
-                          unsigned int& imageY,
-                          double sceneX,
-                          double sceneY) const;
-
-  protected:
-    virtual const AffineTransform2D& GetTransform() const;
-
-    virtual const AffineTransform2D& GetTransformInverse() const;
-
-
-  private:
-    void DrawMask() const;
-
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyScene.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,968 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "RadiographyScene.h"
-
-#include "RadiographyAlphaLayer.h"
-#include "RadiographyDicomLayer.h"
-#include "RadiographyTextLayer.h"
-#include "RadiographyMaskLayer.h"
-#include "../Deprecated/Toolbox/DicomFrameConverter.h"
-#include "../Scene2D/CairoCompositor.h"
-#include "../Scene2D/FloatTextureSceneLayer.h"
-#include "../Scene2D/TextSceneLayer.h"
-
-#include <Images/Image.h>
-#include <Images/ImageProcessing.h>
-#include <Images/PamReader.h>
-#include <Images/PamWriter.h>
-#include <Images/PngWriter.h>
-#include <OrthancException.h>
-#include <Toolbox.h>
-#include <DicomDatasetReader.h>
-#include <FullOrthancDataset.h>
-
-#include <boost/math/special_functions/round.hpp>
-
-
-namespace OrthancStone
-{
-  RadiographyScene::LayerAccessor::LayerAccessor(RadiographyScene& scene,
-                                                 size_t index) :
-    scene_(scene),
-    index_(index)
-  {
-    Layers::iterator layer = scene.layers_.find(index);
-    if (layer == scene.layers_.end())
-    {
-      layer_ = NULL;
-    }
-    else
-    {
-      assert(layer->second != NULL);
-      layer_ = layer->second;
-    }
-  }
-
-
-  RadiographyScene::LayerAccessor::LayerAccessor(RadiographyScene& scene,
-                                                 double x,
-                                                 double y) :
-    scene_(scene),
-    index_(0)  // Dummy initialization
-  {
-    if (scene.LookupLayer(index_, x, y))
-    {
-      Layers::iterator layer = scene.layers_.find(index_);
-
-      if (layer == scene.layers_.end())
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-      }
-      else
-      {
-        assert(layer->second != NULL);
-        layer_ = layer->second;
-      }
-    }
-    else
-    {
-      layer_ = NULL;
-    }
-  }
-
-
-  RadiographyScene& RadiographyScene::LayerAccessor::GetScene() const
-  {
-    if (IsValid())
-    {
-      return scene_;
-    }
-    else
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-  }
-
-
-  size_t RadiographyScene::LayerAccessor::GetIndex() const
-  {
-    if (IsValid())
-    {
-      return index_;
-    }
-    else
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-  }
-
-  
-  RadiographyLayer& RadiographyScene::LayerAccessor::GetLayer() const
-  {
-    if (IsValid())
-    {
-      return *layer_;
-    }
-    else
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-  }
-
-  void RadiographyScene::_RegisterLayer(RadiographyLayer* layer)
-  {
-    std::unique_ptr<RadiographyLayer> raii(layer);
-
-    // LOG(INFO) << "Registering layer: " << countLayers_;
-
-    size_t index = nextLayerIndex_++;
-    raii->SetIndex(index);
-    layers_[index] = raii.release();
-  }
-
-  RadiographyLayer& RadiographyScene::RegisterLayer(RadiographyLayer* layer)
-  {
-    if (layer == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
-    }
-
-    _RegisterLayer(layer);
-
-    BroadcastMessage(GeometryChangedMessage(*this, *layer));
-    BroadcastMessage(ContentChangedMessage(*this, *layer));
-    Register<RadiographyLayer::LayerEditedMessage>(*layer, &RadiographyScene::OnLayerEdited);
-
-    return *layer;
-  }
-
-  size_t RadiographyScene::GetApproximateMemoryUsage() const
-  {
-    size_t size = 0;
-    for (Layers::const_iterator it = layers_.begin(); it != layers_.end(); it++)
-    {
-      size += it->second->GetApproximateMemoryUsage();
-    }
-    return size;
-  }
-
-  void RadiographyScene::OnLayerEdited(const RadiographyLayer::LayerEditedMessage& message)
-  {
-    BroadcastMessage(RadiographyScene::LayerEditedMessage(*this, message.GetOrigin()));
-  }
-
-  
-  RadiographyScene::RadiographyScene() :
-    nextLayerIndex_(0),
-    hasWindowing_(false),
-    windowingCenter_(0),  // Dummy initialization
-    windowingWidth_(0)    // Dummy initialization
-  {
-  }
-
-
-  RadiographyScene::~RadiographyScene()
-  {
-    for (Layers::iterator it = layers_.begin(); it != layers_.end(); it++)
-    {
-      assert(it->second != NULL);
-      delete it->second;
-    }
-  }
-
-  RadiographyPhotometricDisplayMode RadiographyScene::GetPreferredPhotomotricDisplayMode() const
-  {
-    // return the mode of the first layer who "cares" about its display mode (normaly, the one and only layer that is a DicomLayer)
-    for (Layers::const_iterator it = layers_.begin(); it != layers_.end(); it++)
-    {
-      if (it->second->GetPreferredPhotomotricDisplayMode() != RadiographyPhotometricDisplayMode_Default)
-      {
-        return it->second->GetPreferredPhotomotricDisplayMode();
-      }
-    }
-
-    return RadiographyPhotometricDisplayMode_Default;
-  }
-
-
-  void RadiographyScene::GetLayersIndexes(std::vector<size_t>& output) const
-  {
-    for (Layers::const_iterator it = layers_.begin(); it != layers_.end(); it++)
-    {
-      output.push_back(it->first);
-    }
-  }
-
-  void RadiographyScene::RemoveLayer(size_t layerIndex)
-  {
-    LOG(INFO) << "Removing layer: " << layerIndex;
-
-    Layers::iterator found = layers_.find(layerIndex);
-
-    if (found == layers_.end())
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-    else
-    {
-      assert(found->second != NULL);
-      delete found->second;
-      
-      layers_.erase(found);
-      
-      LOG(INFO) << "Removing layer, there are now : " << layers_.size() << " layers";
-
-      _OnLayerRemoved();
-
-      BroadcastMessage(RadiographyScene::LayerRemovedMessage(*this, layerIndex));
-    }
-  }
-
-  const RadiographyLayer& RadiographyScene::GetLayer(size_t layerIndex) const
-  {
-    Layers::const_iterator found = layers_.find(layerIndex);
-    
-    if (found == layers_.end())
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-    else
-    {
-      assert(found->second != NULL);
-      return *found->second;
-    }
-  }
-
-  RadiographyLayer& RadiographyScene::GetLayer(size_t layerIndex)
-  {
-    Layers::const_iterator found = layers_.find(layerIndex);
-
-    if (found == layers_.end())
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-    else
-    {
-      assert(found->second != NULL);
-      return *found->second;
-    }
-  }
-
-  bool RadiographyScene::GetWindowing(float& center,
-                                      float& width) const
-  {
-    if (hasWindowing_)
-    {
-      center = windowingCenter_;
-      width = windowingWidth_;
-      return true;
-    }
-    else
-    {
-      return false;
-    }
-  }
-
-
-  void RadiographyScene::GetWindowingWithDefault(float& center,
-                                                 float& width) const
-  {
-    if (!GetWindowing(center, width))
-    {
-      center = 128;
-      width = 256;
-    }
-  }
-
-
-  void RadiographyScene::SetWindowing(float center,
-                                      float width)
-  {
-    hasWindowing_ = true;
-    windowingCenter_ = center;
-    windowingWidth_ = width;
-
-    BroadcastMessage(RadiographyScene::WindowingChangedMessage(*this));
-  }
-
-
-  RadiographyLayer& RadiographyScene::UpdateText(size_t layerIndex,
-                                                 const std::string& utf8,
-                                                 const std::string& font,
-                                                 unsigned int fontSize,
-                                                 uint8_t foreground)
-  {
-    RadiographyTextLayer& textLayer = dynamic_cast<RadiographyTextLayer&>(GetLayer(layerIndex));
-    textLayer.SetText(utf8, font, fontSize, foreground);
-
-    BroadcastMessage(RadiographyScene::ContentChangedMessage(*this, textLayer));
-    BroadcastMessage(RadiographyScene::LayerEditedMessage(*this, textLayer));
-    return textLayer;
-  }
-
-
-  RadiographyLayer& RadiographyScene::LoadText(const std::string& utf8,
-                                               const std::string& font,
-                                               unsigned int fontSize,
-                                               uint8_t foreground,
-                                               RadiographyLayer::Geometry* centerGeometry,
-                                               bool isCenterGeometry)
-  {
-    std::unique_ptr<RadiographyTextLayer>  alpha(new RadiographyTextLayer(*this));
-    alpha->SetText(utf8, font, fontSize, foreground);
-    if (centerGeometry != NULL)
-    {
-      if (isCenterGeometry)
-      {
-        // modify geometry to reference the top left corner
-        double tlx = centerGeometry->GetPanX();
-        double tly = centerGeometry->GetPanY();
-        Extent2D textExtent = alpha->GetSceneExtent(false);
-        tlx = tlx - (textExtent.GetWidth() / 2) * centerGeometry->GetPixelSpacingX();
-        tly = tly - (textExtent.GetHeight() / 2) * centerGeometry->GetPixelSpacingY();
-        centerGeometry->SetPan(tlx, tly);
-      }
-      alpha->SetGeometry(*centerGeometry);
-    }
-
-    RadiographyLayer& registeredLayer = RegisterLayer(alpha.release());
-
-    BroadcastMessage(RadiographyScene::LayerEditedMessage(*this, registeredLayer));
-    return registeredLayer;
-  }
-
-
-  RadiographyLayer& RadiographyScene::LoadTestBlock(unsigned int width,
-                                                    unsigned int height,
-                                                    RadiographyLayer::Geometry* geometry)
-  {
-    std::unique_ptr<Orthanc::Image>  block(new Orthanc::Image(Orthanc::PixelFormat_Grayscale8, width, height, false));
-
-    for (unsigned int padding = 0;
-         (width > 2 * padding) && (height > 2 * padding);
-         padding++)
-    {
-      uint8_t color;
-      if (255 > 10 * padding)
-      {
-        color = 255 - 10 * padding;
-      }
-      else
-      {
-        color = 0;
-      }
-
-      Orthanc::ImageAccessor region;
-      block->GetRegion(region, padding, padding, width - 2 * padding, height - 2 * padding);
-      Orthanc::ImageProcessing::Set(region, color);
-    }
-
-    return LoadAlphaBitmap(block.release(), geometry);
-  }
-
-  RadiographyLayer& RadiographyScene::LoadMask(const std::vector<Orthanc::ImageProcessing::ImagePoint>& corners,
-                                               const RadiographyDicomLayer& dicomLayer,
-                                               float foreground,
-                                               RadiographyLayer::Geometry* geometry)
-  {
-    std::unique_ptr<RadiographyMaskLayer>  mask(new RadiographyMaskLayer(*this, dicomLayer, foreground));
-    mask->SetCorners(corners);
-    if (geometry != NULL)
-    {
-      mask->SetGeometry(*geometry);
-    }
-
-    return RegisterLayer(mask.release());
-  }
-
-
-  RadiographyLayer& RadiographyScene::LoadAlphaBitmap(Orthanc::ImageAccessor* bitmap, RadiographyLayer::Geometry *geometry)
-  {
-    std::unique_ptr<RadiographyAlphaLayer>  alpha(new RadiographyAlphaLayer(*this));
-    alpha->SetAlpha(bitmap);
-    if (geometry != NULL)
-    {
-      alpha->SetGeometry(*geometry);
-    }
-
-    return RegisterLayer(alpha.release());
-  }
-
-  RadiographyLayer& RadiographyScene::LoadDicomImage(Orthanc::ImageAccessor* dicomImage, // takes ownership
-                                                     const std::string& instance,
-                                                     unsigned int frame,
-                                                     Deprecated::DicomFrameConverter* converter,  // takes ownership
-                                                     RadiographyPhotometricDisplayMode preferredPhotometricDisplayMode,
-                                                     RadiographyLayer::Geometry* geometry)
-  {
-    RadiographyDicomLayer& layer = dynamic_cast<RadiographyDicomLayer&>(RegisterLayer(new RadiographyDicomLayer(*this)));
-
-    layer.SetInstance(instance, frame);
-
-    if (geometry != NULL)
-    {
-      layer.SetGeometry(*geometry);
-    }
-
-    layer.SetDicomFrameConverter(converter);
-    layer.SetSourceImage(dicomImage);
-    layer.SetPreferredPhotomotricDisplayMode(preferredPhotometricDisplayMode);
-
-    return layer;
-  }
-
-  RadiographyLayer& RadiographyScene::LoadDicomFrame(Deprecated::OrthancApiClient& orthanc,
-                                                     const std::string& instance,
-                                                     unsigned int frame,
-                                                     bool httpCompression,
-                                                     RadiographyLayer::Geometry* geometry)
-  {
-    RadiographyDicomLayer& layer = dynamic_cast<RadiographyDicomLayer&>(RegisterLayer(new RadiographyDicomLayer( *this)));
-    layer.SetInstance(instance, frame);
-
-    if (geometry != NULL)
-    {
-      layer.SetGeometry(*geometry);
-    }
-
-    {
-      Deprecated::IWebService::HttpHeaders headers;
-      std::string uri = "/instances/" + instance + "/tags";
-
-      orthanc.GetBinaryAsync(
-            uri, headers,
-            new Deprecated::DeprecatedCallable<RadiographyScene, Deprecated::OrthancApiClient::BinaryResponseReadyMessage>
-            (GetSharedObserver(), &RadiographyScene::OnTagsReceived), NULL,
-            new Orthanc::SingleValueObject<size_t>(layer.GetIndex()));
-    }
-
-    {
-      Deprecated::IWebService::HttpHeaders headers;
-      headers["Accept"] = "image/x-portable-arbitrarymap";
-
-      if (httpCompression)
-      {
-        headers["Accept-Encoding"] = "gzip";
-      }
-
-      std::string uri = ("/instances/" + instance + "/frames/" +
-                         boost::lexical_cast<std::string>(frame) + "/image-uint16");
-
-      orthanc.GetBinaryAsync(
-            uri, headers,
-            new Deprecated::DeprecatedCallable<RadiographyScene, Deprecated::OrthancApiClient::BinaryResponseReadyMessage>
-            (GetSharedObserver(), &RadiographyScene::OnFrameReceived), NULL,
-            new Orthanc::SingleValueObject<size_t>(layer.GetIndex()));
-    }
-
-    return layer;
-  }
-
-
-  RadiographyLayer& RadiographyScene::LoadDicomWebFrame(Deprecated::IWebService& web)
-  {
-    RadiographyLayer& layer = RegisterLayer(new RadiographyDicomLayer(*this));
-
-
-    return layer;
-  }
-
-
-
-  void RadiographyScene::OnTagsReceived(const Deprecated::OrthancApiClient::BinaryResponseReadyMessage& message)
-  {
-    size_t index = dynamic_cast<const Orthanc::SingleValueObject<size_t>&>
-        (message.GetPayload()).GetValue();
-
-    VLOG(1) << "JSON received: " << message.GetUri().c_str()
-            << " (" << message.GetAnswerSize() << " bytes) for layer " << index;
-
-    Layers::iterator layer = layers_.find(index);
-    if (layer != layers_.end())
-    {
-      assert(layer->second != NULL);
-
-      OrthancPlugins::FullOrthancDataset dicom(message.GetAnswer(), message.GetAnswerSize());
-      dynamic_cast<RadiographyDicomLayer*>(layer->second)->SetDicomTags(dicom);
-
-      float c, w;
-      if (!hasWindowing_ &&
-          layer->second->GetDefaultWindowing(c, w))
-      {
-        hasWindowing_ = true;
-        windowingCenter_ = c;
-        windowingWidth_ = w;
-      }
-
-      BroadcastMessage(GeometryChangedMessage(*this, *(layer->second)));
-    }
-  }
-
-
-  void RadiographyScene::OnFrameReceived(const Deprecated::OrthancApiClient::BinaryResponseReadyMessage& message)
-  {
-    size_t index = dynamic_cast<const Orthanc::SingleValueObject<size_t>&>(message.GetPayload()).GetValue();
-
-    VLOG(1) << "DICOM frame received: " << message.GetUri().c_str()
-            << " (" << message.GetAnswerSize() << " bytes) for layer " << index;
-
-    Layers::iterator layer = layers_.find(index);
-    if (layer != layers_.end())
-    {
-      assert(layer->second != NULL);
-
-      std::string content;
-      if (message.GetAnswerSize() > 0)
-      {
-        content.assign(reinterpret_cast<const char*>(message.GetAnswer()), message.GetAnswerSize());
-      }
-
-      std::unique_ptr<Orthanc::PamReader> reader(new Orthanc::PamReader);
-      reader->ReadFromMemory(content);
-      dynamic_cast<RadiographyDicomLayer*>(layer->second)->SetSourceImage(reader.release());
-
-      BroadcastMessage(ContentChangedMessage(*this, *(layer->second)));
-    }
-  }
-
-
-  Extent2D RadiographyScene::GetSceneExtent(bool minimal) const
-  {
-    Extent2D extent;
-
-    for (Layers::const_iterator it = layers_.begin();
-         it != layers_.end(); ++it)
-    {
-      assert(it->second != NULL);
-      extent.Union(it->second->GetSceneExtent(minimal));
-    }
-
-    return extent;
-  }
-
-
-  void RadiographyScene::Render(Orthanc::ImageAccessor& buffer,
-                                const AffineTransform2D& viewTransform,
-                                ImageInterpolation interpolation,
-                                bool applyWindowing) const
-  {
-    // Render layers in the background-to-foreground order
-    for (size_t index = 0; index < nextLayerIndex_; index++)
-    {
-      try
-      {
-        Layers::const_iterator it = layers_.find(index);
-        if (it != layers_.end())
-        {
-          assert(it->second != NULL);
-          it->second->Render(buffer, viewTransform, interpolation, windowingCenter_, windowingWidth_, applyWindowing);
-        }
-      }
-      catch (Orthanc::OrthancException& ex)
-      {
-        LOG(ERROR) << "RadiographyScene::Render: " << index << ", OrthancException: " << ex.GetDetails();
-        throw ex; // rethrow because we want it to crash to see there's a problem !
-      }
-      catch (...)
-      {
-        LOG(ERROR) << "RadiographyScene::Render: " << index << ", unkown exception: ";
-        throw; // rethrow because we want it to crash to see there's a problem !
-      }
-    }
-  }
-
-
-  bool RadiographyScene::LookupLayer(size_t& index /* out */,
-                                     double x,
-                                     double y) const
-  {
-    // Render layers in the foreground-to-background order
-    for (size_t i = nextLayerIndex_; i > 0; i--)
-    {
-      index = i - 1;
-      Layers::const_iterator it = layers_.find(index);
-      if (it != layers_.end())
-      {
-        assert(it->second != NULL);
-        if (it->second->Contains(x, y))
-        {
-          return true;
-        }
-      }
-    }
-
-    return false;
-  }
-
-
-  void RadiographyScene::DrawBorder(CairoContext& context,
-                                    unsigned int layer,
-                                    double zoom)
-  {
-    Layers::const_iterator found = layers_.find(layer);
-
-    if (found != layers_.end())
-    {
-      context.SetSourceColor(255, 0, 0);
-      found->second->DrawBorders(context, zoom);
-    }
-  }
-
-
-  void RadiographyScene::GetRange(float& minValue,
-                                  float& maxValue) const
-  {
-    bool first = true;
-
-    for (Layers::const_iterator it = layers_.begin();
-         it != layers_.end(); it++)
-    {
-      assert(it->second != NULL);
-
-      float a, b;
-      if (it->second->GetRange(a, b))
-      {
-        if (first)
-        {
-          minValue = a;
-          maxValue = b;
-          first = false;
-        }
-        else
-        {
-          minValue = std::min(a, minValue);
-          maxValue = std::max(b, maxValue);
-        }
-      }
-    }
-
-    if (first)
-    {
-      minValue = 0;
-      maxValue = 0;
-    }
-  }
-
-  void RadiographyScene::ExtractLayerFromRenderedScene(Orthanc::ImageAccessor& layer,
-                                                       const Orthanc::ImageAccessor& renderedScene,
-                                                       size_t layerIndex,
-                                                       bool isCropped,
-                                                       ImageInterpolation interpolation)
-  {
-    Extent2D sceneExtent = GetSceneExtent(isCropped);
-
-    double pixelSpacingX = sceneExtent.GetWidth() / renderedScene.GetWidth();
-    double pixelSpacingY = sceneExtent.GetHeight() / renderedScene.GetHeight();
-
-    AffineTransform2D view = AffineTransform2D::Combine(
-          AffineTransform2D::CreateScaling(1.0 / pixelSpacingX, 1.0 / pixelSpacingY),
-          AffineTransform2D::CreateOffset(-sceneExtent.GetX1(), -sceneExtent.GetY1()));
-
-    AffineTransform2D layerToSceneTransform = AffineTransform2D::Combine(
-          view,
-          GetLayer(layerIndex).GetTransform());
-
-    AffineTransform2D sceneToLayerTransform = AffineTransform2D::Invert(layerToSceneTransform);
-    sceneToLayerTransform.Apply(layer, renderedScene, interpolation, false);
-  }
-
-  Orthanc::Image* RadiographyScene::ExportToImage(double pixelSpacingX,
-                                                  double pixelSpacingY,
-                                                  ImageInterpolation interpolation,
-                                                  bool invert,
-                                                  int64_t maxValue /* for inversion */,
-                                                  bool autoCrop,
-                                                  bool applyWindowing)
-  {
-    if (pixelSpacingX <= 0 ||
-        pixelSpacingY <= 0)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    Extent2D extent = GetSceneExtent(autoCrop);
-
-    int w = boost::math::iround(extent.GetWidth() / pixelSpacingX);
-    int h = boost::math::iround(extent.GetHeight() / pixelSpacingY);
-
-    if (w < 0 || h < 0)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-    }
-
-    Orthanc::Image layers(Orthanc::PixelFormat_Float32,
-                          static_cast<unsigned int>(w),
-                          static_cast<unsigned int>(h), false);
-
-    AffineTransform2D view = AffineTransform2D::Combine(
-          AffineTransform2D::CreateScaling(1.0 / pixelSpacingX, 1.0 / pixelSpacingY),
-          AffineTransform2D::CreateOffset(-extent.GetX1(), -extent.GetY1()));
-
-    // wipe background before rendering
-    if (GetPreferredPhotomotricDisplayMode() == RadiographyPhotometricDisplayMode_Monochrome1)
-    {
-      Orthanc::ImageProcessing::Set(layers, 65535);
-    }
-    else
-    {
-      Orthanc::ImageProcessing::Set(layers, 0);
-    }
-
-    Render(layers, view, interpolation, applyWindowing);
-
-    std::unique_ptr<Orthanc::Image> rendered(new Orthanc::Image(Orthanc::PixelFormat_Grayscale16,
-                                                              layers.GetWidth(), layers.GetHeight(), false));
-
-    Orthanc::ImageProcessing::Convert(*rendered, layers);
-    if (invert)
-      Orthanc::ImageProcessing::Invert(*rendered, maxValue);
-
-    return rendered.release();
-  }
-
-
-  Orthanc::Image* RadiographyScene::ExportToCreateDicomRequestAndImage(Json::Value& createDicomRequestContent,
-                                                                       const Json::Value& dicomTags,
-                                                                       const std::string& parentOrthancId,
-                                                                       double pixelSpacingX,
-                                                                       double pixelSpacingY,
-                                                                       bool invert,
-                                                                       bool autoCrop,
-                                                                       ImageInterpolation interpolation)
-  {
-    LOG(INFO) << "Exporting RadiographyScene to DICOM";
-
-    std::unique_ptr<Orthanc::Image> rendered(ExportToImage(pixelSpacingX, pixelSpacingY, interpolation, autoCrop, false)); // note: we don't invert the image in the pixels data because we'll set the PhotometricDisplayMode correctly in the DICOM tags
-
-    createDicomRequestContent["Tags"] = dicomTags;
-
-    RadiographyPhotometricDisplayMode photometricMode = GetPreferredPhotomotricDisplayMode();
-    if ((invert && photometricMode != RadiographyPhotometricDisplayMode_Monochrome2) ||
-        (!invert && photometricMode == RadiographyPhotometricDisplayMode_Monochrome1))
-    {
-      createDicomRequestContent["Tags"]["PhotometricInterpretation"] = "MONOCHROME1";
-    }
-    else
-    {
-      createDicomRequestContent["Tags"]["PhotometricInterpretation"] = "MONOCHROME2";
-    }
-
-    // WARNING: The order of PixelSpacing is Y/X. We use "%0.8f" to
-    // avoid floating-point numbers to grow over 16 characters,
-    // which would be invalid according to DICOM standard
-    // ("dciodvfy" would complain).
-    char buf[32];
-    sprintf(buf, "%0.8f\\%0.8f", pixelSpacingY, pixelSpacingX);
-
-    createDicomRequestContent["Tags"]["PixelSpacing"] = buf;
-
-    float center, width;
-    if (GetWindowing(center, width))
-    {
-      createDicomRequestContent["Tags"]["WindowCenter"] =
-          boost::lexical_cast<std::string>(boost::math::iround(center));
-
-      createDicomRequestContent["Tags"]["WindowWidth"] =
-          boost::lexical_cast<std::string>(boost::math::iround(width));
-    }
-
-    if (!parentOrthancId.empty())
-    {
-      createDicomRequestContent["Parent"] = parentOrthancId;
-    }
-
-    return rendered.release();
-  }
-
-
-  void RadiographyScene::ExportToCreateDicomRequest(Json::Value& createDicomRequestContent,
-                                                    const Json::Value& dicomTags,
-                                                    const std::string& parentOrthancId,
-                                                    double pixelSpacingX,
-                                                    double pixelSpacingY,
-                                                    bool invert,
-                                                    bool autoCrop,
-                                                    ImageInterpolation interpolation,
-                                                    bool usePam)
-  {
-    LOG(INFO) << "Exporting RadiographyScene to DICOM";
-    VLOG(1) << "Exporting RadiographyScene to: export to image";
-
-    std::unique_ptr<Orthanc::Image> rendered(ExportToCreateDicomRequestAndImage(createDicomRequestContent, dicomTags, parentOrthancId, pixelSpacingX, pixelSpacingY, invert, autoCrop, interpolation));
-
-    // convert the image into base64 for inclusing in the createDicomRequest
-    std::string base64;
-
-    {
-      std::string content;
-
-      if (usePam)
-      {
-        VLOG(1) << "Exporting RadiographyScene: convert to PAM";
-        Orthanc::PamWriter writer;
-        writer.WriteToMemory(content, *rendered);
-      }
-      else
-      {
-        Orthanc::PngWriter writer;
-        writer.WriteToMemory(content, *rendered);
-      }
-
-      VLOG(1) << "Exporting RadiographyScene: encoding to base64";
-      Orthanc::Toolbox::EncodeBase64(base64, content);
-    }
-
-    // This is Data URI scheme: https://en.wikipedia.org/wiki/Data_URI_scheme
-    createDicomRequestContent["Content"] = ("data:" +
-                                            std::string(usePam ? Orthanc::MIME_PAM : Orthanc::MIME_PNG) +
-                                            ";base64," + base64);
-
-    VLOG(1) << "Exporting RadiographyScene: create-dicom request is ready";
-  }
-
-
-  void RadiographyScene::ExportDicom(Deprecated::OrthancApiClient& orthanc,
-                                     const Json::Value& dicomTags,
-                                     const std::string& parentOrthancId,
-                                     double pixelSpacingX,
-                                     double pixelSpacingY,
-                                     bool invert,
-                                     bool autoCrop,
-                                     ImageInterpolation interpolation,
-                                     bool usePam)
-  {
-    Json::Value createDicomRequestContent;
-
-    ExportToCreateDicomRequest(createDicomRequestContent, dicomTags, parentOrthancId, pixelSpacingX, pixelSpacingY, invert, autoCrop, interpolation, usePam);
-
-    orthanc.PostJsonAsyncExpectJson(
-          "/tools/create-dicom", createDicomRequestContent,
-          new Deprecated::DeprecatedCallable<RadiographyScene, Deprecated::OrthancApiClient::JsonResponseReadyMessage>
-          (GetSharedObserver(), &RadiographyScene::OnDicomExported),
-          NULL, NULL);
-
-  }
-
-
-  // Export using PAM is faster than using PNG, but requires Orthanc
-  // core >= 1.4.3
-  void RadiographyScene::ExportDicom(Deprecated::OrthancApiClient& orthanc,
-                                     const Orthanc::DicomMap& dicom,
-                                     const std::string& parentOrthancId,
-                                     double pixelSpacingX,
-                                     double pixelSpacingY,
-                                     bool invert,
-                                     bool autoCrop,
-                                     ImageInterpolation interpolation,
-                                     bool usePam)
-  {
-    std::set<Orthanc::DicomTag> tags;
-    dicom.GetTags(tags);
-
-    Json::Value jsonTags = Json::objectValue;
-
-    for (std::set<Orthanc::DicomTag>::const_iterator
-         tag = tags.begin(); tag != tags.end(); ++tag)
-    {
-      const Orthanc::DicomValue& value = dicom.GetValue(*tag);
-      if (!value.IsNull() &&
-          !value.IsBinary())
-      {
-        jsonTags[tag->Format()] = value.GetContent();
-      }
-    }
-
-    ExportDicom(orthanc, jsonTags, parentOrthancId, pixelSpacingX, pixelSpacingY, invert, autoCrop, interpolation, usePam);
-  }
-
-  void RadiographyScene::OnDicomExported(const Deprecated::OrthancApiClient::JsonResponseReadyMessage& message)
-  {
-    LOG(INFO) << "DICOM export was successful: "
-              << message.GetJson().toStyledString();
-  }
-
-
-  void RadiographyScene::OnDicomWebReceived(const Deprecated::IWebService::HttpRequestSuccessMessage& message)
-  {
-    LOG(INFO) << "DICOMweb WADO-RS received: " << message.GetAnswerSize() << " bytes";
-
-    const Deprecated::IWebService::HttpHeaders& h = message.GetAnswerHttpHeaders();
-    for (Deprecated::IWebService::HttpHeaders::const_iterator
-         it = h.begin(); it != h.end(); ++it)
-    {
-      printf("[%s] = [%s]\n", it->first.c_str(), it->second.c_str());
-    }
-  }
-
-  void RadiographyScene::ExportToScene2D(Scene2D& output) const
-  {
-    int depth = 0;
-    for (Layers::const_iterator it = layers_.begin();
-         it != layers_.end(); ++it)
-    {
-      assert(it->second != NULL);
-
-      std::unique_ptr<ISceneLayer> layer;
-      if (dynamic_cast<RadiographyDicomLayer*>(it->second))
-      {
-        RadiographyDicomLayer* oldLayer = dynamic_cast<RadiographyDicomLayer*>(it->second);
-
-        std::unique_ptr<FloatTextureSceneLayer> newLayer(new FloatTextureSceneLayer(*(oldLayer->GetSourceImage())));
-
-        newLayer->SetOrigin(oldLayer->GetGeometry().GetPanX(),
-                            oldLayer->GetGeometry().GetPanY()
-                            );
-        newLayer->SetAngle(oldLayer->GetGeometry().GetAngle());
-
-        layer.reset(newLayer.release());
-
-        // TODO: windowing dynamic_cast
-      }
-      else if (dynamic_cast<RadiographyTextLayer*>(it->second))
-      {
-        RadiographyTextLayer* oldLayer = dynamic_cast<RadiographyTextLayer*>(it->second);
-
-        std::unique_ptr<TextSceneLayer> newLayer(new TextSceneLayer());
-
-        newLayer->SetText(oldLayer->GetText());
-        newLayer->SetColor(oldLayer->GetForegroundGreyLevel(),
-                           oldLayer->GetForegroundGreyLevel(),
-                           oldLayer->GetForegroundGreyLevel()
-                           );
-        newLayer->SetPosition(oldLayer->GetGeometry().GetPanX(),
-                              oldLayer->GetGeometry().GetPanY()
-                              );
-        newLayer->SetFontIndex(1);
-        newLayer->SetAnchor(BitmapAnchor_TopLeft);
-        //newLayer->SetAngle(oldLayer->GetGeometry().GetAngle());
-
-        layer.reset(newLayer.release());
-      }
-
-      output.SetLayer(depth++, layer.release());
-
-    }
-
-  }
-
-}
-
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyScene.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,371 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "RadiographyLayer.h"
-#include "../Messages/ObserverBase.h"
-#include "../Deprecated/Toolbox/DicomFrameConverter.h"
-#include "../Deprecated/Toolbox/OrthancApiClient.h"
-#include "../StoneEnumerations.h"
-#include "../Scene2D/Scene2D.h"
-
-#include <Images/Image.h>
-#include <Images/ImageProcessing.h>
-
-
-namespace OrthancStone
-{
-  class RadiographyDicomLayer;
-
-  class RadiographyScene :
-    public ObserverBase<RadiographyScene>,
-    public IObservable
-  {
-    friend class RadiographySceneGeometryReader;
-  public:
-    class GeometryChangedMessage : public OriginMessage<RadiographyScene>
-    {
-      ORTHANC_STONE_MESSAGE(__FILE__, __LINE__);
-
-    private:
-      RadiographyLayer&        layer_;
-
-    public:
-      GeometryChangedMessage(const RadiographyScene& origin,
-                             RadiographyLayer& layer) :
-        OriginMessage(origin),
-        layer_(layer)
-      {
-      }
-
-      RadiographyLayer& GetLayer() const
-      {
-        return layer_;
-      }
-    };
-
-    class ContentChangedMessage : public OriginMessage<RadiographyScene>
-    {
-      ORTHANC_STONE_MESSAGE(__FILE__, __LINE__);
-
-    private:
-      RadiographyLayer&        layer_;
-
-    public:
-      ContentChangedMessage(const RadiographyScene& origin,
-                            RadiographyLayer& layer) :
-        OriginMessage(origin),
-        layer_(layer)
-      {
-      }
-
-      RadiographyLayer& GetLayer() const
-      {
-        return layer_;
-      }
-    };
-
-    class LayerEditedMessage : public OriginMessage<RadiographyScene>
-    {
-      ORTHANC_STONE_MESSAGE(__FILE__, __LINE__);
-
-    private:
-      const RadiographyLayer&        layer_;
-
-    public:
-      LayerEditedMessage(const RadiographyScene& origin,
-                         const RadiographyLayer& layer) :
-        OriginMessage(origin),
-        layer_(layer)
-      {
-      }
-
-      const RadiographyLayer& GetLayer() const
-      {
-        return layer_;
-      }
-    };
-
-    class LayerRemovedMessage : public OriginMessage<RadiographyScene>
-    {
-      ORTHANC_STONE_MESSAGE(__FILE__, __LINE__);
-
-    private:
-      size_t&        layerIndex_;
-
-    public:
-      LayerRemovedMessage(const RadiographyScene& origin,
-                          size_t& layerIndex) :
-        OriginMessage(origin),
-        layerIndex_(layerIndex)
-      {
-      }
-
-      size_t& GetLayerIndex() const
-      {
-        return layerIndex_;
-      }
-    };
-
-
-    ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, WindowingChangedMessage, RadiographyScene);
-
-    
-    class LayerAccessor : public boost::noncopyable
-    {
-    private:
-      RadiographyScene&  scene_;
-      size_t             index_;
-      RadiographyLayer*  layer_;
-
-    public:
-      LayerAccessor(RadiographyScene& scene,
-                    size_t index);
-
-      LayerAccessor(RadiographyScene& scene,
-                    double x,
-                    double y);
-
-      void Invalidate()
-      {
-        layer_ = NULL;
-      }
-
-      bool IsValid() const
-      {
-        return layer_ != NULL;
-      }
-
-      RadiographyScene& GetScene() const;
-
-      size_t GetIndex() const;
-
-      RadiographyLayer& GetLayer() const;
-    };
-
-
-  protected:
-    typedef std::map<size_t, RadiographyLayer*>  Layers;
-
-    size_t  nextLayerIndex_;
-    bool    hasWindowing_;
-    float   windowingCenter_;
-    float   windowingWidth_;
-    Layers  layers_;
-
-  public:
-    RadiographyLayer& RegisterLayer(RadiographyLayer* layer);
-
-  protected:
-    virtual void _RegisterLayer(RadiographyLayer* layer);
-    virtual void _OnLayerRemoved() {}
-
-    void SetLayerIndex(RadiographyLayer* layer, size_t index)
-    {
-      layer->SetIndex(index);
-    }
-
-    virtual void OnTagsReceived(const Deprecated::OrthancApiClient::BinaryResponseReadyMessage& message);
-
-    virtual void OnFrameReceived(const Deprecated::OrthancApiClient::BinaryResponseReadyMessage& message);
-    
-    void OnDicomExported(const Deprecated::OrthancApiClient::JsonResponseReadyMessage& message);
-
-    void OnDicomWebReceived(const Deprecated::IWebService::HttpRequestSuccessMessage& message);
-
-    virtual void OnLayerEdited(const RadiographyLayer::LayerEditedMessage& message);
-
-  public:
-    RadiographyScene();
-    
-    virtual ~RadiographyScene();
-
-    virtual size_t GetApproximateMemoryUsage() const;
-
-    bool GetWindowing(float& center,
-                      float& width) const;
-
-    void GetWindowingWithDefault(float& center,
-                                 float& width) const;
-
-    virtual void SetWindowing(float center,
-                              float width);
-
-    RadiographyPhotometricDisplayMode GetPreferredPhotomotricDisplayMode() const;
-
-    RadiographyLayer& LoadText(const std::string& utf8,
-                               const std::string& font,
-                               unsigned int fontSize,
-                               uint8_t foreground,
-                               RadiographyLayer::Geometry* geometry,
-                               bool isCenterGeometry);
-
-    RadiographyLayer& UpdateText(size_t layerIndex,
-                                 const std::string& font,
-                                 const std::string& utf8,
-                                 unsigned int fontSize,
-                                 uint8_t foreground);
-
-    RadiographyLayer& LoadTestBlock(unsigned int width,
-                                    unsigned int height,
-                                    RadiographyLayer::Geometry* geometry);
-
-    RadiographyLayer& LoadMask(const std::vector<Orthanc::ImageProcessing::ImagePoint>& corners,
-                               const RadiographyDicomLayer& dicomLayer,
-                               float foreground,
-                               RadiographyLayer::Geometry* geometry);
-
-    RadiographyLayer& LoadAlphaBitmap(Orthanc::ImageAccessor* bitmap,  // takes ownership
-                                      RadiographyLayer::Geometry* geometry);
-
-    virtual RadiographyLayer& LoadDicomImage(Orthanc::ImageAccessor* dicomImage, // takes ownership
-                                             const std::string& instance,
-                                             unsigned int frame,
-                                             Deprecated::DicomFrameConverter* converter,  // takes ownership
-                                             RadiographyPhotometricDisplayMode preferredPhotometricDisplayMode,
-                                             RadiographyLayer::Geometry* geometry);
-
-    virtual RadiographyLayer& LoadDicomFrame(Deprecated::OrthancApiClient& orthanc,
-                                             const std::string& instance,
-                                             unsigned int frame,
-                                             bool httpCompression,
-                                             RadiographyLayer::Geometry* geometry); // pass NULL if you want default geometry
-
-    RadiographyLayer& LoadDicomWebFrame(Deprecated::IWebService& web);
-
-    void RemoveLayer(size_t layerIndex);
-
-    RadiographyLayer& GetLayer(size_t layerIndex);
-
-    const RadiographyLayer& GetLayer(size_t layerIndex) const;
-
-    template <typename TypeLayer>
-    TypeLayer* GetTypedLayer(size_t indexOfType = 0)
-    {
-      std::vector<size_t> layerIndexes;
-      GetLayersIndexes(layerIndexes);
-
-      size_t count = 0;
-
-      for (size_t i = 0; i < layerIndexes.size(); ++i)
-      {
-        TypeLayer* typedLayer = dynamic_cast<TypeLayer*>(layers_[layerIndexes[i]]);
-        if (typedLayer != NULL)
-        {
-          if (count == indexOfType)
-          {
-            return typedLayer;
-          }
-          count++;
-        }
-      }
-
-      return NULL;
-    }
-
-    void GetLayersIndexes(std::vector<size_t>& output) const;
-
-    virtual Extent2D GetSceneExtent(bool minimal) const;
-
-    virtual void Render(Orthanc::ImageAccessor& buffer,
-                        const AffineTransform2D& viewTransform,
-                        ImageInterpolation interpolation,
-                        bool applyWindowing) const;
-
-    bool LookupLayer(size_t& index /* out */,
-                     double x,
-                     double y) const;
-    
-    void DrawBorder(CairoContext& context,
-                    unsigned int layer,
-                    double zoom);
-
-    void GetRange(float& minValue,
-                  float& maxValue) const;
-
-    void ExportToScene2D(Scene2D& output) const;
-
-    // Export using PAM is faster than using PNG, but requires Orthanc
-    // core >= 1.4.3
-    void ExportDicom(Deprecated::OrthancApiClient& orthanc,
-                     const Orthanc::DicomMap& dicom,
-                     const std::string& parentOrthancId,
-                     double pixelSpacingX,
-                     double pixelSpacingY,
-                     bool invert,
-                     bool autoCrop,
-                     ImageInterpolation interpolation,
-                     bool usePam);
-
-    void ExportDicom(Deprecated::OrthancApiClient& orthanc,
-                     const Json::Value& dicomTags,
-                     const std::string& parentOrthancId,
-                     double pixelSpacingX,
-                     double pixelSpacingY,
-                     bool invert,
-                     bool autoCrop,
-                     ImageInterpolation interpolation,
-                     bool usePam);
-
-    void ExportToCreateDicomRequest(Json::Value& createDicomRequestContent,
-                                    const Json::Value& dicomTags,
-                                    const std::string& parentOrthancId,
-                                    double pixelSpacingX,
-                                    double pixelSpacingY,
-                                    bool invert,
-                                    bool autoCrop,
-                                    ImageInterpolation interpolation,
-                                    bool usePam);
-
-    Orthanc::Image* ExportToCreateDicomRequestAndImage(Json::Value& createDicomRequestContent,
-                                                       const Json::Value& dicomTags,
-                                                       const std::string& parentOrthancId,
-                                                       double pixelSpacingX,
-                                                       double pixelSpacingY,
-                                                       bool invert,
-                                                       bool autoCrop,
-                                                       ImageInterpolation interpolation);
-
-    Orthanc::Image* ExportToImage(double pixelSpacingX,
-                                  double pixelSpacingY,
-                                  ImageInterpolation interpolation,
-                                  bool autoCrop,
-                                  bool applyWindowing)
-    {
-      return ExportToImage(pixelSpacingX, pixelSpacingY, interpolation, false, 0, autoCrop, applyWindowing);
-    }
-
-    Orthanc::Image* ExportToImage(double pixelSpacingX,
-                                  double pixelSpacingY,
-                                  ImageInterpolation interpolation,
-                                  bool invert,
-                                  int64_t maxValue /* for inversion */,
-                                  bool autoCrop,
-                                  bool applyWindowing);
-
-    void ExtractLayerFromRenderedScene(Orthanc::ImageAccessor& layer,
-                                       const Orthanc::ImageAccessor& renderedScene,
-                                       size_t layerIndex,
-                                       bool isCropped,
-                                       ImageInterpolation interpolation);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographySceneCommand.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "RadiographySceneCommand.h"
-
-
-namespace OrthancStone
-{
-  RadiographySceneCommand::RadiographySceneCommand(RadiographyScene& scene,
-                                                   size_t layer) :
-    scene_(scene),
-    layer_(layer)
-  {
-  }
-
-  
-  RadiographySceneCommand::RadiographySceneCommand(const RadiographyScene::LayerAccessor& accessor) :
-    scene_(accessor.GetScene()),
-    layer_(accessor.GetIndex())
-  {
-  }
-
-  
-  void RadiographySceneCommand::Undo() const
-  {
-    RadiographyScene::LayerAccessor accessor(scene_, layer_);
-
-    if (accessor.IsValid())
-    {
-      UndoInternal(accessor.GetLayer());
-    }
-  }
-
-  
-  void RadiographySceneCommand::Redo() const
-  {
-    RadiographyScene::LayerAccessor accessor(scene_, layer_);
-
-    if (accessor.IsValid())
-    {
-      RedoInternal(accessor.GetLayer());
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographySceneCommand.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../Toolbox/UndoRedoStack.h"
-#include "RadiographyScene.h"
-
-namespace OrthancStone
-{
-  class RadiographySceneCommand : public UndoRedoStack::ICommand
-  {
-  private:
-    RadiographyScene&  scene_;
-    size_t             layer_;
-
-  protected:
-    virtual void UndoInternal(RadiographyLayer& layer) const = 0;
-
-    virtual void RedoInternal(RadiographyLayer& layer) const = 0;
-
-  public:
-    RadiographySceneCommand(RadiographyScene& scene,
-                            size_t layer);
-
-    RadiographySceneCommand(const RadiographyScene::LayerAccessor& accessor);
-
-    virtual void Undo() const;
-
-    virtual void Redo() const;
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographySceneReader.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "RadiographySceneReader.h"
-
-#include "../Deprecated/Toolbox/DicomFrameConverter.h"
-
-#include <Images/FontRegistry.h>
-#include <Images/PngReader.h>
-#include <OrthancException.h>
-#include <Toolbox.h>
-
-namespace OrthancStone
-{
-
-  void RadiographySceneBuilder::Read(const Json::Value& input, Orthanc::ImageAccessor* dicomImage /* takes ownership */,
-                                     Deprecated::DicomFrameConverter* dicomFrameConverter  /* takes ownership */,
-                                     RadiographyPhotometricDisplayMode preferredPhotometricDisplayMode
-                                     )
-  {
-    dicomImage_.reset(dicomImage);
-    dicomFrameConverter_.reset(dicomFrameConverter);
-    preferredPhotometricDisplayMode_ = preferredPhotometricDisplayMode;
-    Read(input);
-  }
-
-  RadiographyDicomLayer* RadiographySceneBuilder::LoadDicom(const std::string& instanceId, unsigned int frame, RadiographyLayer::Geometry* geometry)
-  {
-    return dynamic_cast<RadiographyDicomLayer*>(&(scene_.LoadDicomImage(dicomImage_.release(), instanceId, frame, dicomFrameConverter_.release(), preferredPhotometricDisplayMode_, geometry)));
-  }
-
-
-  RadiographyDicomLayer* RadiographySceneReader::LoadDicom(const std::string& instanceId, unsigned int frame, RadiographyLayer::Geometry* geometry)
-  {
-    return dynamic_cast<RadiographyDicomLayer*>(&(scene_.LoadDicomFrame(orthancApiClient_, instanceId, frame, false, geometry)));
-  }
-
-  RadiographyDicomLayer* RadiographySceneGeometryReader::LoadDicom(const std::string& instanceId, unsigned int frame, RadiographyLayer::Geometry* geometry)
-  {
-    std::unique_ptr<RadiographyPlaceholderLayer>  layer(new RadiographyPlaceholderLayer(scene_));
-    layer->SetGeometry(*geometry);
-    layer->SetSize(dicomImageWidth_, dicomImageHeight_);
-    scene_.RegisterLayer(layer.get());
-
-    return layer.release();
-  }
-
-  void RadiographySceneBuilder::Read(const Json::Value& input)
-  {
-    unsigned int version = input["version"].asUInt();
-
-    if (version != 1)
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
-
-    if (input.isMember("hasWindowing") && input["hasWindowing"].asBool())
-    {
-      scene_.SetWindowing(input["windowCenter"].asFloat(), input["windowWidth"].asFloat());
-    }
-
-    RadiographyDicomLayer* dicomLayer = NULL;
-    for(size_t layerIndex = 0; layerIndex < input["layers"].size(); layerIndex++)
-    {
-      const Json::Value& jsonLayer = input["layers"][(int)layerIndex];
-      RadiographyLayer::Geometry geometry;
-
-      if (jsonLayer["type"].asString() == "dicom")
-      {
-        ReadLayerGeometry(geometry, jsonLayer);
-        dicomLayer = LoadDicom(jsonLayer["instanceId"].asString(), jsonLayer["frame"].asUInt(), &geometry);
-      }
-      else if (jsonLayer["type"].asString() == "mask")
-      {
-        if (dicomLayer == NULL)
-        {
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); // we always assumed the dicom layer was read before the mask
-        }
-        ReadLayerGeometry(geometry, jsonLayer);
-
-        float foreground = jsonLayer["foreground"].asFloat();
-        std::vector<Orthanc::ImageProcessing::ImagePoint> corners;
-        for (size_t i = 0; i < jsonLayer["corners"].size(); i++)
-        {
-          Orthanc::ImageProcessing::ImagePoint corner(jsonLayer["corners"][(int)i]["x"].asInt(),
-              jsonLayer["corners"][(int)i]["y"].asInt());
-          corners.push_back(corner);
-        }
-
-        scene_.LoadMask(corners, *dicomLayer, foreground, &geometry);
-      }
-      else if (jsonLayer["type"].asString() == "text")
-      {
-        ReadLayerGeometry(geometry, jsonLayer);
-        scene_.LoadText(jsonLayer["text"].asString(), jsonLayer["font"].asString(), jsonLayer["fontSize"].asUInt(), static_cast<uint8_t>(jsonLayer["foreground"].asUInt()), &geometry, false);
-      }
-      else if (jsonLayer["type"].asString() == "alpha")
-      {
-        ReadLayerGeometry(geometry, jsonLayer);
-
-        const std::string& pngContentBase64 = jsonLayer["content"].asString();
-        std::string pngContent;
-        std::string mimeType;
-        Orthanc::Toolbox::DecodeDataUriScheme(mimeType, pngContent, pngContentBase64);
-
-        std::unique_ptr<Orthanc::ImageAccessor>  image;
-        if (mimeType == "image/png")
-        {
-          image.reset(new Orthanc::PngReader());
-          dynamic_cast<Orthanc::PngReader*>(image.get())->ReadFromMemory(pngContent);
-        }
-        else
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
-
-        RadiographyAlphaLayer& layer = dynamic_cast<RadiographyAlphaLayer&>(scene_.LoadAlphaBitmap(image.release(), &geometry));
-
-        if (!jsonLayer["isUsingWindowing"].asBool())
-        {
-          layer.SetForegroundValue((float)(jsonLayer["foreground"].asDouble()));
-        }
-      }
-      else
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
-    }
-  }
-
-
-
-
-  void RadiographySceneBuilder::ReadDicomLayerGeometry(RadiographyLayer::Geometry& geometry, const Json::Value& input)
-  {
-    for(size_t layerIndex = 0; layerIndex < input["layers"].size(); layerIndex++)
-    {
-      const Json::Value& jsonLayer = input["layers"][(int)layerIndex];
-      if (jsonLayer["type"].asString() == "dicom")
-      {
-        ReadLayerGeometry(geometry, jsonLayer);
-        return;
-      }
-    }
-  }
-
-  void RadiographySceneBuilder::ReadLayerGeometry(RadiographyLayer::Geometry& geometry, const Json::Value& jsonLayer)
-  {
-    {// crop
-      unsigned int x, y, width, height;
-      if (jsonLayer["crop"]["hasCrop"].asBool())
-      {
-        x = jsonLayer["crop"]["x"].asUInt();
-        y = jsonLayer["crop"]["y"].asUInt();
-        width = jsonLayer["crop"]["width"].asUInt();
-        height = jsonLayer["crop"]["height"].asUInt();
-        geometry.SetCrop(x, y, width, height);
-      }
-    }
-
-    geometry.SetAngle(jsonLayer["angle"].asDouble());
-    geometry.SetResizeable(jsonLayer["isResizable"].asBool());
-    geometry.SetPan(jsonLayer["pan"]["x"].asDouble(), jsonLayer["pan"]["y"].asDouble());
-    geometry.SetPixelSpacing(jsonLayer["pixelSpacing"]["x"].asDouble(), jsonLayer["pixelSpacing"]["y"].asDouble());
-
-    // these fields were introduced later -> they might not exist
-    if (jsonLayer.isMember("flipVertical"))
-    {
-      geometry.SetFlipVertical(jsonLayer["flipVertical"].asBool());
-    }
-    if (jsonLayer.isMember("flipHorizontal"))
-    {
-      geometry.SetFlipHorizontal(jsonLayer["flipHorizontal"].asBool());
-    }
-
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographySceneReader.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "RadiographyScene.h"
-#include "RadiographyAlphaLayer.h"
-#include "RadiographyDicomLayer.h"
-#include "RadiographyMaskLayer.h"
-#include "RadiographyTextLayer.h"
-#include "../Deprecated/Toolbox/OrthancApiClient.h"
-
-#include <json/value.h>
-#include <Images/FontRegistry.h>
-
-namespace OrthancStone
-{
-  // a layer containing only the geometry of a DICOM layer (bit hacky !)
-  class RadiographyPlaceholderLayer : public RadiographyDicomLayer
-  {
-  public:
-    RadiographyPlaceholderLayer(const RadiographyScene& scene) :
-      RadiographyDicomLayer(scene)
-    {
-    }
-
-  };
-
-
-  // HACK: I had to introduce this builder class in order to be able to recreate a RadiographyScene
-  // from a serialized scene that is passed to web-workers.
-  // It needs some architecturing...
-  class RadiographySceneBuilder : public boost::noncopyable
-  {
-  protected:
-    RadiographyScene&                               scene_;
-    std::unique_ptr<Orthanc::ImageAccessor>           dicomImage_;
-    std::unique_ptr<Deprecated::DicomFrameConverter>  dicomFrameConverter_;
-    RadiographyPhotometricDisplayMode               preferredPhotometricDisplayMode_;
-
-  public:
-    RadiographySceneBuilder(RadiographyScene& scene) :
-      scene_(scene)
-    {
-    }
-
-    void Read(const Json::Value& input);
-    void Read(const Json::Value& input,
-              Orthanc::ImageAccessor* dicomImage, // takes ownership
-              Deprecated::DicomFrameConverter* dicomFrameConverter, // takes ownership
-              RadiographyPhotometricDisplayMode preferredPhotometricDisplayMode
-              );
-
-    static void ReadLayerGeometry(RadiographyLayer::Geometry& geometry, const Json::Value& input);
-    static void ReadDicomLayerGeometry(RadiographyLayer::Geometry& geometry, const Json::Value& input);
-
-  protected:
-    virtual RadiographyDicomLayer* LoadDicom(const std::string& instanceId, unsigned int frame, RadiographyLayer::Geometry* geometry);
-
-  };
-
-
-  class RadiographySceneReader : public RadiographySceneBuilder
-  {
-    Deprecated::OrthancApiClient&             orthancApiClient_;
-
-  public:
-    RadiographySceneReader(RadiographyScene& scene, Deprecated::OrthancApiClient& orthancApiClient) :
-      RadiographySceneBuilder(scene),
-      orthancApiClient_(orthancApiClient)
-    {
-    }
-
-  protected:
-    virtual RadiographyDicomLayer*  LoadDicom(const std::string& instanceId, unsigned int frame, RadiographyLayer::Geometry* geometry);
-  };
-
-  // reads the whole scene but the DICOM image such that we have the full geometry
-  class RadiographySceneGeometryReader : public RadiographySceneBuilder
-  {
-    unsigned int dicomImageWidth_;
-    unsigned int dicomImageHeight_;
-
-  public:
-    RadiographySceneGeometryReader(RadiographyScene& scene, unsigned int dicomImageWidth, unsigned int dicomImageHeight) :
-      RadiographySceneBuilder(scene),
-      dicomImageWidth_(dicomImageWidth),
-      dicomImageHeight_(dicomImageHeight)
-    {
-    }
-
-  protected:
-    virtual RadiographyDicomLayer*  LoadDicom(const std::string& instanceId, unsigned int frame, RadiographyLayer::Geometry* geometry);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographySceneWriter.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,168 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "RadiographySceneWriter.h"
-
-#include <OrthancException.h>
-#include <Images/PngWriter.h>
-#include <Toolbox.h>
-
-namespace OrthancStone
-{
-  void RadiographySceneWriter::Write(Json::Value& output, const RadiographyScene& scene)
-  {
-    output["version"] = 1;
-    float windowCenter, windowWidth;
-    bool hasWindowing = scene.GetWindowing(windowCenter, windowWidth);
-    output["hasWindowing"] = hasWindowing;
-    if (hasWindowing)
-    {
-      output["windowCenter"] = windowCenter;
-      output["windowWidth"] = windowWidth;
-    }
-    output["layers"] = Json::arrayValue;
-
-    std::vector<size_t> layersIndexes;
-    scene.GetLayersIndexes(layersIndexes);
-
-    for (std::vector<size_t>::iterator itLayerIndex = layersIndexes.begin(); itLayerIndex < layersIndexes.end(); itLayerIndex++)
-    {
-      Json::Value layer;
-      WriteLayer(layer, scene.GetLayer(*itLayerIndex));
-      output["layers"].append(layer);
-    }
-  }
-
-  void RadiographySceneWriter::WriteLayer(Json::Value& output, const RadiographyDicomLayer& layer)
-  {
-    output["type"] = "dicom";
-    output["instanceId"] = layer.GetInstanceId();
-    output["frame"] = layer.GetFrame();
-  }
-
-  void RadiographySceneWriter::WriteLayer(Json::Value& output, const RadiographyTextLayer& layer)
-  {
-    output["type"] = "text";
-    output["text"] = layer.GetText();
-    output["font"] = layer.GetFont();
-    output["fontSize"] = layer.GetFontSize();
-    output["foreground"] = layer.GetForegroundGreyLevel();
-  }
-
-  void RadiographySceneWriter::WriteLayer(Json::Value& output, const RadiographyMaskLayer& layer)
-  {
-    output["type"] = "mask";
-    output["instanceId"] = layer.GetInstanceId(); // the dicom layer it's being linked to
-    output["foreground"] = layer.GetForeground();
-    output["corners"] = Json::arrayValue;
-    const std::vector<Orthanc::ImageProcessing::ImagePoint>& corners = layer.GetCorners();
-    for (size_t i = 0; i < corners.size(); i++)
-    {
-      Json::Value corner;
-      corner["x"] = corners[i].GetX();
-      corner["y"] = corners[i].GetY();
-      output["corners"].append(corner);
-    }
-  }
-
-  void RadiographySceneWriter::WriteLayer(Json::Value& output, const RadiographyAlphaLayer& layer)
-  {
-    output["type"] = "alpha";
-
-    //output["bitmap"] =
-    const Orthanc::ImageAccessor& alpha = layer.GetAlpha();
-
-    Orthanc::PngWriter pngWriter;
-    std::string pngContent;
-    std::string pngContentBase64;
-    pngWriter.WriteToMemory(pngContent, alpha);
-
-    Orthanc::Toolbox::EncodeDataUriScheme(pngContentBase64, "image/png", pngContent);
-    output["content"] = pngContentBase64;
-    output["foreground"] = layer.GetForegroundValue();
-  }
-
-  void RadiographySceneWriter::WriteLayer(Json::Value& output, const RadiographyLayer& layer)
-  {
-    const RadiographyLayer::Geometry& geometry = layer.GetGeometry();
-
-    {// crop
-      Json::Value crop;
-      if (geometry.HasCrop())
-      {
-        unsigned int x, y, width, height;
-        geometry.GetCrop(x, y, width, height);
-        crop["hasCrop"] = true;
-        crop["x"] = x;
-        crop["y"] = y;
-        crop["width"] = width;
-        crop["height"] = height;
-      }
-      else
-      {
-        crop["hasCrop"] = false;
-      }
-
-      output["crop"] = crop;
-    }
-
-    output["angle"] = geometry.GetAngle();
-    output["isResizable"] = geometry.IsResizeable();
-
-    {// pan
-      Json::Value pan;
-      pan["x"] = geometry.GetPanX();
-      pan["y"] = geometry.GetPanY();
-      output["pan"] = pan;
-    }
-
-    {// pixelSpacing
-      Json::Value pan;
-      pan["x"] = geometry.GetPixelSpacingX();
-      pan["y"] = geometry.GetPixelSpacingY();
-      output["pixelSpacing"] = pan;
-    }
-
-    output["flipVertical"] = geometry.GetFlipVertical();
-    output["flipHorizontal"] = geometry.GetFlipHorizontal();
-
-    if (dynamic_cast<const RadiographyTextLayer*>(&layer) != NULL)
-    {
-      WriteLayer(output, dynamic_cast<const RadiographyTextLayer&>(layer));
-    }
-    else if (dynamic_cast<const RadiographyDicomLayer*>(&layer) != NULL)
-    {
-      WriteLayer(output, dynamic_cast<const RadiographyDicomLayer&>(layer));
-    }
-    else if (dynamic_cast<const RadiographyAlphaLayer*>(&layer) != NULL)
-    {
-      WriteLayer(output, dynamic_cast<const RadiographyAlphaLayer&>(layer));
-    }
-    else if (dynamic_cast<const RadiographyMaskLayer*>(&layer) != NULL)
-    {
-      WriteLayer(output, dynamic_cast<const RadiographyMaskLayer&>(layer));
-    }
-    else
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographySceneWriter.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "RadiographyScene.h"
-#include "RadiographyAlphaLayer.h"
-#include "RadiographyDicomLayer.h"
-#include "RadiographyTextLayer.h"
-#include "RadiographyMaskLayer.h"
-#include <json/value.h>
-
-namespace OrthancStone
-{
-  class RadiographyScene;
-
-  class RadiographySceneWriter : public boost::noncopyable
-  {
-
-  public:
-    RadiographySceneWriter()
-    {
-    }
-
-    void Write(Json::Value& output, const RadiographyScene& scene);
-
-  private:
-    void WriteLayer(Json::Value& output, const RadiographyLayer& layer);
-    void WriteLayer(Json::Value& output, const RadiographyDicomLayer& layer);
-    void WriteLayer(Json::Value& output, const RadiographyTextLayer& layer);
-    void WriteLayer(Json::Value& output, const RadiographyAlphaLayer& layer);
-    void WriteLayer(Json::Value& output, const RadiographyMaskLayer& layer);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyTextLayer.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "RadiographyTextLayer.h"
-
-#include "RadiographyScene.h"
-#include "../Toolbox/TextRenderer.h"
-
-#include <OrthancException.h>
-
-namespace OrthancStone
-{
-  std::map<std::string, Orthanc::EmbeddedResources::FileResourceId> RadiographyTextLayer::fonts_;
-
-  void RadiographyTextLayer::SetText(const std::string& utf8,
-                                     const std::string& font,
-                                     unsigned int fontSize,
-                                     uint8_t foregroundGreyLevel)
-  {
-    if (fonts_.find(font) == fonts_.end())
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls, "The font has not been registered");
-    }
-
-    text_ = utf8;
-    font_ = font;
-    fontSize_ = fontSize;
-    foregroundGreyLevel_ = foregroundGreyLevel;
-
-    SetAlpha(TextRenderer::Render(fonts_[font_],
-                                  fontSize_,
-                                  text_));
-
-    SetForegroundValue(foregroundGreyLevel * 256.0f);
-  }
-
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyTextLayer.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "RadiographyAlphaLayer.h"
-
-namespace OrthancStone
-{
-  class RadiographyScene;
-
-  class RadiographyTextLayer : public RadiographyAlphaLayer
-  {
-  private:
-    std::string                 text_;
-    std::string                 font_;
-    unsigned int                fontSize_;
-    uint8_t                     foregroundGreyLevel_;
-
-    static std::map<std::string, Orthanc::EmbeddedResources::FileResourceId>  fonts_;
-  public:
-    RadiographyTextLayer(const RadiographyScene& scene) :
-      RadiographyAlphaLayer(scene)
-    {
-    }
-
-    void SetText(const std::string& utf8, const std::string& font, unsigned int fontSize, uint8_t foregroundGreyLevel);
-
-    const std::string& GetText() const
-    {
-      return text_;
-    }
-
-    const std::string& GetFont() const
-    {
-      return font_;
-    }
-
-    unsigned int GetFontSize() const
-    {
-      return fontSize_;
-    }
-
-    uint8_t GetForegroundGreyLevel() const
-    {
-      return foregroundGreyLevel_;
-    }
-
-    static void RegisterFont(const std::string& name, Orthanc::EmbeddedResources::FileResourceId fontResourceId)
-    {
-      fonts_[name] = fontResourceId;
-    }
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyWidget.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,284 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "RadiographyWidget.h"
-
-#include <OrthancException.h>
-#include <Images/Image.h>
-#include <Images/ImageProcessing.h>
-
-#include "RadiographyMaskLayer.h"
-
-namespace OrthancStone
-{
-
-  bool RadiographyWidget::IsInvertedInternal() const
-  {
-    // MONOCHROME1 images must be inverted and the user can invert the 
-    // image, too -> XOR the two
-    return (scene_->GetPreferredPhotomotricDisplayMode() == 
-            RadiographyPhotometricDisplayMode_Monochrome1) ^ invert_; 
-  }
-
-  void RadiographyWidget::RenderBackground(
-    Orthanc::ImageAccessor& image, float minValue, float maxValue)
-  {
-    // wipe background before rendering
-    float backgroundValue = minValue;
-
-    switch (scene_->GetPreferredPhotomotricDisplayMode())
-    {
-    case RadiographyPhotometricDisplayMode_Monochrome1:
-    case RadiographyPhotometricDisplayMode_Default:
-      if (IsInvertedInternal())
-        backgroundValue = maxValue;
-      else
-        backgroundValue = minValue;
-      break;
-    case RadiographyPhotometricDisplayMode_Monochrome2:
-      if (IsInvertedInternal())
-        backgroundValue = minValue;
-      else
-        backgroundValue = maxValue;
-      break;
-    default:
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
-    }
-
-    Orthanc::ImageProcessing::Set(image, static_cast<int64_t>(backgroundValue));
-  }
-
-  bool RadiographyWidget::RenderInternal(unsigned int width,
-                                         unsigned int height,
-                                         ImageInterpolation interpolation)
-  {
-    if (floatBuffer_.get() == NULL ||
-        floatBuffer_->GetWidth() != width ||
-        floatBuffer_->GetHeight() != height)
-    {
-      floatBuffer_.reset(new Orthanc::Image(
-        Orthanc::PixelFormat_Float32, width, height, false));
-
-      if (floatBuffer_.get() == NULL)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_NotEnoughMemory, "RadiographyWidget::RenderInternal: unable to allocate float buffer");
-      }
-    }
-
-    if (cairoBuffer_.get() == NULL ||
-        cairoBuffer_->GetWidth() != width ||
-        cairoBuffer_->GetHeight() != height)
-    {
-      cairoBuffer_.reset(new CairoSurface(width, height, false /* no alpha */));
-
-      if (cairoBuffer_.get() == NULL)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_NotEnoughMemory, "RadiographyWidget::RenderInternal: unable to allocate cairo buffer");
-      }
-    }
-
-    RenderBackground(*floatBuffer_, 0.0, 65535.0);
-
-    scene_->Render(*floatBuffer_, GetView().GetMatrix(), interpolation, true);
-
-    // Conversion from Float32 to BGRA32 (cairo). Very similar to
-    // GrayscaleFrameRenderer => TODO MERGE?
-    Orthanc::ImageAccessor target;
-    cairoBuffer_->GetWriteableAccessor(target);
-
-    bool invert = IsInvertedInternal();
-
-    for (unsigned int y = 0; y < height; y++)
-    {
-      const float* p = reinterpret_cast<const float*>(floatBuffer_->GetConstRow(y));
-      uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
-
-      for (unsigned int x = 0; x < width; x++, p++, q += 4)
-      {
-        uint8_t v = 0;
-        if (*p >= 65535.0)
-        {
-          v = 255;
-        }
-        else if (*p <= 0.0)
-        {
-          v = 0;
-        }
-        else
-        {
-          v = static_cast<uint8_t>(*p / 256.0);
-        }
-
-        if (invert)
-        {
-          v = 255 - v;
-        }
-
-        q[0] = v;
-        q[1] = v;
-        q[2] = v;
-        q[3] = 255;
-      }
-    }
-
-    return true;
-  }
-
-
-  bool RadiographyWidget::RenderScene(CairoContext& context,
-                                      const Deprecated::ViewportGeometry& view)
-  {
-    cairo_t* cr = context.GetObject();
-
-    if (RenderInternal(context.GetWidth(), context.GetHeight(), interpolation_))
-    {
-      // https://www.cairographics.org/FAQ/#paint_from_a_surface
-      cairo_save(cr);
-      cairo_identity_matrix(cr);
-      cairo_set_source_surface(cr, cairoBuffer_->GetObject(), 0, 0);
-      cairo_paint(cr);
-      cairo_restore(cr);
-    }
-    else
-    {
-      // https://www.cairographics.org/FAQ/#clear_a_surface
-      context.SetSourceColor(0, 0, 0);
-      cairo_paint(cr);
-    }
-
-    if (hasSelection_)
-    {
-      scene_->DrawBorder(
-        context, static_cast<unsigned int>(selectedLayer_), view.GetZoom());
-    }
-
-    return true;
-  }
-
-
-  RadiographyWidget::RadiographyWidget(boost::shared_ptr<RadiographyScene> scene,
-                                       const std::string& name) :
-    WorldSceneWidget(name),
-    invert_(false),
-    interpolation_(ImageInterpolation_Nearest),
-    hasSelection_(false),
-    selectedLayer_(0)    // Dummy initialization
-  {
-    SetScene(scene);
-  }
-
-
-  void RadiographyWidget::Select(size_t layer)
-  {
-    hasSelection_ = true;
-    selectedLayer_ = layer;
-
-    NotifyContentChanged();
-    BroadcastMessage(SelectionChangedMessage(*this));
-  }
-
-  void RadiographyWidget::Unselect()
-  {
-    hasSelection_ = false;
-
-    NotifyContentChanged();
-    BroadcastMessage(SelectionChangedMessage(*this));
-  }
-
-  bool RadiographyWidget::LookupSelectedLayer(size_t& layer) const
-  {
-    if (hasSelection_)
-    {
-      layer = selectedLayer_;
-      return true;
-    }
-    else
-    {
-      return false;
-    }
-  }
-
-  
-  void RadiographyWidget::OnGeometryChanged(const RadiographyScene::GeometryChangedMessage& message)
-  {
-//    LOG(INFO) << "Scene geometry has changed";
-    FitContent();
-  }
-
-  
-  void RadiographyWidget::OnContentChanged(const RadiographyScene::ContentChangedMessage& message)
-  {
-//    LOG(INFO) << "Scene content has changed";
-    NotifyContentChanged();
-  }
-
-  void RadiographyWidget::OnLayerRemoved(const RadiographyScene::LayerRemovedMessage& message)
-  {
-    size_t removedLayerIndex = message.GetLayerIndex();
-    if (hasSelection_ && selectedLayer_ == removedLayerIndex)
-    {
-      Unselect();
-    }
-    NotifyContentChanged();
-  }
-  
-  void RadiographyWidget::SetInvert(bool invert)
-  {
-    if (invert_ != invert)
-    {
-      invert_ = invert;
-      NotifyContentChanged();
-    }
-  }
-
-  
-    void RadiographyWidget::SwitchInvert()
-  {
-    invert_ = !invert_;
-    NotifyContentChanged();
-  }
-
-
-  void RadiographyWidget::SetInterpolation(ImageInterpolation interpolation)
-  {
-    if (interpolation_ != interpolation)
-    {
-      interpolation_ = interpolation;
-      NotifyContentChanged();
-    }
-  }
-
-  void RadiographyWidget::SetScene(boost::shared_ptr<RadiographyScene> scene)
-  {
-    scene_ = scene;
-
-    Register<RadiographyScene::GeometryChangedMessage>(*scene_, &RadiographyWidget::OnGeometryChanged);
-    Register<RadiographyScene::ContentChangedMessage>(*scene_, &RadiographyWidget::OnContentChanged);
-    Register<RadiographyScene::LayerRemovedMessage>(*scene_, &RadiographyWidget::OnLayerRemoved);
-
-    Unselect();
-
-    NotifyContentChanged();
-
-    // force redraw
-    FitContent();
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyWidget.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../Deprecated/Widgets/WorldSceneWidget.h"
-#include "../Messages/ObserverBase.h"
-#include "RadiographyScene.h"
-
-
-namespace OrthancStone
-{
-  class RadiographyMaskLayer;
-
-  class RadiographyWidget :
-    public Deprecated::WorldSceneWidget,
-    public ObserverBase<RadiographyWidget>,
-    public IObservable
-  {
-  public:
-    ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, SelectionChangedMessage, RadiographyWidget);
-
-  private:
-    boost::shared_ptr<RadiographyScene>    scene_;
-    std::unique_ptr<Orthanc::ImageAccessor>  floatBuffer_;
-    std::unique_ptr<CairoSurface>            cairoBuffer_;
-    bool                                   invert_;
-    ImageInterpolation                     interpolation_;
-    bool                                   hasSelection_;
-    size_t                                 selectedLayer_;
-
-    bool RenderInternal(unsigned int width,
-                        unsigned int height,
-                        ImageInterpolation interpolation);
-
-  protected:
-    virtual Extent2D GetSceneExtent()
-    {
-      return scene_->GetSceneExtent(false);
-    }
-
-    virtual bool RenderScene(CairoContext& context,
-                             const Deprecated::ViewportGeometry& view);
-
-    virtual void RenderBackground(Orthanc::ImageAccessor& image, float minValue, float maxValue);
-
-    bool IsInvertedInternal() const;
-
-  public:
-    RadiographyWidget(boost::shared_ptr<RadiographyScene> scene,  // TODO: check how we can avoid boost::shared_ptr here since we don't want them in the public API (app is keeping a boost::shared_ptr to this right now)
-                      const std::string& name);
-
-    RadiographyScene& GetScene() const
-    {
-      return *scene_;
-    }
-
-    void SetScene(boost::shared_ptr<RadiographyScene> scene);
-
-    void Select(size_t layer);
-
-    void Unselect();
-
-    template<typename LayerType> bool SelectLayerByType(size_t index = 0);
-
-    bool LookupSelectedLayer(size_t& layer) const;
-
-    void OnGeometryChanged(const RadiographyScene::GeometryChangedMessage& message);
-
-    void OnContentChanged(const RadiographyScene::ContentChangedMessage& message);
-
-    void OnLayerRemoved(const RadiographyScene::LayerRemovedMessage& message);
-
-    void SetInvert(bool invert);
-
-    void SwitchInvert();
-
-    bool IsInverted() const
-    {
-      return invert_;
-    }
-
-    void SetInterpolation(ImageInterpolation interpolation);
-
-    ImageInterpolation GetInterpolation() const
-    {
-      return interpolation_;
-    }
-  };
-
-  template<typename LayerType> bool RadiographyWidget::SelectLayerByType(size_t index)
-  {
-    std::vector<size_t> layerIndexes;
-    size_t count = 0;
-    scene_->GetLayersIndexes(layerIndexes);
-
-    for (size_t i = 0; i < layerIndexes.size(); ++i)
-    {
-      const LayerType* typedLayer = dynamic_cast<const LayerType*>(&(scene_->GetLayer(layerIndexes[i])));
-      if (typedLayer != NULL)
-      {
-        if (count == index)
-        {
-          Select(layerIndexes[i]);
-          return true;
-        }
-        count++;
-      }
-    }
-
-    return false;
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyWindowingTracker.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,192 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "RadiographyWindowingTracker.h"
-#include "RadiographyWidget.h"
-
-#include <OrthancException.h>
-
-
-namespace OrthancStone
-{
-  class RadiographyWindowingTracker::UndoRedoCommand : public UndoRedoStack::ICommand
-  {
-  private:
-    RadiographyScene&  scene_;
-    float              sourceCenter_;
-    float              sourceWidth_;
-    float              targetCenter_;
-    float              targetWidth_;
-
-  public:
-    UndoRedoCommand(const RadiographyWindowingTracker& tracker) :
-      scene_(tracker.scene_),
-      sourceCenter_(tracker.sourceCenter_),
-      sourceWidth_(tracker.sourceWidth_)
-    {
-      scene_.GetWindowingWithDefault(targetCenter_, targetWidth_);
-    }
-
-    virtual void Undo() const
-    {
-      scene_.SetWindowing(sourceCenter_, sourceWidth_);
-    }
-      
-    virtual void Redo() const
-    {
-      scene_.SetWindowing(targetCenter_, targetWidth_);
-    }
-  };
-
-
-  void RadiographyWindowingTracker::ComputeAxisEffect(int& deltaCenter,
-                                                      int& deltaWidth,
-                                                      int delta,
-                                                      Action actionNegative,
-                                                      Action actionPositive)
-  {
-    if (delta < 0)
-    {
-      switch (actionNegative)
-      {
-        case Action_IncreaseWidth:
-          deltaWidth = -delta;
-          break;
-
-        case Action_DecreaseWidth:
-          deltaWidth = delta;
-          break;
-
-        case Action_IncreaseCenter:
-          deltaCenter = -delta;
-          break;
-
-        case Action_DecreaseCenter:
-          deltaCenter = delta;
-          break;
-
-        default:
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-      }
-    }
-    else if (delta > 0)
-    {
-      switch (actionPositive)
-      {
-        case Action_IncreaseWidth:
-          deltaWidth = delta;
-          break;
-
-        case Action_DecreaseWidth:
-          deltaWidth = -delta;
-          break;
-
-        case Action_IncreaseCenter:
-          deltaCenter = delta;
-          break;
-
-        case Action_DecreaseCenter:
-          deltaCenter = -delta;
-          break;
-
-        default:
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-      }
-    }
-  }
-    
-    
-  RadiographyWindowingTracker::RadiographyWindowingTracker(UndoRedoStack& undoRedoStack,
-                                                           RadiographyScene& scene,
-                                                           RadiographyWidget& widget,
-                                                           ImageInterpolation interpolationDuringTracking,
-                                                           int x,
-                                                           int y,
-                                                           Action leftAction,
-                                                           Action rightAction,
-                                                           Action upAction,
-                                                           Action downAction) :
-    undoRedoStack_(undoRedoStack),
-    scene_(scene),
-    widget_(widget),
-    initialWidgetInterpolation_(widget.GetInterpolation()),
-    clickX_(x),
-    clickY_(y),
-    leftAction_(leftAction),
-    rightAction_(rightAction),
-    upAction_(upAction),
-    downAction_(downAction)
-  {
-    scene_.GetWindowingWithDefault(sourceCenter_, sourceWidth_);
-    widget_.SetInterpolation(interpolationDuringTracking);
-
-    float minValue, maxValue;
-    scene.GetRange(minValue, maxValue);
-
-    assert(minValue <= maxValue);
-
-    float delta = (maxValue - minValue);
-    strength_ = delta / 1000.0f; // 1px move will change the ww/wc by 0.1%
-
-    if (strength_ < 1)
-    {
-      strength_ = 1;
-    }
-  }
-
-
-  void RadiographyWindowingTracker::Render(CairoContext& context,
-                                           double zoom)
-  {
-    throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-  }
-  
-
-  void RadiographyWindowingTracker::MouseUp()
-  {
-    widget_.SetInterpolation(initialWidgetInterpolation_);
-    undoRedoStack_.Add(new UndoRedoCommand(*this));
-  }
-
-
-  void RadiographyWindowingTracker::MouseMove(int displayX,
-                                              int displayY,
-                                              double sceneX,
-                                              double sceneY,
-                                              const std::vector<Deprecated::Touch>& displayTouches,
-                                              const std::vector<Deprecated::Touch>& sceneTouches)
-  {
-    // This follows the behavior of the Osimis Web viewer:
-    // https://bitbucket.org/osimis/osimis-webviewer-plugin/src/master/frontend/src/app/viewport/image-plugins/windowing-viewport-tool.class.js
-
-    static const float SCALE = 1.0;
-      
-    int deltaCenter = 0;
-    int deltaWidth = 0;
-
-    ComputeAxisEffect(deltaCenter, deltaWidth, displayX - clickX_, leftAction_, rightAction_);
-    ComputeAxisEffect(deltaCenter, deltaWidth, displayY - clickY_, upAction_, downAction_);
-
-    float newCenter = sourceCenter_ + (deltaCenter / SCALE * strength_);
-    float newWidth = sourceWidth_ + (deltaWidth / SCALE * strength_);
-    scene_.SetWindowing(newCenter, newWidth);
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Radiography/RadiographyWindowingTracker.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../Toolbox/UndoRedoStack.h"
-#include "../Deprecated/Widgets/IWorldSceneMouseTracker.h"
-#include "RadiographyScene.h"
-
-namespace OrthancStone
-{
-
-  class RadiographyWidget;
-
-  class RadiographyWindowingTracker : public Deprecated::IWorldSceneMouseTracker
-  {   
-  public:
-    enum Action
-    {
-      Action_IncreaseWidth,
-      Action_DecreaseWidth,
-      Action_IncreaseCenter,
-      Action_DecreaseCenter
-    };
-    
-  private:
-    class UndoRedoCommand;
-
-    UndoRedoStack&      undoRedoStack_;
-    RadiographyScene&   scene_;
-    RadiographyWidget&  widget_;
-    ImageInterpolation  initialWidgetInterpolation_;
-    int                 clickX_;
-    int                 clickY_;
-    Action              leftAction_;
-    Action              rightAction_;
-    Action              upAction_;
-    Action              downAction_;
-    float               strength_;
-    float               sourceCenter_;
-    float               sourceWidth_;
-
-    static void ComputeAxisEffect(int& deltaCenter,
-                                  int& deltaWidth,
-                                  int delta,
-                                  Action actionNegative,
-                                  Action actionPositive);    
-    
-  public:
-    RadiographyWindowingTracker(UndoRedoStack& undoRedoStack,
-                                RadiographyScene& scene,
-                                RadiographyWidget& widget,
-                                ImageInterpolation interpolationDuringTracking,
-                                int x,
-                                int y,
-                                Action leftAction,
-                                Action rightAction,
-                                Action upAction,
-                                Action downAction);
-    
-    virtual bool HasRender() const
-    {
-      return false;
-    }
-
-    virtual void Render(CairoContext& context,
-                        double zoom);
-
-    virtual void MouseUp();
-
-    virtual void MouseMove(int displayX,
-                           int displayY,
-                           double sceneX,
-                           double sceneY,
-                           const std::vector<Deprecated::Touch>& displayTouches,
-                           const std::vector<Deprecated::Touch>& sceneTouches);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/SmartLoader.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,285 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "SmartLoader.h"
-
-#include "../StoneException.h"
-#include "Layers/DicomSeriesVolumeSlicer.h"
-#include "Layers/FrameRenderer.h"
-#include "Widgets/SliceViewerWidget.h"
-
-#include <Images/Image.h>
-#include <Logging.h>
-
-namespace Deprecated
-{
-  enum CachedSliceStatus
-  {
-    CachedSliceStatus_ScheduledToLoad,
-    CachedSliceStatus_GeometryLoaded,
-    CachedSliceStatus_ImageLoaded
-  };
-
-  class SmartLoader::CachedSlice : public IVolumeSlicer
-  {
-  public:
-    class RendererFactory : public LayerReadyMessage::IRendererFactory
-    {
-    private:
-      const CachedSlice&  that_;
-
-    public:
-      RendererFactory(const CachedSlice& that) :
-        that_(that)
-      {
-      }
-
-      virtual ILayerRenderer* CreateRenderer() const
-      {
-        bool isFull = (that_.effectiveQuality_ == SliceImageQuality_FullPng ||
-                       that_.effectiveQuality_ == SliceImageQuality_FullPam);
-
-        return FrameRenderer::CreateRenderer(*that_.image_, *that_.slice_, isFull);
-      }
-    };
-    
-    unsigned int                    sliceIndex_;
-    std::unique_ptr<Slice>            slice_;
-    boost::shared_ptr<Orthanc::ImageAccessor>   image_;
-    SliceImageQuality               effectiveQuality_;
-    CachedSliceStatus               status_;
-
-  public:
-    virtual ~CachedSlice()
-    {
-    }
-
-    virtual bool GetExtent(std::vector<OrthancStone::Vector>& points,
-                           const OrthancStone::CoordinateSystem3D& viewportSlice)
-    {
-      // TODO: viewportSlice is not used !!!!
-      slice_->GetExtent(points);
-      return true;
-    }
-
-    virtual void ScheduleLayerCreation(const OrthancStone::CoordinateSystem3D& viewportSlice)
-    {
-      // TODO: viewportSlice is not used !!!!
-
-      // it has already been loaded -> trigger the "layer ready" message immediately otherwise, do nothing now.  The LayerReady will be triggered
-      // once the VolumeSlicer is ready
-      if (status_ == CachedSliceStatus_ImageLoaded)
-      {
-        LOG(WARNING) << "ScheduleLayerCreation for CachedSlice (image is loaded): " << slice_->GetOrthancInstanceId();
-
-        RendererFactory factory(*this);   
-        BroadcastMessage(IVolumeSlicer::LayerReadyMessage(*this, factory, slice_->GetGeometry()));
-      }
-      else
-      {
-        LOG(WARNING) << "ScheduleLayerCreation for CachedSlice (image is not loaded yet): " << slice_->GetOrthancInstanceId();
-      }
-    }
-
-    CachedSlice* Clone() const
-    {
-      CachedSlice* output = new CachedSlice;
-      output->sliceIndex_ = sliceIndex_;
-      output->slice_.reset(slice_->Clone());
-      output->image_ = image_;
-      output->effectiveQuality_ = effectiveQuality_;
-      output->status_ = status_;
-
-      return output;
-    }
-
-  };
-
-
-  SmartLoader::SmartLoader(boost::shared_ptr<OrthancApiClient> orthancApiClient) :
-    imageQuality_(SliceImageQuality_FullPam),
-    orthancApiClient_(orthancApiClient)
-  {
-  }
-
-  void SmartLoader::SetFrameInWidget(SliceViewerWidget& sliceViewer, 
-                                     size_t layerIndex, 
-                                     const std::string& instanceId, 
-                                     unsigned int frame)
-  {
-    // TODO: check if this frame has already been loaded or is already being loaded.
-    // - if already loaded: create a "clone" that will emit the GeometryReady/ImageReady messages "immediately"
-    //   (it can not be immediate because Observers needs to register first and this is done after this method returns)
-    // - if currently loading, we need to return an object that will observe the existing VolumeSlicer and forward
-    //   the messages to its observables
-    // in both cases, we must be carefull about objects lifecycle !!!
-
-    boost::shared_ptr<IVolumeSlicer> layerSource;
-    std::string sliceKeyId = instanceId + ":" + boost::lexical_cast<std::string>(frame);
-    SmartLoader::CachedSlice* cachedSlice = NULL;
-
-    if (cachedSlices_.find(sliceKeyId) != cachedSlices_.end()) // && cachedSlices_[sliceKeyId]->status_ == CachedSliceStatus_Loaded)
-    {
-      layerSource.reset(cachedSlices_[sliceKeyId]->Clone());
-      cachedSlice = dynamic_cast<SmartLoader::CachedSlice*>(layerSource.get());
-    }
-    else
-    {
-      layerSource.reset(new DicomSeriesVolumeSlicer);
-      dynamic_cast<DicomSeriesVolumeSlicer*>(layerSource.get())->Connect(orthancApiClient_);
-      dynamic_cast<DicomSeriesVolumeSlicer*>(layerSource.get())->SetImageQuality(imageQuality_);
-      Register<IVolumeSlicer::GeometryReadyMessage>(*layerSource, &SmartLoader::OnLayerGeometryReady);
-      Register<DicomSeriesVolumeSlicer::FrameReadyMessage>(*layerSource, &SmartLoader::OnFrameReady);
-      Register<IVolumeSlicer::LayerReadyMessage>(*layerSource, &SmartLoader::OnLayerReady);
-      dynamic_cast<DicomSeriesVolumeSlicer*>(layerSource.get())->LoadFrame(instanceId, frame);
-    }
-
-    // make sure that the widget registers the events before we trigger them
-    if (sliceViewer.GetLayerCount() == layerIndex)
-    {
-      sliceViewer.AddLayer(layerSource);
-    }
-    else if (sliceViewer.GetLayerCount() > layerIndex)
-    {
-      sliceViewer.ReplaceLayer(layerIndex, layerSource);
-    }
-    else
-    {
-      throw OrthancStone::StoneException(OrthancStone::ErrorCode_CanOnlyAddOneLayerAtATime);
-    }
-
-    if (cachedSlice != NULL)
-    {
-      BroadcastMessage(IVolumeSlicer::GeometryReadyMessage(*cachedSlice));
-    }
-
-  }
-
-  void SmartLoader::PreloadSlice(const std::string instanceId, 
-                                 unsigned int frame)
-  {
-    // TODO: reactivate -> need to be able to ScheduleLayerLoading in IVolumeSlicer without calling ScheduleLayerCreation
-    return;
-    // TODO: check if it is already in the cache
-
-
-
-    // create the slice in the cache with "empty" data
-    boost::shared_ptr<CachedSlice> cachedSlice(new CachedSlice);
-    cachedSlice->slice_.reset(new Slice(instanceId, frame));
-    cachedSlice->status_ = CachedSliceStatus_ScheduledToLoad;
-    std::string sliceKeyId = instanceId + ":" + boost::lexical_cast<std::string>(frame);
-
-    LOG(WARNING) << "Will preload: " << sliceKeyId;
-
-    cachedSlices_[sliceKeyId] = boost::shared_ptr<CachedSlice>(cachedSlice);
-
-    std::unique_ptr<IVolumeSlicer> layerSource(new DicomSeriesVolumeSlicer);
-    dynamic_cast<DicomSeriesVolumeSlicer*>(layerSource.get())->Connect(orthancApiClient_);
-    dynamic_cast<DicomSeriesVolumeSlicer*>(layerSource.get())->SetImageQuality(imageQuality_);
-    Register<IVolumeSlicer::GeometryReadyMessage>(*layerSource, &SmartLoader::OnLayerGeometryReady);
-    Register<DicomSeriesVolumeSlicer::FrameReadyMessage>(*layerSource, &SmartLoader::OnFrameReady);
-    Register<IVolumeSlicer::LayerReadyMessage>(*layerSource, &SmartLoader::OnLayerReady);
-    dynamic_cast<DicomSeriesVolumeSlicer*>(layerSource.get())->LoadFrame(instanceId, frame);
-
-    // keep a ref to the VolumeSlicer until the slice is fully loaded and saved to cache
-    preloadingInstances_[sliceKeyId] = boost::shared_ptr<IVolumeSlicer>(layerSource.release());
-  }
-
-
-//  void PreloadStudy(const std::string studyId)
-//  {
-//    /* TODO */
-//  }
-
-//  void PreloadSeries(const std::string seriesId)
-//  {
-//    /* TODO */
-//  }
-
-
-  void SmartLoader::OnLayerGeometryReady(const IVolumeSlicer::GeometryReadyMessage& message)
-  {
-    const DicomSeriesVolumeSlicer& source =
-      dynamic_cast<const DicomSeriesVolumeSlicer&>(message.GetOrigin());
-
-    // save/replace the slice in cache
-    const Slice& slice = source.GetSlice(0); // TODO handle GetSliceCount()
-    std::string sliceKeyId = (slice.GetOrthancInstanceId() + ":" + 
-                              boost::lexical_cast<std::string>(slice.GetFrame()));
-
-    LOG(WARNING) << "Geometry ready: " << sliceKeyId;
-
-    boost::shared_ptr<CachedSlice> cachedSlice(new CachedSlice);
-    cachedSlice->slice_.reset(slice.Clone());
-    cachedSlice->effectiveQuality_ = source.GetImageQuality();
-    cachedSlice->status_ = CachedSliceStatus_GeometryLoaded;
-
-    cachedSlices_[sliceKeyId] = boost::shared_ptr<CachedSlice>(cachedSlice);
-
-    // re-emit original Layer message to observers
-    BroadcastMessage(message);
-  }
-
-
-  void SmartLoader::OnFrameReady(const DicomSeriesVolumeSlicer::FrameReadyMessage& message)
-  {
-    // save/replace the slice in cache
-    const Slice& slice = message.GetSlice();
-    std::string sliceKeyId = (slice.GetOrthancInstanceId() + ":" + 
-                              boost::lexical_cast<std::string>(slice.GetFrame()));
-
-    LOG(WARNING) << "Image ready: " << sliceKeyId;
-
-    boost::shared_ptr<CachedSlice> cachedSlice(new CachedSlice);
-    cachedSlice->image_.reset(Orthanc::Image::Clone(message.GetFrame()));
-    cachedSlice->effectiveQuality_ = message.GetImageQuality();
-    cachedSlice->slice_.reset(message.GetSlice().Clone());
-    cachedSlice->status_ = CachedSliceStatus_ImageLoaded;
-
-    cachedSlices_[sliceKeyId] = cachedSlice;
-
-    // re-emit original Layer message to observers
-    BroadcastMessage(message);
-  }
-
-
-  void SmartLoader::OnLayerReady(const IVolumeSlicer::LayerReadyMessage& message)
-  {
-    const DicomSeriesVolumeSlicer& source =
-      dynamic_cast<const DicomSeriesVolumeSlicer&>(message.GetOrigin());
-    
-    const Slice& slice = source.GetSlice(0); // TODO handle GetSliceCount() ?
-    std::string sliceKeyId = (slice.GetOrthancInstanceId() + ":" + 
-                              boost::lexical_cast<std::string>(slice.GetFrame()));
-
-    LOG(WARNING) << "Layer ready: " << sliceKeyId;
-
-    // remove the slice from the preloading slices now that it has been fully loaded and it is referenced in the cache
-    if (preloadingInstances_.find(sliceKeyId) != preloadingInstances_.end())
-    {
-      preloadingInstances_.erase(sliceKeyId);
-    }
-
-    // re-emit original Layer message to observers
-    BroadcastMessage(message);
-  }
-}
--- a/OrthancStone/Sources/Deprecated/SmartLoader.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-#include <map>
-
-#include "Layers/DicomSeriesVolumeSlicer.h"
-#include "../Messages/IObservable.h"
-#include "Toolbox/OrthancApiClient.h"
-
-namespace Deprecated
-{
-  class SliceViewerWidget;
-
-  class SmartLoader : public OrthancStone::IObservable, public OrthancStone::ObserverBase<SmartLoader>
-  {
-    class CachedSlice;
-
-  protected:
-    typedef std::map<std::string, boost::shared_ptr<SmartLoader::CachedSlice> > CachedSlices;
-    CachedSlices cachedSlices_;
-
-    typedef std::map<std::string, boost::shared_ptr<IVolumeSlicer> > PreloadingInstances;
-    PreloadingInstances preloadingInstances_;
-
-    SliceImageQuality     imageQuality_;
-    boost::shared_ptr<OrthancApiClient>  orthancApiClient_;
-
-  public:
-    SmartLoader(boost::shared_ptr<OrthancApiClient> orthancApiClient);  // TODO: add maxPreloadStorageSizeInBytes
-
-//    void PreloadStudy(const std::string studyId);
-//    void PreloadSeries(const std::string seriesId);
-    void PreloadSlice(const std::string instanceId, unsigned int frame);
-
-    void SetImageQuality(SliceImageQuality imageQuality) { imageQuality_ = imageQuality; }
-
-    void SetFrameInWidget(SliceViewerWidget& sliceViewer, size_t layerIndex, const std::string& instanceId, unsigned int frame);
-
-    void GetFirstInstanceIdForSeries(std::string& output, const std::string& seriesId);
-
-  private:
-    void OnLayerGeometryReady(const IVolumeSlicer::GeometryReadyMessage& message);
-    void OnFrameReady(const DicomSeriesVolumeSlicer::FrameReadyMessage& message);
-    void OnLayerReady(const IVolumeSlicer::LayerReadyMessage& message);
-
-  };
-
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/BaseWebService.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,178 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "BaseWebService.h"
-
-#include "../../Messages/IObservable.h"
-#include "../../../Platforms/Generic/IOracleCommand.h"
-
-#include <OrthancException.h>
-
-#include <boost/shared_ptr.hpp>
-#include <algorithm>
-#include <Logging.h>
-
-namespace Deprecated
-{
-
-
-  class BaseWebService::BaseWebServicePayload : public Orthanc::IDynamicObject
-  {
-  private:
-    std::unique_ptr< MessageHandler<IWebService::HttpRequestSuccessMessage> >   userSuccessHandler_;
-    std::unique_ptr< MessageHandler<IWebService::HttpRequestErrorMessage> >     userFailureHandler_;
-    std::unique_ptr< Orthanc::IDynamicObject>                                   userPayload_;
-
-  public:
-    BaseWebServicePayload(MessageHandler<IWebService::HttpRequestSuccessMessage>* userSuccessHandler,
-                          MessageHandler<IWebService::HttpRequestErrorMessage>* userFailureHandler,
-                          Orthanc::IDynamicObject* userPayload) :
-      userSuccessHandler_(userSuccessHandler),
-      userFailureHandler_(userFailureHandler),
-      userPayload_(userPayload)
-    {
-    }
-
-    void HandleSuccess(const IWebService::HttpRequestSuccessMessage& message) const
-    {
-      if (userSuccessHandler_.get() != NULL)
-      {
-        // recreate a success message with the user payload
-        IWebService::HttpRequestSuccessMessage successMessage(message.GetUri(),
-                                                              message.GetAnswer(),
-                                                              message.GetAnswerSize(),
-                                                              message.GetAnswerHttpHeaders(),
-                                                              userPayload_.get());
-        userSuccessHandler_->Apply(successMessage);
-      }
-      else
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-      }
-    }
-
-    void HandleFailure(const IWebService::HttpRequestErrorMessage& message) const
-    {
-      if (userFailureHandler_.get() != NULL)
-      {
-        // recreate a failure message with the user payload
-        IWebService::HttpRequestErrorMessage failureMessage(message.GetUri(),
-                                                            message.GetHttpStatus(),
-                                                            userPayload_.get());
-
-        userFailureHandler_->Apply(failureMessage);
-      }
-    }
-
-  };
-
-
-  void BaseWebService::GetAsync(const std::string& uri,
-                                const HttpHeaders& headers,
-                                Orthanc::IDynamicObject* payload  /* takes ownership */,
-                                MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback,
-                                MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback,
-                                unsigned int timeoutInSeconds)
-  {
-    if (!cacheEnabled_ || cache_.find(uri) == cache_.end())
-    {
-      GetAsyncInternal(uri, headers,
-                       new BaseWebService::BaseWebServicePayload(successCallback, failureCallback, payload), // ownership is transfered
-                       new DeprecatedCallable<BaseWebService, IWebService::HttpRequestSuccessMessage>
-                       (GetSharedObserver(), &BaseWebService::CacheAndNotifyHttpSuccess),
-                       new DeprecatedCallable<BaseWebService, IWebService::HttpRequestErrorMessage>
-                       (GetSharedObserver(), &BaseWebService::NotifyHttpError),
-                       timeoutInSeconds);
-    }
-    else
-    {
-      // put the uri on top of the most recently accessed list
-      std::deque<std::string>::iterator it = std::find(orderedCacheKeys_.begin(), orderedCacheKeys_.end(), uri);
-      if (it != orderedCacheKeys_.end())
-      {
-        std::string uri = *it;
-        orderedCacheKeys_.erase(it);
-        orderedCacheKeys_.push_front(uri);
-      }
-
-      // create a command and "post" it to the Oracle so it is executed and commited "later"
-      NotifyHttpSuccessLater(cache_[uri], payload, successCallback);
-    }
-
-  }
-
-
-
-  void BaseWebService::NotifyHttpSuccess(const IWebService::HttpRequestSuccessMessage& message)
-  {
-    if (message.HasPayload())
-    {
-      dynamic_cast<const BaseWebServicePayload&>(message.GetPayload()).HandleSuccess(message);
-    }
-    else
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-    }
-  }
-
-  void BaseWebService::CacheAndNotifyHttpSuccess(const IWebService::HttpRequestSuccessMessage& message)
-  {
-    if (cacheEnabled_)
-    {
-      while (cacheCurrentSize_ + message.GetAnswerSize() > cacheMaxSize_ && orderedCacheKeys_.size() > 0)
-      {
-        VLOG(1) << "BaseWebService: clearing cache: " << cacheCurrentSize_ << "/" << cacheMaxSize_ << "(" << message.GetAnswerSize() << ")";
-        const std::string& oldestUri = orderedCacheKeys_.back();
-        HttpCache::iterator it = cache_.find(oldestUri);
-        if (it != cache_.end())
-        {
-          cacheCurrentSize_ -= it->second->GetAnswerSize();
-          cache_.erase(it);
-        }
-        orderedCacheKeys_.pop_back();
-
-      }
-
-      boost::shared_ptr<CachedHttpRequestSuccessMessage> cachedMessage(new CachedHttpRequestSuccessMessage(message));
-      cache_[message.GetUri()] = cachedMessage;
-      orderedCacheKeys_.push_front(message.GetUri());
-      cacheCurrentSize_ += message.GetAnswerSize();
-    }
-
-    NotifyHttpSuccess(message);
-  }
-
-  void BaseWebService::NotifyHttpError(const IWebService::HttpRequestErrorMessage& message)
-  {
-    if (message.HasPayload())
-    {
-      dynamic_cast<const BaseWebServicePayload&>(message.GetPayload()).HandleFailure(message);
-    }
-    else
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-    }
-  }
-
-
-
-
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/BaseWebService.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "IWebService.h"
-#include "../../Messages/ObserverBase.h"
-
-#include <string>
-#include <map>
-#include <deque>
-
-namespace Deprecated
-{
-  // This is an intermediate of IWebService that implements some caching on
-  // the HTTP GET requests
-  class BaseWebService : public IWebService, public OrthancStone::ObserverBase<BaseWebService>
-  {
-  public:
-    class CachedHttpRequestSuccessMessage
-    {
-    protected:
-      std::string                    uri_;
-      void*                          answer_;
-      size_t                         answerSize_;
-      IWebService::HttpHeaders       answerHeaders_;
-
-    public:
-      CachedHttpRequestSuccessMessage(const IWebService::HttpRequestSuccessMessage& message) :
-        uri_(message.GetUri()),
-        answerSize_(message.GetAnswerSize()),
-        answerHeaders_(message.GetAnswerHttpHeaders())
-      {
-        answer_ =  malloc(answerSize_);
-        memcpy(answer_, message.GetAnswer(), answerSize_);
-      }
-
-      ~CachedHttpRequestSuccessMessage()
-      {
-        free(answer_);
-      }
-
-      const std::string& GetUri() const
-      {
-        return uri_;
-      }
-
-      const void* GetAnswer() const
-      {
-        return answer_;
-      }
-
-      size_t GetAnswerSize() const
-      {
-        return answerSize_;
-      }
-
-      const IWebService::HttpHeaders&  GetAnswerHttpHeaders() const
-      {
-        return answerHeaders_;
-      }
-
-    };
-  protected:
-    class BaseWebServicePayload;
-
-    bool          cacheEnabled_;
-    size_t        cacheCurrentSize_;
-    size_t        cacheMaxSize_;
-
-    typedef std::map<std::string, boost::shared_ptr<CachedHttpRequestSuccessMessage> > HttpCache;
-    HttpCache cache_;
-    std::deque<std::string> orderedCacheKeys_;
-
-  public:
-    BaseWebService() :
-      cacheEnabled_(false),
-      cacheCurrentSize_(0),
-      cacheMaxSize_(100*1024*1024)
-    {
-    }
-
-    virtual ~BaseWebService()
-    {
-    }
-
-    virtual void EnableCache(bool enable)
-    {
-      cacheEnabled_ = enable;
-    }
-
-    virtual void GetAsync(const std::string& uri,
-                          const HttpHeaders& headers,
-                          Orthanc::IDynamicObject* payload  /* takes ownership */,
-                          MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback,
-                          MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback = NULL,
-                          unsigned int timeoutInSeconds = 60);
-
-  protected:
-    virtual void GetAsyncInternal(const std::string& uri,
-                          const HttpHeaders& headers,
-                          Orthanc::IDynamicObject* payload  /* takes ownership */,
-                          MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback,
-                          MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback = NULL,
-                          unsigned int timeoutInSeconds = 60) = 0;
-
-    virtual void NotifyHttpSuccessLater(boost::shared_ptr<BaseWebService::CachedHttpRequestSuccessMessage> cachedHttpMessage,
-                                        Orthanc::IDynamicObject* payload, // takes ownership
-                                        MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback) = 0;
-
-  private:
-    void NotifyHttpSuccess(const IWebService::HttpRequestSuccessMessage& message);
-
-    void NotifyHttpError(const IWebService::HttpRequestErrorMessage& message);
-
-    void CacheAndNotifyHttpSuccess(const IWebService::HttpRequestSuccessMessage& message);
-
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/DicomFrameConverter.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,282 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "DicomFrameConverter.h"
-
-#include "../../Toolbox/LinearAlgebra.h"
-
-#include <Images/Image.h>
-#include <Images/ImageProcessing.h>
-#include <OrthancException.h>
-#include <Toolbox.h>
-
-namespace Deprecated
-{
-  static const Orthanc::DicomTag IMAGE_TAGS[] =
-  {
-    Orthanc::DICOM_TAG_BITS_STORED,
-    Orthanc::DICOM_TAG_DOSE_GRID_SCALING,
-    Orthanc::DICOM_TAG_PHOTOMETRIC_INTERPRETATION,
-    Orthanc::DICOM_TAG_PIXEL_REPRESENTATION,
-    Orthanc::DICOM_TAG_RESCALE_INTERCEPT,
-    Orthanc::DICOM_TAG_RESCALE_SLOPE,
-    Orthanc::DICOM_TAG_WINDOW_CENTER,
-    Orthanc::DICOM_TAG_WINDOW_WIDTH
-  };
-
-  
-  void DicomFrameConverter::SetDefaultParameters()
-  {
-    isSigned_ = true;
-    isColor_ = false;
-    hasRescale_ = false;
-    rescaleIntercept_ = 0;
-    rescaleSlope_ = 1;
-    hasDefaultWindow_ = false;
-    defaultWindowCenter_ = 128;
-    defaultWindowWidth_ = 256;
-    expectedPixelFormat_ = Orthanc::PixelFormat_Grayscale16;
-  }
-
-
-  void DicomFrameConverter::ReadParameters(const Orthanc::DicomMap& dicom)
-  {
-    SetDefaultParameters();
-
-    OrthancStone::Vector c, w;
-    if (OrthancStone::LinearAlgebra::ParseVector(c, dicom, Orthanc::DICOM_TAG_WINDOW_CENTER) &&
-        OrthancStone::LinearAlgebra::ParseVector(w, dicom, Orthanc::DICOM_TAG_WINDOW_WIDTH) &&
-        c.size() > 0 && 
-        w.size() > 0)
-    {
-      hasDefaultWindow_ = true;
-      defaultWindowCenter_ = static_cast<float>(c[0]);
-      defaultWindowWidth_ = static_cast<float>(w[0]);
-    }
-
-    int32_t tmp;
-    if (!dicom.ParseInteger32(tmp, Orthanc::DICOM_TAG_PIXEL_REPRESENTATION))
-    {
-      // Type 1 tag, must be present
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
-    }
-
-    isSigned_ = (tmp == 1);
-
-    double doseGridScaling;
-    bool isRTDose = false;
-    
-    if (dicom.ParseDouble(rescaleIntercept_, Orthanc::DICOM_TAG_RESCALE_INTERCEPT) &&
-        dicom.ParseDouble(rescaleSlope_, Orthanc::DICOM_TAG_RESCALE_SLOPE))
-    {
-      hasRescale_ = true;
-    }
-    else if (dicom.ParseDouble(doseGridScaling, Orthanc::DICOM_TAG_DOSE_GRID_SCALING))
-    {
-      // This is for RT-DOSE
-      hasRescale_ = true;
-      isRTDose = true;
-      rescaleIntercept_ = 0;
-      rescaleSlope_ = doseGridScaling;
-
-      if (!dicom.ParseInteger32(tmp, Orthanc::DICOM_TAG_BITS_STORED))
-      {
-        // Type 1 tag, must be present
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
-      }
-
-      switch (tmp)
-      {
-        case 16:
-          expectedPixelFormat_ = Orthanc::PixelFormat_Grayscale16;
-          break;
-
-        case 32:
-          expectedPixelFormat_ = Orthanc::PixelFormat_Grayscale32;
-          break;
-
-        default:
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
-      }
-    }
-
-    std::string photometric;
-    if (dicom.LookupStringValue(photometric, Orthanc::DICOM_TAG_PHOTOMETRIC_INTERPRETATION, false))
-    {
-      photometric = Orthanc::Toolbox::StripSpaces(photometric);
-    }
-    else
-    {
-      // Type 1 tag, must be present
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
-    }
-
-    photometric_ = Orthanc::StringToPhotometricInterpretation(photometric.c_str());
-    
-    isColor_ = (photometric != "MONOCHROME1" &&
-                photometric != "MONOCHROME2");
-
-    // TODO Add more checks, e.g. on the number of bytes per value
-    // (cf. DicomImageInformation.h in Orthanc)
-
-    if (!isRTDose)
-    {
-      if (isColor_)
-      {
-        expectedPixelFormat_ = Orthanc::PixelFormat_RGB24;
-      }
-      else if (isSigned_)
-      {
-        expectedPixelFormat_ = Orthanc::PixelFormat_SignedGrayscale16;
-      }
-      else
-      {
-        expectedPixelFormat_ = Orthanc::PixelFormat_Grayscale16;
-      }
-    }
-  }
-
-  
-  void DicomFrameConverter::ReadParameters(const OrthancPlugins::IDicomDataset& dicom)
-  {
-    Orthanc::DicomMap converted;
-
-    for (size_t i = 0; i < sizeof(IMAGE_TAGS) / sizeof(Orthanc::DicomTag); i++)
-    {
-      OrthancPlugins::DicomTag tag(IMAGE_TAGS[i].GetGroup(), IMAGE_TAGS[i].GetElement());
-    
-      std::string value;
-      if (dicom.GetStringValue(value, tag))
-      {
-        converted.SetValue(IMAGE_TAGS[i], value, false);
-      }
-    }
-
-    ReadParameters(converted);
-  }
-    
-
-  void DicomFrameConverter::ConvertFrameInplace(std::unique_ptr<Orthanc::ImageAccessor>& source) const
-  {
-    assert(sizeof(float) == 4);
-
-    if (source.get() == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    if (source->GetFormat() == GetExpectedPixelFormat() &&
-        source->GetFormat() == Orthanc::PixelFormat_RGB24)
-    {
-      // No conversion has to be done, check out (*)
-      return;
-    }
-    else
-    {
-      source.reset(ConvertFrame(*source));
-    }
-  }
-
-
-  Orthanc::ImageAccessor* DicomFrameConverter::ConvertFrame(const Orthanc::ImageAccessor& source) const
-  {
-    assert(sizeof(float) == 4);
-
-    Orthanc::PixelFormat sourceFormat = source.GetFormat();
-
-    if (sourceFormat != GetExpectedPixelFormat())
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat);
-    }
-
-    if (sourceFormat == Orthanc::PixelFormat_RGB24)
-    {
-      // This is the case of a color image. No conversion has to be done (*)
-      std::unique_ptr<Orthanc::Image> converted(new Orthanc::Image(Orthanc::PixelFormat_RGB24, 
-                                                                 source.GetWidth(), 
-                                                                 source.GetHeight(),
-                                                                 false));
-      Orthanc::ImageProcessing::Copy(*converted, source);
-      return converted.release();
-    }
-    else
-    {
-      assert(sourceFormat == Orthanc::PixelFormat_Grayscale16 ||
-             sourceFormat == Orthanc::PixelFormat_Grayscale32 ||
-             sourceFormat == Orthanc::PixelFormat_SignedGrayscale16);
-
-      // This is the case of a grayscale frame. Convert it to Float32.
-      std::unique_ptr<Orthanc::Image> converted(new Orthanc::Image(Orthanc::PixelFormat_Float32, 
-                                                                 source.GetWidth(), 
-                                                                 source.GetHeight(),
-                                                                 false));
-      Orthanc::ImageProcessing::Convert(*converted, source);
-
-      // Correct rescale slope/intercept if need be
-      ApplyRescale(*converted, sourceFormat != Orthanc::PixelFormat_Grayscale32);
-      
-      return converted.release();
-    }
-  }
-
-
-  void DicomFrameConverter::ApplyRescale(Orthanc::ImageAccessor& image,
-                                         bool useDouble) const
-  {
-    if (image.GetFormat() != Orthanc::PixelFormat_Float32)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat);
-    }
-    
-    if (hasRescale_)
-    {
-      for (unsigned int y = 0; y < image.GetHeight(); y++)
-      {
-        float* p = reinterpret_cast<float*>(image.GetRow(y));
-
-        if (useDouble)
-        {
-          // Slower, accurate implementation using double
-          for (unsigned int x = 0; x < image.GetWidth(); x++, p++)
-          {
-            double value = static_cast<double>(*p);
-            *p = static_cast<float>(value * rescaleSlope_ + rescaleIntercept_);
-          }
-        }
-        else
-        {
-          // Fast, approximate implementation using float
-          for (unsigned int x = 0; x < image.GetWidth(); x++, p++)
-          {
-            *p = (*p) * static_cast<float>(rescaleSlope_) + static_cast<float>(rescaleIntercept_);
-          }
-        }
-      }
-    }
-  }
-
-  
-  double DicomFrameConverter::Apply(double x) const
-  {
-    return x * rescaleSlope_ + rescaleIntercept_;
-  }
-
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/DicomFrameConverter.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,170 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include <IDicomDataset.h>
-#include <Compatibility.h>
-#include <DicomFormat/DicomMap.h>
-#include <Images/ImageAccessor.h>
-
-#include <memory>
-
-namespace Deprecated
-{
-  /**
-   * This class is responsible for converting the pixel format of a
-   * DICOM frame coming from Orthanc, into a pixel format that is
-   * suitable for Stone, given the relevant DICOM tags:
-   * - Color frames will stay in the RGB24 format.
-   * - Grayscale frames will be converted to the Float32 format.
-   **/
-  class DicomFrameConverter
-  {
-  private:
-    bool    isSigned_;
-    bool    isColor_;
-    bool    hasRescale_;
-    double  rescaleIntercept_;
-    double  rescaleSlope_;
-    bool    hasDefaultWindow_;
-    double  defaultWindowCenter_;
-    double  defaultWindowWidth_;
-    
-    Orthanc::PhotometricInterpretation  photometric_;
-    Orthanc::PixelFormat                expectedPixelFormat_;
-
-    void SetDefaultParameters();
-
-  public:
-    DicomFrameConverter()
-    {
-      SetDefaultParameters();
-    }
-
-    ~DicomFrameConverter()
-    {
-      // TODO: check whether this dtor is called or not
-      // An MSVC warning explains that declaring an
-      // std::unique_ptr with a forward-declared type
-      // prevents its dtor from being called. Does not
-      // seem an issue here (only POD types inside), but
-      // definitely something to keep an eye on.
-      (void)0;
-    }
-
-    // AM: this is required to serialize/deserialize it
-    DicomFrameConverter(
-        bool isSigned,
-        bool isColor,
-        bool hasRescale,
-        double rescaleIntercept,
-        double rescaleSlope,
-        bool hasDefaultWindow,
-        double defaultWindowCenter,
-        double defaultWindowWidth,
-        Orthanc::PhotometricInterpretation photometric,
-        Orthanc::PixelFormat expectedPixelFormat
-        ):
-      isSigned_(isSigned),
-      isColor_(isColor),
-      hasRescale_(hasRescale),
-      rescaleIntercept_(rescaleIntercept),
-      rescaleSlope_(rescaleSlope),
-      hasDefaultWindow_(hasDefaultWindow),
-      defaultWindowCenter_(defaultWindowCenter),
-      defaultWindowWidth_(defaultWindowWidth),
-      photometric_(photometric),
-      expectedPixelFormat_(expectedPixelFormat)
-    {}
-
-    void GetParameters(bool& isSigned,
-                       bool& isColor,
-                       bool& hasRescale,
-                       double& rescaleIntercept,
-                       double& rescaleSlope,
-                       bool& hasDefaultWindow,
-                       double& defaultWindowCenter,
-                       double& defaultWindowWidth,
-                       Orthanc::PhotometricInterpretation& photometric,
-                       Orthanc::PixelFormat& expectedPixelFormat) const
-    {
-      isSigned = isSigned_;
-      isColor = isColor_;
-      hasRescale = hasRescale_;
-      rescaleIntercept = rescaleIntercept_;
-      rescaleSlope = rescaleSlope_;
-      hasDefaultWindow = hasDefaultWindow_;
-      defaultWindowCenter = defaultWindowCenter_;
-      defaultWindowWidth = defaultWindowWidth_;
-      photometric = photometric_;
-      expectedPixelFormat = expectedPixelFormat_;
-    }
-
-    Orthanc::PixelFormat GetExpectedPixelFormat() const
-    {
-      return expectedPixelFormat_;
-    }
-
-    Orthanc::PhotometricInterpretation GetPhotometricInterpretation() const
-    {
-      return photometric_;
-    }
-
-    void ReadParameters(const Orthanc::DicomMap& dicom);
-
-    void ReadParameters(const OrthancPlugins::IDicomDataset& dicom);
-
-    bool HasDefaultWindow() const
-    {
-      return hasDefaultWindow_;
-    }
-    
-    double GetDefaultWindowCenter() const
-    {
-      return defaultWindowCenter_;
-    }
-    
-    double GetDefaultWindowWidth() const
-    {
-      return defaultWindowWidth_;
-    }
-
-    double GetRescaleIntercept() const
-    {
-      return rescaleIntercept_;
-    }
-
-    double GetRescaleSlope() const
-    {
-      return rescaleSlope_;
-    }
-
-    void ConvertFrameInplace(std::unique_ptr<Orthanc::ImageAccessor>& source) const;
-
-    Orthanc::ImageAccessor* ConvertFrame(const Orthanc::ImageAccessor& source) const;
-
-    void ApplyRescale(Orthanc::ImageAccessor& image,
-                      bool useDouble) const;
-
-    double Apply(double x) const;
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/DownloadStack.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,196 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "DownloadStack.h"
-
-#include <OrthancException.h>
-
-#include <cassert>
-
-namespace Deprecated
-{
-  bool DownloadStack::CheckInvariants() const
-  {
-    std::vector<bool> dequeued(nodes_.size(), true);
-
-    int i = firstNode_;
-    while (i != NIL)
-    {
-      const Node& node = nodes_[i];
-
-      dequeued[i] = false;
-
-      if (node.next_ != NIL &&
-          nodes_[node.next_].prev_ != i)
-      {
-        return false;
-      }
-
-      if (node.prev_ != NIL &&
-          nodes_[node.prev_].next_ != i)
-      {
-        return false;
-      }
-
-      i = nodes_[i].next_;
-    }
-
-    for (size_t i = 0; i < nodes_.size(); i++)
-    {
-      if (nodes_[i].dequeued_ != dequeued[i])
-      {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-
-  DownloadStack::DownloadStack(unsigned int size)
-  {
-    nodes_.resize(size);
-
-    if (size == 0)
-    {
-      firstNode_ = NIL;
-    }
-    else
-    {
-      for (size_t i = 0; i < size; i++)
-      {
-        nodes_[i].prev_ = static_cast<int>(i - 1);
-        nodes_[i].next_ = static_cast<int>(i + 1);
-        nodes_[i].dequeued_ = false;
-      }
-
-      nodes_.front().prev_ = NIL;
-      nodes_.back().next_ = NIL;
-      firstNode_ = 0;
-    }
-
-    assert(CheckInvariants());
-  }
-
-
-  DownloadStack::~DownloadStack()
-  {
-    assert(CheckInvariants());    
-  }
-
-
-  bool DownloadStack::Pop(unsigned int& value)
-  {
-    assert(CheckInvariants());
-
-    if (firstNode_ == NIL)
-    {
-      for (size_t i = 0; i < nodes_.size(); i++)
-      {
-        assert(nodes_[i].dequeued_);
-      }
-
-      return false;
-    }
-    else
-    {
-      assert(firstNode_ >= 0 && firstNode_ < static_cast<int>(nodes_.size()));
-      value = firstNode_;
-
-      Node& node = nodes_[firstNode_];
-      assert(node.prev_ == NIL);
-      assert(!node.dequeued_);
-
-      node.dequeued_ = true;
-      firstNode_ = node.next_;
-
-      if (firstNode_ != NIL)
-      {
-        nodes_[firstNode_].prev_ = NIL;
-      }
-
-      return true;
-    }
-  }
-
-
-  void DownloadStack::SetTopNodeInternal(unsigned int value)
-  {
-    assert(CheckInvariants());
-
-    Node& node = nodes_[value];
-
-    if (node.dequeued_)
-    {
-      // This node has already been processed by the download thread, nothing to do
-      return;
-    }
-
-    // Remove the node from the list
-    if (node.prev_ == NIL)
-    {
-      assert(firstNode_ == static_cast<int>(value));
-      
-      // This is already the top node in the list, nothing to do
-      return;
-    }
-
-    nodes_[node.prev_].next_ = node.next_;
-
-    if (node.next_ != NIL)
-    {
-      nodes_[node.next_].prev_ = node.prev_;
-    }
-
-    // Add back the node at the top of the list
-    assert(firstNode_ != NIL);
-
-    Node& old = nodes_[firstNode_];
-    assert(old.prev_ == NIL);
-    assert(!old.dequeued_);
-    node.prev_ = NIL;
-    node.next_ = firstNode_;
-    old.prev_ = value;
-
-    firstNode_ = value;
-  }
-
-  
-  void DownloadStack::SetTopNode(unsigned int value)
-  {
-    if (value >= nodes_.size())
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    SetTopNodeInternal(value);
-  }
-
-
-  void DownloadStack::SetTopNodePermissive(int value)
-  {
-    if (value >= 0 &&
-        value < static_cast<int>(nodes_.size()))
-    {
-      SetTopNodeInternal(value);
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/DownloadStack.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include <vector>
-#include <boost/noncopyable.hpp>
-
-namespace Deprecated
-{
-  class DownloadStack : public boost::noncopyable
-  {
-  private:
-    static const int NIL = -1;
-
-    // This is a doubly-linked list
-    struct Node
-    {
-      int   next_;
-      int   prev_;
-      bool  dequeued_;
-    };
-
-    std::vector<Node>   nodes_;
-    int                 firstNode_;
-
-    bool CheckInvariants() const;
-
-    void SetTopNodeInternal(unsigned int value);  
-
-  public:
-    DownloadStack(unsigned int size);
-
-    ~DownloadStack();
-
-    bool Pop(unsigned int& value);
-
-    void SetTopNode(unsigned int value);  
-
-    void SetTopNodePermissive(int value);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/IDelayedCallExecutor.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "IWebService.h"
-#include "../../Messages/IObserver.h"
-#include "../../Messages/ICallable.h"
-
-#include <IDynamicObject.h>
-#include <Logging.h>
-
-#include <string>
-#include <map>
-
-namespace Deprecated
-{
-  // The IDelayedCall executes a callback after a delay (equivalent to timeout() function in javascript).
-  class IDelayedCallExecutor : public boost::noncopyable
-  {
-  public:
-    ORTHANC_STONE_DEFINE_EMPTY_MESSAGE(__FILE__, __LINE__, TimeoutMessage);
-
-    virtual ~IDelayedCallExecutor()
-    {
-    }
-    
-    virtual void Schedule(MessageHandler<IDelayedCallExecutor::TimeoutMessage>* callback,
-                          unsigned int timeoutInMs = 1000) = 0;
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/ISeriesLoader.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "ParallelSlices.h"
-
-#include <Images/ImageAccessor.h>
-#include <IDicomDataset.h>
-
-namespace Deprecated
-{
-  class ISeriesLoader : public boost::noncopyable
-  {
-  public:
-    virtual ~ISeriesLoader()
-    {
-    }
-    
-    virtual ParallelSlices& GetGeometry() = 0;
-
-    virtual Orthanc::PixelFormat GetPixelFormat() = 0;
-
-    virtual unsigned int GetWidth() = 0;
-
-    virtual unsigned int GetHeight() = 0;
-
-    virtual OrthancPlugins::IDicomDataset* DownloadDicom(size_t index) = 0;
-
-    // This downloads the frame from Orthanc. The resulting pixel
-    // format must be Grayscale8, Grayscale16, SignedGrayscale16 or
-    // RGB24. Orthanc Stone assumes the conversion of the photometric
-    // interpretation is done by Orthanc.
-    virtual Orthanc::ImageAccessor* DownloadFrame(size_t index) = 0;
-
-    virtual Orthanc::ImageAccessor* DownloadJpegFrame(size_t index,
-                                                      unsigned int quality) = 0;
-
-    virtual bool IsJpegAvailable() = 0;
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/IWebService.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "IWebService.h"
-
-#include <OrthancException.h>
-
-
-namespace Deprecated
-{
-  const Orthanc::IDynamicObject&
-  IWebService::HttpRequestSuccessMessage::GetPayload() const
-  {
-    if (HasPayload())
-    {
-      return *payload_;
-    }
-    else
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-  }
-    
-
-  const Orthanc::IDynamicObject&
-  IWebService::HttpRequestErrorMessage::GetPayload() const
-  {
-    if (HasPayload())
-    {
-      return *payload_;
-    }
-    else
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/IWebService.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,213 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Messages/IObserver.h"
-#include "../../Messages/ICallable.h"
-
-#include <Enumerations.h>
-#include <IDynamicObject.h>
-#include <Logging.h>
-
-#include <string>
-#include <map>
-
-namespace Deprecated
-{
-  template <typename TMessage>
-  class MessageHandler : public OrthancStone::ICallable
-  {
-  };
-
-
-  template <typename TObserver,
-            typename TMessage>
-  class DeprecatedCallable : public MessageHandler<TMessage>
-  {
-  private:
-    typedef void (TObserver::* MemberMethod) (const TMessage&);
-
-    boost::weak_ptr<OrthancStone::IObserver>  observer_;
-    MemberMethod                function_;
-
-  public:
-    DeprecatedCallable(boost::shared_ptr<TObserver> observer,
-                       MemberMethod function) :
-      observer_(observer),
-      function_(function)
-    {
-    }
-
-    virtual void Apply(const OrthancStone::IMessage& message)
-    {
-      boost::shared_ptr<OrthancStone::IObserver> lock(observer_);
-      if (lock)
-      {
-        TObserver& observer = dynamic_cast<TObserver&>(*lock);
-        const TMessage& typedMessage = dynamic_cast<const TMessage&>(message);
-        (observer.*function_) (typedMessage);
-      }
-    }
-
-    virtual const OrthancStone::MessageIdentifier& GetMessageIdentifier()
-    {
-      return TMessage::GetStaticIdentifier();
-    }
-
-    virtual boost::weak_ptr<OrthancStone::IObserver> GetObserver() const
-    {
-      return observer_;
-    }
-  };
-
-
-  // The IWebService performs HTTP requests.
-  // Since applications can run in native or WASM environment and, since
-  // in a WASM environment, the WebService is asynchronous, the IWebservice
-  // also implements an asynchronous interface: you must schedule a request
-  // and you'll be notified when the response/error is ready.
-  class IWebService : public boost::noncopyable
-  {
-  public:
-    typedef std::map<std::string, std::string> HttpHeaders;
-
-    class HttpRequestSuccessMessage : public OrthancStone::IMessage
-    {
-      ORTHANC_STONE_MESSAGE(__FILE__, __LINE__);
-
-    private:
-      const std::string&             uri_;
-      const void*                    answer_;
-      size_t                         answerSize_;
-      const HttpHeaders&             answerHeaders_;
-      const Orthanc::IDynamicObject* payload_;
-
-    public:
-      HttpRequestSuccessMessage(const std::string& uri,
-                                const void* answer,
-                                size_t answerSize,
-                                const HttpHeaders& answerHeaders,
-                                const Orthanc::IDynamicObject* payload) :
-        uri_(uri),
-        answer_(answer),
-        answerSize_(answerSize),
-        answerHeaders_(answerHeaders),
-        payload_(payload)
-      {
-      }
-
-      const std::string& GetUri() const
-      {
-        return uri_;
-      }
-
-      const void* GetAnswer() const
-      {
-        return answer_;
-      }
-
-      size_t GetAnswerSize() const
-      {
-        return answerSize_;
-      }
-
-      const HttpHeaders&  GetAnswerHttpHeaders() const
-      {
-        return answerHeaders_;
-      }
-
-      bool HasPayload() const
-      {
-        return payload_ != NULL;
-      }
-
-      const Orthanc::IDynamicObject& GetPayload() const;
-    };
-    
-
-    class HttpRequestErrorMessage : public OrthancStone::IMessage
-    {
-      ORTHANC_STONE_MESSAGE(__FILE__, __LINE__);
-
-    private:
-      const std::string&              uri_;
-      const Orthanc::IDynamicObject*  payload_;
-      Orthanc::HttpStatus             httpStatus_;
-
-    public:
-      HttpRequestErrorMessage(const std::string& uri,
-                              Orthanc::HttpStatus httpStatus,
-                              const Orthanc::IDynamicObject* payload) :
-        uri_(uri),
-        payload_(payload),
-        httpStatus_(httpStatus)
-      {
-      }
-
-      const std::string& GetUri() const
-      {
-        return uri_;
-      }
-
-      Orthanc::HttpStatus GetHttpStatus() const
-      {
-        return httpStatus_;
-      }
-
-      bool HasPayload() const
-      {
-        return payload_ != NULL;
-      }
-
-      const Orthanc::IDynamicObject& GetPayload() const;
-    };
-
-
-    virtual ~IWebService()
-    {
-    }
-
-    virtual void EnableCache(bool enable) = 0;
-    
-    virtual void GetAsync(const std::string& uri,
-                          const HttpHeaders& headers,
-                          Orthanc::IDynamicObject* payload  /* takes ownership */,
-                          MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback,
-                          MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback = NULL,
-                          unsigned int timeoutInSeconds = 60) = 0;
-
-    virtual void PostAsync(const std::string& uri,
-                           const HttpHeaders& headers,
-                           const std::string& body,
-                           Orthanc::IDynamicObject* payload  /* takes ownership */,
-                           MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback,
-                           MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback = NULL,
-                           unsigned int timeoutInSeconds = 60) = 0;
-
-    virtual void DeleteAsync(const std::string& uri,
-                             const HttpHeaders& headers,
-                             Orthanc::IDynamicObject* payload  /* takes ownership */,
-                             MessageHandler<IWebService::HttpRequestSuccessMessage>* successCallback,
-                             MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback = NULL,
-                             unsigned int timeoutInSeconds = 60) = 0;
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/MessagingToolbox.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,462 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "MessagingToolbox.h"
-
-#include <Images/Image.h>
-#include <Images/ImageProcessing.h>
-#include <Images/JpegReader.h>
-#include <Images/PngReader.h>
-#include <OrthancException.h>
-#include <Toolbox.h>
-#include <Logging.h>
-
-#include <boost/lexical_cast.hpp>
-
-#ifdef _MSC_VER
-// 'Json::Reader': Use CharReader and CharReaderBuilder instead
-#pragma warning(disable:4996)
-#endif
-
-#include <json/reader.h>
-#include <json/writer.h>
-
-
-namespace Deprecated
-{
-  namespace MessagingToolbox
-  {
-    static bool ParseVersion(std::string& version,
-                             unsigned int& major,
-                             unsigned int& minor,
-                             unsigned int& patch,
-                             const Json::Value& info)
-    {
-      if (info.type() != Json::objectValue ||
-          !info.isMember("Version") ||
-          info["Version"].type() != Json::stringValue)
-      {
-        return false;
-      }
-
-      version = info["Version"].asString();
-      if (version == "mainline")
-      {
-        // Some arbitrary high values Orthanc versions will never reach ;)
-        major = 999;
-        minor = 999;
-        patch = 999;
-        return true;
-      }
-
-      std::vector<std::string> tokens;
-      Orthanc::Toolbox::TokenizeString(tokens, version, '.');
-      
-      if (tokens.size() != 2 &&
-          tokens.size() != 3)
-      {
-        return false;
-      }
-
-      int a, b, c;
-      try
-      {
-        a = boost::lexical_cast<int>(tokens[0]);
-        b = boost::lexical_cast<int>(tokens[1]);
-
-        if (tokens.size() == 3)
-        {
-          c = boost::lexical_cast<int>(tokens[2]);
-        }
-        else
-        {
-          c = 0;
-        }
-      }
-      catch (boost::bad_lexical_cast&)
-      {
-        return false;
-      }
-
-      if (a < 0 ||
-          b < 0 ||
-          c < 0)
-      {
-        return false;
-      }
-      else
-      {
-        major = static_cast<unsigned int>(a);
-        minor = static_cast<unsigned int>(b);
-        patch = static_cast<unsigned int>(c);
-        return true;
-      }         
-    }
-
-
-    bool ParseJson(Json::Value& target,
-                   const void* content,
-                   size_t size)
-    {
-      Json::Reader reader;
-      return reader.parse(reinterpret_cast<const char*>(content),
-                          reinterpret_cast<const char*>(content) + size,
-                          target);
-    }
-
-    void JsonToString(std::string& target,
-                      const Json::Value& source)
-    {
-      Json::FastWriter writer;
-      target = writer.write(source);
-    }
-
-    static void ParseJsonException(Json::Value& target,
-                                   const std::string& source)
-    {
-      Json::Reader reader;
-      if (!reader.parse(source, target))
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
-      }
-    }
-
-
-    void RestApiGet(Json::Value& target,
-                    OrthancPlugins::IOrthancConnection& orthanc,
-                    const std::string& uri)
-    {
-      std::string tmp;
-      orthanc.RestApiGet(tmp, uri);
-      ParseJsonException(target, tmp);
-    }
-
-
-    void RestApiPost(Json::Value& target,
-                     OrthancPlugins::IOrthancConnection& orthanc,
-                     const std::string& uri,
-                     const std::string& body)
-    {
-      std::string tmp;
-      orthanc.RestApiPost(tmp, uri, body);
-      ParseJsonException(target, tmp);
-    }
-
-
-    bool HasWebViewerInstalled(OrthancPlugins::IOrthancConnection& orthanc)
-    {
-      try
-      {
-        Json::Value json;
-        RestApiGet(json, orthanc, "/plugins/web-viewer");
-        return json.type() == Json::objectValue;
-      }
-      catch (Orthanc::OrthancException&)
-      {
-        return false;
-      }
-    }
-
-
-    bool CheckOrthancVersion(OrthancPlugins::IOrthancConnection& orthanc)
-    {
-      Json::Value json;
-      std::string version;
-      unsigned int major, minor, patch;
-
-      try
-      {
-        RestApiGet(json, orthanc, "/system");
-      }
-      catch (Orthanc::OrthancException&)
-      {
-        LOG(ERROR) << "Cannot connect to your Orthanc server";
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol);
-      }
-        
-      if (!ParseVersion(version, major, minor, patch, json))
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol);
-      }
-
-      LOG(WARNING) << "Version of the Orthanc core (must be above 1.3.1): " << version;
-
-      // Stone is only compatible with Orthanc >= 1.3.1
-      if (major < 1 ||
-          (major == 1 && minor < 3) ||
-          (major == 1 && minor == 3 && patch < 1))
-      {
-        return false;
-      }
-
-      try
-      {
-        RestApiGet(json, orthanc, "/plugins/web-viewer");       
-      }
-      catch (Orthanc::OrthancException&)
-      {
-        // The Web viewer is not installed, this is OK
-        LOG(WARNING) << "The Web viewer plugin is not installed, progressive download is disabled";
-        return true;
-      }
-
-      if (!ParseVersion(version, major, minor, patch, json))
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol);
-      }
-
-      LOG(WARNING) << "Version of the Web viewer plugin (must be above 2.2): " << version;
-
-      return (major >= 3 ||
-              (major == 2 && minor >= 2));
-    }
-
-
-    Orthanc::ImageAccessor* DecodeFrame(OrthancPlugins::IOrthancConnection& orthanc,
-                                        const std::string& instance,
-                                        unsigned int frame,
-                                        Orthanc::PixelFormat targetFormat)
-    {
-      std::string uri = ("instances/" + instance + "/frames/" + 
-                         boost::lexical_cast<std::string>(frame));
-
-      std::string compressed;
-
-      switch (targetFormat)
-      {
-        case Orthanc::PixelFormat_RGB24:
-          orthanc.RestApiGet(compressed, uri + "/preview");
-          break;
-
-        case Orthanc::PixelFormat_Grayscale16:
-          orthanc.RestApiGet(compressed, uri + "/image-uint16");
-          break;
-
-        case Orthanc::PixelFormat_SignedGrayscale16:
-          orthanc.RestApiGet(compressed, uri + "/image-int16");
-          break;
-
-        default:
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-      }
-      
-      std::unique_ptr<Orthanc::PngReader> result(new Orthanc::PngReader);
-      result->ReadFromMemory(compressed);
-
-      if (targetFormat == Orthanc::PixelFormat_SignedGrayscale16)
-      {
-        if (result->GetFormat() == Orthanc::PixelFormat_Grayscale16)
-        {
-          result->SetFormat(Orthanc::PixelFormat_SignedGrayscale16);
-        }
-        else
-        {
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol);
-        }
-      }
-
-      return result.release();
-    }
-
-
-    Orthanc::ImageAccessor* DecodeJpegFrame(OrthancPlugins::IOrthancConnection& orthanc,
-                                            const std::string& instance,
-                                            unsigned int frame,
-                                            unsigned int quality,
-                                            Orthanc::PixelFormat targetFormat)
-    {
-      if (quality <= 0 || 
-          quality > 100)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-      }
-
-      // This requires the official Web viewer plugin to be installed!
-      std::string uri = ("web-viewer/instances/jpeg" + 
-                         boost::lexical_cast<std::string>(quality) + 
-                         "-" + instance + "_" + 
-                         boost::lexical_cast<std::string>(frame));
-
-      Json::Value encoded;
-      RestApiGet(encoded, orthanc, uri);
-
-      if (encoded.type() != Json::objectValue ||
-          !encoded.isMember("Orthanc") ||
-          encoded["Orthanc"].type() != Json::objectValue)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol);
-      }
-
-      Json::Value& info = encoded["Orthanc"];
-      if (!info.isMember("PixelData") ||
-          !info.isMember("Stretched") ||
-          !info.isMember("Compression") ||
-          info["Compression"].type() != Json::stringValue ||
-          info["PixelData"].type() != Json::stringValue ||
-          info["Stretched"].type() != Json::booleanValue ||
-          info["Compression"].asString() != "Jpeg")
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol);
-      }          
-
-      bool isSigned = false;
-      bool isStretched = info["Stretched"].asBool();
-
-      if (info.isMember("IsSigned"))
-      {
-        if (info["IsSigned"].type() != Json::booleanValue)
-        {
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol);
-        }          
-        else
-        {
-          isSigned = info["IsSigned"].asBool();
-        }
-      }
-
-      std::string jpeg;
-      Orthanc::Toolbox::DecodeBase64(jpeg, info["PixelData"].asString());
-
-      std::unique_ptr<Orthanc::JpegReader> reader(new Orthanc::JpegReader);
-      reader->ReadFromMemory(jpeg);
-
-      if (reader->GetFormat() == Orthanc::PixelFormat_RGB24)  // This is a color image
-      {
-        if (targetFormat != Orthanc::PixelFormat_RGB24)
-        {
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol);
-        }
-
-        if (isSigned || isStretched)
-        {
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
-        }
-        else
-        {
-          return reader.release();
-        }
-      }
-
-      if (reader->GetFormat() != Orthanc::PixelFormat_Grayscale8)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
-      }
-
-      if (!isStretched)
-      {
-        if (targetFormat != reader->GetFormat())
-        {
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol);
-        }
-
-        return reader.release();
-      }
-
-      int32_t stretchLow = 0;
-      int32_t stretchHigh = 0;
-
-      if (!info.isMember("StretchLow") ||
-          !info.isMember("StretchHigh") ||
-          info["StretchLow"].type() != Json::intValue ||
-          info["StretchHigh"].type() != Json::intValue)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol);
-      }
-
-      stretchLow = info["StretchLow"].asInt();
-      stretchHigh = info["StretchHigh"].asInt();
-
-      if (stretchLow < -32768 ||
-          stretchHigh > 65535 ||
-          (stretchLow < 0 && stretchHigh > 32767))
-      {
-        // This range cannot be represented with a uint16_t or an int16_t
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);          
-      }
-
-      // Decode a grayscale JPEG 8bpp image coming from the Web viewer
-      std::unique_ptr<Orthanc::ImageAccessor> image
-        (new Orthanc::Image(targetFormat, reader->GetWidth(), reader->GetHeight(), false));
-
-      float scaling = static_cast<float>(stretchHigh - stretchLow) / 255.0f;
-      float offset = static_cast<float>(stretchLow) / scaling;
-      
-      Orthanc::ImageProcessing::Convert(*image, *reader);
-      Orthanc::ImageProcessing::ShiftScale(*image, offset, scaling, true);
-
-#if 0
-      /*info.removeMember("PixelData");
-        std::cout << info.toStyledString();*/
-      
-      int64_t a, b;
-      Orthanc::ImageProcessing::GetMinMaxValue(a, b, *image);
-      std::cout << stretchLow << "->" << stretchHigh << " = " << a << "->" << b << std::endl;
-#endif
-
-      return image.release();
-    }
-
-
-    static void AddTag(Orthanc::DicomMap& target,
-                       const OrthancPlugins::IDicomDataset& source,
-                       const Orthanc::DicomTag& tag)
-    {
-      OrthancPlugins::DicomTag key(tag.GetGroup(), tag.GetElement());
-      
-      std::string value;
-      if (source.GetStringValue(value, key))
-      {
-        target.SetValue(tag, value, false);
-      }
-    }
-
-    
-    void ConvertDataset(Orthanc::DicomMap& target,
-                        const OrthancPlugins::IDicomDataset& source)
-    {
-      target.Clear();
-
-      AddTag(target, source, Orthanc::DICOM_TAG_BITS_ALLOCATED);
-      AddTag(target, source, Orthanc::DICOM_TAG_BITS_STORED);
-      AddTag(target, source, Orthanc::DICOM_TAG_COLUMNS);
-      AddTag(target, source, Orthanc::DICOM_TAG_DOSE_GRID_SCALING);
-      AddTag(target, source, Orthanc::DICOM_TAG_FRAME_INCREMENT_POINTER);
-      AddTag(target, source, Orthanc::DICOM_TAG_GRID_FRAME_OFFSET_VECTOR);
-      AddTag(target, source, Orthanc::DICOM_TAG_HIGH_BIT);
-      AddTag(target, source, Orthanc::DICOM_TAG_IMAGE_ORIENTATION_PATIENT);
-      AddTag(target, source, Orthanc::DICOM_TAG_IMAGE_POSITION_PATIENT);
-      AddTag(target, source, Orthanc::DICOM_TAG_NUMBER_OF_FRAMES);
-      AddTag(target, source, Orthanc::DICOM_TAG_PHOTOMETRIC_INTERPRETATION);
-      AddTag(target, source, Orthanc::DICOM_TAG_PIXEL_REPRESENTATION);
-      AddTag(target, source, Orthanc::DICOM_TAG_PIXEL_SPACING);
-      AddTag(target, source, Orthanc::DICOM_TAG_PLANAR_CONFIGURATION);
-      AddTag(target, source, Orthanc::DICOM_TAG_RESCALE_INTERCEPT);
-      AddTag(target, source, Orthanc::DICOM_TAG_RESCALE_SLOPE);
-      AddTag(target, source, Orthanc::DICOM_TAG_ROWS);
-      AddTag(target, source, Orthanc::DICOM_TAG_SAMPLES_PER_PIXEL);
-      AddTag(target, source, Orthanc::DICOM_TAG_SERIES_INSTANCE_UID);
-      AddTag(target, source, Orthanc::DICOM_TAG_SLICE_THICKNESS);
-      AddTag(target, source, Orthanc::DICOM_TAG_SOP_CLASS_UID);
-      AddTag(target, source, Orthanc::DICOM_TAG_SOP_INSTANCE_UID);
-      AddTag(target, source, Orthanc::DICOM_TAG_WINDOW_CENTER);
-      AddTag(target, source, Orthanc::DICOM_TAG_WINDOW_WIDTH);
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/MessagingToolbox.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../StoneEnumerations.h"
-
-#include <DicomFormat/DicomMap.h>
-#include <Images/ImageAccessor.h>
-#include <IDicomDataset.h>
-#include <IOrthancConnection.h>
-
-#include <json/value.h>
-
-namespace Deprecated
-{
-  namespace MessagingToolbox
-  {
-    bool ParseJson(Json::Value& target,
-                   const void* content,
-                   size_t size);
-
-    void JsonToString(std::string& target,
-                      const Json::Value& source);
-
-
-    void RestApiGet(Json::Value& target,
-                    OrthancPlugins::IOrthancConnection& orthanc,
-                    const std::string& uri);
-
-    void RestApiPost(Json::Value& target,
-                     OrthancPlugins::IOrthancConnection& orthanc,
-                     const std::string& uri,
-                     const std::string& body);
-
-    bool HasWebViewerInstalled(OrthancPlugins::IOrthancConnection& orthanc);
-
-    bool CheckOrthancVersion(OrthancPlugins::IOrthancConnection& orthanc);
-
-    // This downloads the image from Orthanc and keeps its pixel
-    // format unchanged (will be either Grayscale8, Grayscale16,
-    // SignedGrayscale16, or RGB24)
-    Orthanc::ImageAccessor* DecodeFrame(OrthancPlugins::IOrthancConnection& orthanc,
-                                        const std::string& instance,
-                                        unsigned int frame,
-                                        Orthanc::PixelFormat targetFormat);
-
-    Orthanc::ImageAccessor* DecodeJpegFrame(OrthancPlugins::IOrthancConnection& orthanc,
-                                            const std::string& instance,
-                                            unsigned int frame,
-                                            unsigned int quality,
-                                            Orthanc::PixelFormat targetFormat);
-
-    void ConvertDataset(Orthanc::DicomMap& target,
-                        const OrthancPlugins::IDicomDataset& source);
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/OrthancApiClient.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,334 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "OrthancApiClient.h"
-
-#include "../Toolbox/MessagingToolbox.h"
-
-#include <OrthancException.h>
-
-namespace Deprecated
-{
-  const Orthanc::IDynamicObject& OrthancApiClient::JsonResponseReadyMessage::GetPayload() const
-  {
-    if (HasPayload())
-    {
-      return *payload_;
-    }
-    else
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-  }
-  
-  
-  const Orthanc::IDynamicObject& OrthancApiClient::BinaryResponseReadyMessage::GetPayload() const
-  {
-    if (HasPayload())
-    {
-      return *payload_;
-    }
-    else
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-  }
-  
-  
-  const Orthanc::IDynamicObject& OrthancApiClient::EmptyResponseReadyMessage::GetPayload() const
-  {
-    if (HasPayload())
-    {
-      return *payload_;
-    }
-    else
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-  }
-  
-  
-  class OrthancApiClient::WebServicePayload : public Orthanc::IDynamicObject
-  {
-  private:
-    std::unique_ptr< MessageHandler<EmptyResponseReadyMessage> >             emptyHandler_;
-    std::unique_ptr< MessageHandler<JsonResponseReadyMessage> >              jsonHandler_;
-    std::unique_ptr< MessageHandler<BinaryResponseReadyMessage> >            binaryHandler_;
-    std::unique_ptr< MessageHandler<IWebService::HttpRequestErrorMessage> >  failureHandler_;
-    std::unique_ptr< Orthanc::IDynamicObject >                               userPayload_;
-
-    void NotifyConversionError(const IWebService::HttpRequestSuccessMessage& message) const
-    {
-      if (failureHandler_.get() != NULL)
-      {
-        failureHandler_->Apply(IWebService::HttpRequestErrorMessage
-                               (message.GetUri(), Orthanc::HttpStatus_None, userPayload_.get()));
-      }
-    }
-    
-  public:
-    WebServicePayload(MessageHandler<EmptyResponseReadyMessage>* handler,
-                      MessageHandler<IWebService::HttpRequestErrorMessage>* failureHandler,
-                      Orthanc::IDynamicObject* userPayload) :
-      emptyHandler_(handler),
-      failureHandler_(failureHandler),
-      userPayload_(userPayload)
-
-    {
-      if (handler == NULL)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
-      }
-    }
-
-    WebServicePayload(MessageHandler<BinaryResponseReadyMessage>* handler,
-                      MessageHandler<IWebService::HttpRequestErrorMessage>* failureHandler,
-                      Orthanc::IDynamicObject* userPayload) :
-      binaryHandler_(handler),
-      failureHandler_(failureHandler),
-      userPayload_(userPayload)
-    {
-      if (handler == NULL)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
-      }
-    }
-
-    WebServicePayload(MessageHandler<JsonResponseReadyMessage>* handler,
-                      MessageHandler<IWebService::HttpRequestErrorMessage>* failureHandler,
-                      Orthanc::IDynamicObject* userPayload) :
-      jsonHandler_(handler),
-      failureHandler_(failureHandler),
-      userPayload_(userPayload)
-    {
-      if (handler == NULL)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
-      }
-    }
-
-    void HandleSuccess(const IWebService::HttpRequestSuccessMessage& message) const
-    {
-      if (emptyHandler_.get() != NULL)
-      {
-        emptyHandler_->Apply(OrthancApiClient::EmptyResponseReadyMessage
-                             (message.GetUri(), userPayload_.get()));
-      }
-      else if (binaryHandler_.get() != NULL)
-      {
-        binaryHandler_->Apply(OrthancApiClient::BinaryResponseReadyMessage
-                              (message.GetUri(), message.GetAnswer(),
-                               message.GetAnswerSize(), userPayload_.get()));
-      }
-      else if (jsonHandler_.get() != NULL)
-      {
-        Json::Value response;
-        if (MessagingToolbox::ParseJson(response, message.GetAnswer(), message.GetAnswerSize()))
-        {
-          jsonHandler_->Apply(OrthancApiClient::JsonResponseReadyMessage
-                              (message.GetUri(), response, userPayload_.get()));
-        }
-        else
-        {
-          NotifyConversionError(message);
-        }
-      }
-      else
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-      }
-    }
-
-    void HandleFailure(const IWebService::HttpRequestErrorMessage& message) const
-    {
-      if (failureHandler_.get() != NULL)
-      {
-        failureHandler_->Apply(IWebService::HttpRequestErrorMessage
-                               (message.GetUri(), message.GetHttpStatus(), userPayload_.get()));
-      }
-    }
-  };
-
-
-  OrthancApiClient::OrthancApiClient(IWebService& web,
-                                     const std::string& baseUrl) :
-    web_(web),
-    baseUrl_(baseUrl)
-  {
-  }
-
-
-  void OrthancApiClient::GetJsonAsync(
-      const std::string& uri,
-      MessageHandler<JsonResponseReadyMessage>* successCallback,
-      MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback,
-      Orthanc::IDynamicObject* payload)
-  {
-    IWebService::HttpHeaders emptyHeaders;
-    web_.GetAsync(baseUrl_ + uri,
-                  emptyHeaders,
-                  new WebServicePayload(successCallback, failureCallback, payload),
-                  new DeprecatedCallable<OrthancApiClient, IWebService::HttpRequestSuccessMessage>
-                  (GetSharedObserver(), &OrthancApiClient::NotifyHttpSuccess),
-                  new DeprecatedCallable<OrthancApiClient, IWebService::HttpRequestErrorMessage>
-                  (GetSharedObserver(), &OrthancApiClient::NotifyHttpError));
-  }
-
-
-  void OrthancApiClient::GetBinaryAsync(
-      const std::string& uri,
-      const std::string& contentType,
-      MessageHandler<BinaryResponseReadyMessage>* successCallback,
-      MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback,
-      Orthanc::IDynamicObject* payload)
-  {
-    IWebService::HttpHeaders headers;
-    headers["Accept"] = contentType;
-    GetBinaryAsync(uri, headers, successCallback, failureCallback, payload);
-  }
-
-  void OrthancApiClient::GetBinaryAsync(
-      const std::string& uri,
-      const IWebService::HttpHeaders& headers,
-      MessageHandler<BinaryResponseReadyMessage>* successCallback,
-      MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback,
-      Orthanc::IDynamicObject* payload)
-  {
-    // printf("GET [%s] [%s]\n", baseUrl_.c_str(), uri.c_str());
-
-    web_.GetAsync(baseUrl_ + uri, headers,
-                  new WebServicePayload(successCallback, failureCallback, payload),
-                  new DeprecatedCallable<OrthancApiClient, IWebService::HttpRequestSuccessMessage>
-                  (GetSharedObserver(), &OrthancApiClient::NotifyHttpSuccess),
-                  new DeprecatedCallable<OrthancApiClient, IWebService::HttpRequestErrorMessage>
-                  (GetSharedObserver(), &OrthancApiClient::NotifyHttpError));
-  }
-
-  
-  void OrthancApiClient::PostBinaryAsyncExpectJson(
-      const std::string& uri,
-      const std::string& body,
-      MessageHandler<JsonResponseReadyMessage>* successCallback,
-      MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback,
-      Orthanc::IDynamicObject* payload)
-  {
-    web_.PostAsync(baseUrl_ + uri, IWebService::HttpHeaders(), body,
-                   new WebServicePayload(successCallback, failureCallback, payload),
-                   new DeprecatedCallable<OrthancApiClient, IWebService::HttpRequestSuccessMessage>
-                   (GetSharedObserver(), &OrthancApiClient::NotifyHttpSuccess),
-                   new DeprecatedCallable<OrthancApiClient, IWebService::HttpRequestErrorMessage>
-                   (GetSharedObserver(), &OrthancApiClient::NotifyHttpError));
-
-  }
-
-  void OrthancApiClient::PostBinaryAsync(
-      const std::string& uri,
-      const std::string& body)
-  {
-    web_.PostAsync(baseUrl_ + uri, IWebService::HttpHeaders(), body, NULL, NULL, NULL);
-  }
-
-  void OrthancApiClient::PostBinaryAsync(
-      const std::string& uri,
-      const std::string& body,
-      MessageHandler<EmptyResponseReadyMessage>* successCallback,
-      MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback,
-      Orthanc::IDynamicObject* payload   /* takes ownership */)
-  {
-    web_.PostAsync(baseUrl_ + uri, IWebService::HttpHeaders(), body,
-                   new WebServicePayload(successCallback, failureCallback, payload),
-                   new DeprecatedCallable<OrthancApiClient, IWebService::HttpRequestSuccessMessage>
-                   (GetSharedObserver(), &OrthancApiClient::NotifyHttpSuccess),
-                   new DeprecatedCallable<OrthancApiClient, IWebService::HttpRequestErrorMessage>
-                   (GetSharedObserver(), &OrthancApiClient::NotifyHttpError));
-  }
-
-  void OrthancApiClient::PostJsonAsyncExpectJson(
-      const std::string& uri,
-      const Json::Value& data,
-      MessageHandler<JsonResponseReadyMessage>* successCallback,
-      MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback,
-      Orthanc::IDynamicObject* payload)
-  {
-    std::string body;
-    MessagingToolbox::JsonToString(body, data);
-    return PostBinaryAsyncExpectJson(uri, body, successCallback, failureCallback, payload);
-  }
-
-  void OrthancApiClient::PostJsonAsync(
-      const std::string& uri,
-      const Json::Value& data)
-  {
-    std::string body;
-    MessagingToolbox::JsonToString(body, data);
-    return PostBinaryAsync(uri, body);
-  }
-
-  void OrthancApiClient::PostJsonAsync(
-      const std::string& uri,
-      const Json::Value& data,
-      MessageHandler<EmptyResponseReadyMessage>* successCallback,
-      MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback,
-      Orthanc::IDynamicObject* payload   /* takes ownership */)
-  {
-    std::string body;
-    MessagingToolbox::JsonToString(body, data);
-    return PostBinaryAsync(uri, body, successCallback, failureCallback, payload);
-  }
-
-  void OrthancApiClient::DeleteAsync(
-      const std::string& uri,
-      MessageHandler<EmptyResponseReadyMessage>* successCallback,
-      MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback,
-      Orthanc::IDynamicObject* payload)
-  {
-    web_.DeleteAsync(baseUrl_ + uri, IWebService::HttpHeaders(),
-                     new WebServicePayload(successCallback, failureCallback, payload),
-                     new DeprecatedCallable<OrthancApiClient, IWebService::HttpRequestSuccessMessage>
-                     (GetSharedObserver(), &OrthancApiClient::NotifyHttpSuccess),
-                     new DeprecatedCallable<OrthancApiClient, IWebService::HttpRequestErrorMessage>
-                     (GetSharedObserver(), &OrthancApiClient::NotifyHttpError));
-  }
-
-
-  void OrthancApiClient::NotifyHttpSuccess(const IWebService::HttpRequestSuccessMessage& message)
-  {
-    if (message.HasPayload())
-    {
-      dynamic_cast<const WebServicePayload&>(message.GetPayload()).HandleSuccess(message);
-    }
-    else
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-    }
-  }
-
-  void OrthancApiClient::NotifyHttpError(const IWebService::HttpRequestErrorMessage& message)
-  {
-    if (message.HasPayload())
-    {
-      dynamic_cast<const WebServicePayload&>(message.GetPayload()).HandleFailure(message);
-    }
-    else
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/OrthancApiClient.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,252 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include <boost/shared_ptr.hpp>
-#include <json/json.h>
-
-#include "IWebService.h"
-#include "../../Messages/ObserverBase.h"
-
-namespace Deprecated
-{
-  enum SliceImageQuality
-  {
-    SliceImageQuality_FullPng,  // smaller to transmit but longer to generate on Orthanc side (better choice when on low bandwidth)
-    SliceImageQuality_FullPam,  // bigger to transmit but faster to generate on Orthanc side (better choice when on localhost or LAN)
-    SliceImageQuality_Jpeg50,
-    SliceImageQuality_Jpeg90,
-    SliceImageQuality_Jpeg95,
-
-    SliceImageQuality_InternalRaw   // downloads the raw pixels data as they are stored in the DICOM file (internal use only)
-  };  
-
-  class OrthancApiClient :
-      public OrthancStone::IObservable,
-      public OrthancStone::ObserverBase<OrthancApiClient>
-  {
-  public:
-    class JsonResponseReadyMessage : public OrthancStone::IMessage
-    {
-      ORTHANC_STONE_MESSAGE(__FILE__, __LINE__);
-
-    private:
-      const std::string&              uri_;
-      const Json::Value&              json_;
-      const Orthanc::IDynamicObject*  payload_;
-
-    public:
-      JsonResponseReadyMessage(const std::string& uri,
-                               const Json::Value& json,
-                               const Orthanc::IDynamicObject* payload) :
-        uri_(uri),
-        json_(json),
-        payload_(payload)
-      {
-      }
-
-      const std::string& GetUri() const
-      {
-        return uri_;
-      }
-
-      const Json::Value& GetJson() const
-      {
-        return json_;
-      }
-
-      bool HasPayload() const
-      {
-        return payload_ != NULL;
-      }
-
-      const Orthanc::IDynamicObject& GetPayload() const;
-    };
-    
-
-    class BinaryResponseReadyMessage : public OrthancStone::IMessage
-    {
-      ORTHANC_STONE_MESSAGE(__FILE__, __LINE__);
-
-    private:
-      const std::string&              uri_;
-      const void*                     answer_;
-      size_t                          answerSize_;
-      const Orthanc::IDynamicObject*  payload_;
-
-    public:
-      BinaryResponseReadyMessage(const std::string& uri,
-                                 const void* answer,
-                                 size_t answerSize,
-                                 const Orthanc::IDynamicObject* payload) :
-        uri_(uri),
-        answer_(answer),
-        answerSize_(answerSize),
-        payload_(payload)
-      {
-      }
-
-      const std::string& GetUri() const
-      {
-        return uri_;
-      }
-
-      const void* GetAnswer() const
-      {
-        return answer_;
-      }
-
-      size_t GetAnswerSize() const
-      {
-        return answerSize_;
-      }
-
-      bool HasPayload() const
-      {
-        return payload_ != NULL;
-      }
-
-      const Orthanc::IDynamicObject& GetPayload() const;
-    };
-
-
-    class EmptyResponseReadyMessage : public OrthancStone::IMessage
-    {
-      ORTHANC_STONE_MESSAGE(__FILE__, __LINE__);
-
-    private:
-      const std::string&              uri_;
-      const Orthanc::IDynamicObject*  payload_;
-
-    public:
-      EmptyResponseReadyMessage(const std::string& uri,
-                                const Orthanc::IDynamicObject* payload) :
-        uri_(uri),
-        payload_(payload)
-      {
-      }
-
-      const std::string& GetUri() const
-      {
-        return uri_;
-      }
-
-      bool HasPayload() const
-      {
-        return payload_ != NULL;
-      }
-
-      const Orthanc::IDynamicObject& GetPayload() const;
-    };
-
-    
-
-  private:
-    class WebServicePayload;
-
-  protected:
-    IWebService&  web_;
-    std::string   baseUrl_;
-
-  public:
-    OrthancApiClient(IWebService& web,
-                     const std::string& baseUrl);
-    
-    virtual ~OrthancApiClient()
-    {
-    }
-
-    const std::string& GetBaseUrl() const {return baseUrl_;}
-
-    // schedule a GET request expecting a JSON response.
-    void GetJsonAsync(const std::string& uri,
-                      MessageHandler<JsonResponseReadyMessage>* successCallback,
-                      MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback = NULL,
-                      Orthanc::IDynamicObject* payload = NULL   /* takes ownership */);
-
-    // schedule a GET request expecting a binary response.
-    void GetBinaryAsync(const std::string& uri,
-                        const std::string& contentType,
-                        MessageHandler<BinaryResponseReadyMessage>* successCallback,
-                        MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback = NULL,
-                        Orthanc::IDynamicObject* payload = NULL   /* takes ownership */);
-
-    // schedule a GET request expecting a binary response.
-    void GetBinaryAsync(const std::string& uri,
-                        const IWebService::HttpHeaders& headers,
-                        MessageHandler<BinaryResponseReadyMessage>* successCallback,
-                        MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback = NULL,
-                        Orthanc::IDynamicObject* payload = NULL   /* takes ownership */);
-
-    // schedule a POST request expecting a JSON response.
-    void PostBinaryAsyncExpectJson(const std::string& uri,
-                                   const std::string& body,
-                                   MessageHandler<JsonResponseReadyMessage>* successCallback,
-                                   MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback = NULL,
-                                   Orthanc::IDynamicObject* payload = NULL   /* takes ownership */);
-
-    // schedule a POST request expecting a JSON response.
-    void PostJsonAsyncExpectJson(const std::string& uri,
-                                 const Json::Value& data,
-                                 MessageHandler<JsonResponseReadyMessage>* successCallback,
-                                 MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback = NULL,
-                                 Orthanc::IDynamicObject* payload = NULL   /* takes ownership */);
-
-    // schedule a POST request and don't mind the response.
-    void PostJsonAsync(const std::string& uri,
-                       const Json::Value& data);
-
-    // schedule a POST request and don't expect any response.
-    void PostJsonAsync(const std::string& uri,
-                       const Json::Value& data,
-                       MessageHandler<EmptyResponseReadyMessage>* successCallback,
-                       MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback = NULL,
-                       Orthanc::IDynamicObject* payload = NULL   /* takes ownership */);
-
-
-    // schedule a POST request and don't mind the response.
-    void PostBinaryAsync(const std::string& uri,
-                         const std::string& body);
-
-    // schedule a POST request and don't expect any response.
-    void PostBinaryAsync(const std::string& uri,
-                         const std::string& body,
-                         MessageHandler<EmptyResponseReadyMessage>* successCallback,
-                         MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback = NULL,
-                         Orthanc::IDynamicObject* payload = NULL   /* takes ownership */);
-
-    // schedule a DELETE request expecting an empty response.
-    void DeleteAsync(const std::string& uri,
-                     MessageHandler<EmptyResponseReadyMessage>* successCallback,
-                     MessageHandler<IWebService::HttpRequestErrorMessage>* failureCallback = NULL,
-                     Orthanc::IDynamicObject* payload = NULL   /* takes ownership */);
-
-    void NotifyHttpSuccess(const IWebService::HttpRequestSuccessMessage& message);
-
-    void NotifyHttpError(const IWebService::HttpRequestErrorMessage& message);
-
-  private:
-    void HandleFromCache(const std::string& uri,
-                         const IWebService::HttpHeaders& headers,
-                         Orthanc::IDynamicObject* payload /* takes ownership */);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/OrthancSlicesLoader.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,901 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "OrthancSlicesLoader.h"
-
-#include "../Toolbox/MessagingToolbox.h"
-
-#include <Compression/GzipCompressor.h>
-#include <Endianness.h>
-#include <Images/Image.h>
-#include <Images/ImageProcessing.h>
-#include <Images/JpegReader.h>
-#include <Images/PngReader.h>
-#include <Images/PamReader.h>
-#include <Logging.h>
-#include <OrthancException.h>
-#include <Toolbox.h>
-#include <FullOrthancDataset.h>
-
-#include <boost/lexical_cast.hpp>
-
-
-
-/**
- * TODO This is a SLOW implementation of base64 decoding, because
- * "Orthanc::Toolbox::DecodeBase64()" does not work properly with
- * WASM. UNDERSTAND WHY.
- * https://stackoverflow.com/a/34571089/881731
- **/
-static std::string base64_decode(const std::string &in)
-{
-  std::string out;
-  
-  std::vector<int> T(256,-1);
-  for (int i=0; i<64; i++) T["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i]] = i;
-  
-  int val=0, valb=-8;
-  for (size_t i = 0; i < in.size(); i++) {
-    unsigned char c = in[i];
-    if (T[c] == -1) break;
-    val = (val<<6) + T[c];
-    valb += 6;
-    if (valb>=0) {
-      out.push_back(char((val>>valb)&0xFF));
-      valb-=8;
-    }
-  }
-  return out;
-}
-
-
-
-namespace Deprecated
-{
-  class OrthancSlicesLoader::Operation : public Orthanc::IDynamicObject
-  {
-  private:
-    Mode               mode_;
-    unsigned int       frame_;
-    unsigned int       sliceIndex_;
-    const Slice*       slice_;
-    std::string        instanceId_;
-    SliceImageQuality  quality_;
-
-    Operation(Mode mode) :
-      mode_(mode)
-    {
-    }
-
-  public:
-    Mode GetMode() const
-    {
-      return mode_;
-    }
-
-    SliceImageQuality GetQuality() const
-    {
-      assert(mode_ == Mode_LoadImage ||
-             mode_ == Mode_LoadRawImage);
-      return quality_;
-    }
-
-    unsigned int GetSliceIndex() const
-    {
-      assert(mode_ == Mode_LoadImage ||
-             mode_ == Mode_LoadRawImage);
-      return sliceIndex_;
-    }
-
-    const Slice& GetSlice() const
-    {
-      assert(mode_ == Mode_LoadImage ||
-             mode_ == Mode_LoadRawImage);
-      assert(slice_ != NULL);
-      return *slice_;
-    }
-
-    unsigned int GetFrame() const
-    {
-      assert(mode_ == Mode_FrameGeometry);
-      return frame_;
-    }
-
-    const std::string& GetInstanceId() const
-    {
-      assert(mode_ == Mode_FrameGeometry ||
-             mode_ == Mode_InstanceGeometry);
-      return instanceId_;
-    }
-
-    static Operation* DownloadInstanceGeometry(const std::string& instanceId)
-    {
-      std::unique_ptr<Operation> operation(new Operation(Mode_InstanceGeometry));
-      operation->instanceId_ = instanceId;
-      return operation.release();
-    }
-
-    static Operation* DownloadFrameGeometry(const std::string& instanceId,
-                                            unsigned int frame)
-    {
-      std::unique_ptr<Operation> operation(new Operation(Mode_FrameGeometry));
-      operation->instanceId_ = instanceId;
-      operation->frame_ = frame;
-      return operation.release();
-    }
-
-    static Operation* DownloadSliceImage(unsigned int  sliceIndex,
-                                         const Slice&  slice,
-                                         SliceImageQuality quality)
-    {
-      std::unique_ptr<Operation> tmp(new Operation(Mode_LoadImage));
-      tmp->sliceIndex_ = sliceIndex;
-      tmp->slice_ = &slice;
-      tmp->quality_ = quality;
-      return tmp.release();
-    }
-
-    static Operation* DownloadSliceRawImage(unsigned int  sliceIndex,
-                                            const Slice&  slice)
-    {
-      std::unique_ptr<Operation> tmp(new Operation(Mode_LoadRawImage));
-      tmp->sliceIndex_ = sliceIndex;
-      tmp->slice_ = &slice;
-      tmp->quality_ = SliceImageQuality_InternalRaw;
-      return tmp.release();
-    }
-
-    static Operation* DownloadDicomFile(const Slice&  slice)
-    {
-      std::unique_ptr<Operation> tmp(new Operation(Mode_LoadDicomFile));
-      tmp->slice_ = &slice;
-      return tmp.release();
-    }
-
-  };
-
-  void OrthancSlicesLoader::NotifySliceImageSuccess(const Operation& operation,
-                                                    const Orthanc::ImageAccessor& image)
-  {
-    OrthancSlicesLoader::SliceImageReadyMessage msg
-      (*this, operation.GetSliceIndex(), operation.GetSlice(), image, operation.GetQuality());
-    BroadcastMessage(msg);
-  }
-  
-  
-  void OrthancSlicesLoader::NotifySliceImageError(const Operation& operation)
-  {
-    OrthancSlicesLoader::SliceImageErrorMessage msg
-      (*this, operation.GetSliceIndex(), operation.GetSlice(), operation.GetQuality());
-    BroadcastMessage(msg);
-  }
-  
-  
-  void OrthancSlicesLoader::SortAndFinalizeSlices()
-  {
-    bool ok = slices_.Sort();
-    
-    state_ = State_GeometryReady;
-    
-    if (ok)
-    {
-      LOG(INFO) << "Loaded a series with " << slices_.GetSlicesCount() << " slice(s)";
-      BroadcastMessage(SliceGeometryReadyMessage(*this));
-    }
-    else
-    {
-      LOG(ERROR) << "This series is empty";
-      BroadcastMessage(SliceGeometryErrorMessage(*this));
-    }
-  }
-  
-  void OrthancSlicesLoader::OnGeometryError(const IWebService::HttpRequestErrorMessage& message)
-  {
-    BroadcastMessage(SliceGeometryErrorMessage(*this));
-    state_ = State_Error;
-  }
-
-  void OrthancSlicesLoader::OnSliceImageError(const IWebService::HttpRequestErrorMessage& message)
-  {
-    NotifySliceImageError(dynamic_cast<const Operation&>(message.GetPayload()));
-    state_ = State_Error;
-  }
-
-  void OrthancSlicesLoader::ParseSeriesGeometry(const OrthancApiClient::JsonResponseReadyMessage& message)
-  {
-    const Json::Value& series = message.GetJson();
-    Json::Value::Members instances = series.getMemberNames();
-    
-    slices_.Reserve(instances.size());
-    
-    for (size_t i = 0; i < instances.size(); i++)
-    {
-      OrthancPlugins::FullOrthancDataset dataset(series[instances[i]]);
-      
-      Orthanc::DicomMap dicom;
-      MessagingToolbox::ConvertDataset(dicom, dataset);
-      
-      unsigned int frames;
-      if (!dicom.ParseUnsignedInteger32(frames, Orthanc::DICOM_TAG_NUMBER_OF_FRAMES))
-      {
-        frames = 1;
-      }
-      
-      for (unsigned int frame = 0; frame < frames; frame++)
-      {
-        std::unique_ptr<Slice> slice(new Slice);
-        if (slice->ParseOrthancFrame(dicom, instances[i], frame))
-        {
-          OrthancStone::CoordinateSystem3D geometry = slice->GetGeometry();
-          slices_.AddSlice(geometry, slice.release());
-        }
-        else
-        {
-          LOG(WARNING) << "Skipping invalid frame " << frame << " within instance " << instances[i];
-        }
-      }
-    }
-    
-    SortAndFinalizeSlices();
-  }
-  
-  void OrthancSlicesLoader::ParseInstanceGeometry(const OrthancApiClient::JsonResponseReadyMessage& message)
-  {
-    const Json::Value& tags = message.GetJson();
-    const std::string& instanceId = dynamic_cast<const OrthancSlicesLoader::Operation&>(message.GetPayload()).GetInstanceId();
-
-    OrthancPlugins::FullOrthancDataset dataset(tags);
-    
-    Orthanc::DicomMap dicom;
-    MessagingToolbox::ConvertDataset(dicom, dataset);
-
-    unsigned int frames;
-    if (!dicom.ParseUnsignedInteger32(frames, Orthanc::DICOM_TAG_NUMBER_OF_FRAMES))
-    {
-      frames = 1;
-    }
-    
-    LOG(INFO) << "Instance " << instanceId << " contains " << frames << " frame(s)";
-    
-    for (unsigned int frame = 0; frame < frames; frame++)
-    {
-      std::unique_ptr<Slice> slice(new Slice);
-      if (slice->ParseOrthancFrame(dicom, instanceId, frame))
-      {
-        OrthancStone::CoordinateSystem3D geometry = slice->GetGeometry();
-        slices_.AddSlice(geometry, slice.release());
-      }
-      else
-      {
-        LOG(WARNING) << "Skipping invalid multi-frame instance " << instanceId;
-        BroadcastMessage(SliceGeometryErrorMessage(*this));
-        return;
-      }
-    }
-    
-    SortAndFinalizeSlices();
-  }
-  
-  
-  void OrthancSlicesLoader::ParseFrameGeometry(const OrthancApiClient::JsonResponseReadyMessage& message)
-  {
-    const Json::Value& tags = message.GetJson();
-    const std::string& instanceId = dynamic_cast<const OrthancSlicesLoader::Operation&>(message.GetPayload()).GetInstanceId();
-    unsigned int frame = dynamic_cast<const OrthancSlicesLoader::Operation&>(message.GetPayload()).GetFrame();
-
-    OrthancPlugins::FullOrthancDataset dataset(tags);
-    
-    state_ = State_GeometryReady;
-    
-    Orthanc::DicomMap dicom;
-    MessagingToolbox::ConvertDataset(dicom, dataset);
-    
-    std::unique_ptr<Slice> slice(new Slice);
-    if (slice->ParseOrthancFrame(dicom, instanceId, frame))
-    {
-      LOG(INFO) << "Loaded instance geometry " << instanceId;
-
-      OrthancStone::CoordinateSystem3D geometry = slice->GetGeometry();
-      slices_.AddSlice(geometry, slice.release());
-      
-      BroadcastMessage(SliceGeometryReadyMessage(*this));
-    }
-    else
-    {
-      LOG(WARNING) << "Skipping invalid instance " << instanceId;
-      BroadcastMessage(SliceGeometryErrorMessage(*this));
-    }
-  }
-  
-  
-  void OrthancSlicesLoader::ParseSliceImagePng(const OrthancApiClient::BinaryResponseReadyMessage& message)
-  {
-    const Operation& operation = dynamic_cast<const OrthancSlicesLoader::Operation&>(message.GetPayload());
-    std::unique_ptr<Orthanc::ImageAccessor>  image;
-    
-    try
-    {
-      image.reset(new Orthanc::PngReader);
-      dynamic_cast<Orthanc::PngReader&>(*image).ReadFromMemory(message.GetAnswer(), message.GetAnswerSize());
-    }
-    catch (Orthanc::OrthancException&)
-    {
-      NotifySliceImageError(operation);
-      return;
-    }
-    
-    if (image->GetWidth() != operation.GetSlice().GetWidth() ||
-        image->GetHeight() != operation.GetSlice().GetHeight())
-    {
-      NotifySliceImageError(operation);
-      return;
-    }
-
-    if (operation.GetSlice().GetConverter().GetExpectedPixelFormat() ==
-        Orthanc::PixelFormat_SignedGrayscale16)
-    {
-      if (image->GetFormat() == Orthanc::PixelFormat_Grayscale16)
-      {
-        image->SetFormat(Orthanc::PixelFormat_SignedGrayscale16);
-      }
-      else
-      {
-        NotifySliceImageError(operation);
-        return;
-      }
-    }
-    
-    NotifySliceImageSuccess(operation, *image);
-  }
-  
-  void OrthancSlicesLoader::ParseSliceImagePam(const OrthancApiClient::BinaryResponseReadyMessage& message)
-  {
-    const Operation& operation = dynamic_cast<const OrthancSlicesLoader::Operation&>(message.GetPayload());
-    std::unique_ptr<Orthanc::ImageAccessor>  image;
-
-    try
-    {
-      image.reset(new Orthanc::PamReader);
-      dynamic_cast<Orthanc::PamReader&>(*image).ReadFromMemory(message.GetAnswer(), message.GetAnswerSize());
-    }
-    catch (Orthanc::OrthancException&)
-    {
-      NotifySliceImageError(operation);
-      return;
-    }
-
-    if (image->GetWidth() != operation.GetSlice().GetWidth() ||
-        image->GetHeight() != operation.GetSlice().GetHeight())
-    {
-      NotifySliceImageError(operation);
-      return;
-    }
-
-    if (operation.GetSlice().GetConverter().GetExpectedPixelFormat() ==
-        Orthanc::PixelFormat_SignedGrayscale16)
-    {
-      if (image->GetFormat() == Orthanc::PixelFormat_Grayscale16)
-      {
-        image->SetFormat(Orthanc::PixelFormat_SignedGrayscale16);
-      }
-      else
-      {
-        NotifySliceImageError(operation);
-        return;
-      }
-    }
-
-    NotifySliceImageSuccess(operation, *image);
-  }
-
-
-  void OrthancSlicesLoader::ParseSliceImageJpeg(const OrthancApiClient::JsonResponseReadyMessage& message)
-  {
-    const Operation& operation = dynamic_cast<const OrthancSlicesLoader::Operation&>(message.GetPayload());
-
-    const Json::Value& encoded = message.GetJson();
-    if (encoded.type() != Json::objectValue ||
-        !encoded.isMember("Orthanc") ||
-        encoded["Orthanc"].type() != Json::objectValue)
-    {
-      NotifySliceImageError(operation);
-      return;
-    }
-    
-    const Json::Value& info = encoded["Orthanc"];
-    if (!info.isMember("PixelData") ||
-        !info.isMember("Stretched") ||
-        !info.isMember("Compression") ||
-        info["Compression"].type() != Json::stringValue ||
-        info["PixelData"].type() != Json::stringValue ||
-        info["Stretched"].type() != Json::booleanValue ||
-        info["Compression"].asString() != "Jpeg")
-    {
-      NotifySliceImageError(operation);
-      return;
-    }
-    
-    bool isSigned = false;
-    bool isStretched = info["Stretched"].asBool();
-    
-    if (info.isMember("IsSigned"))
-    {
-      if (info["IsSigned"].type() != Json::booleanValue)
-      {
-        NotifySliceImageError(operation);
-        return;
-      }
-      else
-      {
-        isSigned = info["IsSigned"].asBool();
-      }
-    }
-    
-    std::unique_ptr<Orthanc::ImageAccessor> reader;
-    
-    {
-      std::string jpeg;
-      //Orthanc::Toolbox::DecodeBase64(jpeg, info["PixelData"].asString());
-      jpeg = base64_decode(info["PixelData"].asString());
-      
-      try
-      {
-        reader.reset(new Orthanc::JpegReader);
-        dynamic_cast<Orthanc::JpegReader&>(*reader).ReadFromMemory(jpeg);
-      }
-      catch (Orthanc::OrthancException&)
-      {
-        NotifySliceImageError(operation);
-        return;
-      }
-    }
-    
-    Orthanc::PixelFormat expectedFormat =
-      operation.GetSlice().GetConverter().GetExpectedPixelFormat();
-    
-    if (reader->GetFormat() == Orthanc::PixelFormat_RGB24)  // This is a color image
-    {
-      if (expectedFormat != Orthanc::PixelFormat_RGB24)
-      {
-        NotifySliceImageError(operation);
-        return;
-      }
-      
-      if (isSigned || isStretched)
-      {
-        NotifySliceImageError(operation);
-        return;
-      }
-      else
-      {
-        NotifySliceImageSuccess(operation, *reader);
-        return;
-      }
-    }
-    
-    if (reader->GetFormat() != Orthanc::PixelFormat_Grayscale8)
-    {
-      NotifySliceImageError(operation);
-      return;
-    }
-    
-    if (!isStretched)
-    {
-      if (expectedFormat != reader->GetFormat())
-      {
-        NotifySliceImageError(operation);
-        return;
-      }
-      else
-      {
-        NotifySliceImageSuccess(operation, *reader);
-        return;
-      }
-    }
-    
-    int32_t stretchLow = 0;
-    int32_t stretchHigh = 0;
-    
-    if (!info.isMember("StretchLow") ||
-        !info.isMember("StretchHigh") ||
-        info["StretchLow"].type() != Json::intValue ||
-        info["StretchHigh"].type() != Json::intValue)
-    {
-      NotifySliceImageError(operation);
-      return;
-    }
-    
-    stretchLow = info["StretchLow"].asInt();
-    stretchHigh = info["StretchHigh"].asInt();
-    
-    if (stretchLow < -32768 ||
-        stretchHigh > 65535 ||
-        (stretchLow < 0 && stretchHigh > 32767))
-    {
-      // This range cannot be represented with a uint16_t or an int16_t
-      NotifySliceImageError(operation);
-      return;
-    }
-    
-    // Decode a grayscale JPEG 8bpp image coming from the Web viewer
-    std::unique_ptr<Orthanc::ImageAccessor> image
-      (new Orthanc::Image(expectedFormat, reader->GetWidth(), reader->GetHeight(), false));
-
-    Orthanc::ImageProcessing::Convert(*image, *reader);
-    reader.reset();
-    
-    float scaling = static_cast<float>(stretchHigh - stretchLow) / 255.0f;
-    
-    if (!OrthancStone::LinearAlgebra::IsCloseToZero(scaling))
-    {
-      float offset = static_cast<float>(stretchLow) / scaling;
-      Orthanc::ImageProcessing::ShiftScale(*image, offset, scaling, true);
-    }
-    
-    NotifySliceImageSuccess(operation, *image);
-  }
-
-
-  class StringImage : public Orthanc::ImageAccessor
-  {
-  private:
-    std::string  buffer_;
-    
-  public:
-    StringImage(Orthanc::PixelFormat format,
-                unsigned int width,
-                unsigned int height,
-                std::string& buffer)
-    {
-      if (buffer.size() != Orthanc::GetBytesPerPixel(format) * width * height)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat);
-      }
-      
-      buffer_.swap(buffer);  // The source buffer is now empty
-      
-      void* data = (buffer_.empty() ? NULL : &buffer_[0]);
-      
-      AssignWritable(format, width, height,
-                     Orthanc::GetBytesPerPixel(format) * width, data);
-    }
-  };
-  
-  void OrthancSlicesLoader::ParseSliceRawImage(const OrthancApiClient::BinaryResponseReadyMessage& message)
-  {
-    const Operation& operation = dynamic_cast<const OrthancSlicesLoader::Operation&>(message.GetPayload());
-    Orthanc::GzipCompressor compressor;
-    
-    std::string raw;
-    compressor.Uncompress(raw, message.GetAnswer(), message.GetAnswerSize());
-    
-    const Orthanc::DicomImageInformation& info = operation.GetSlice().GetImageInformation();
-    
-    if (info.GetBitsAllocated() == 32 &&
-        info.GetBitsStored() == 32 &&
-        info.GetHighBit() == 31 &&
-        info.GetChannelCount() == 1 &&
-        !info.IsSigned() &&
-        info.GetPhotometricInterpretation() == Orthanc::PhotometricInterpretation_Monochrome2 &&
-        raw.size() == info.GetWidth() * info.GetHeight() * 4)
-    {
-      // This is the case of RT-DOSE (uint32_t values)
-      
-      std::unique_ptr<Orthanc::ImageAccessor> image
-        (new StringImage(Orthanc::PixelFormat_Grayscale32, info.GetWidth(),
-                         info.GetHeight(), raw));
-      
-      // TODO - Only for big endian
-      for (unsigned int y = 0; y < image->GetHeight(); y++)
-      {
-        uint32_t *p = reinterpret_cast<uint32_t*>(image->GetRow(y));
-        for (unsigned int x = 0; x < image->GetWidth(); x++, p++)
-        {
-          *p = le32toh(*p);
-        }
-      }
-      
-      NotifySliceImageSuccess(operation, *image);
-    }
-    else if (info.GetBitsAllocated() == 16 &&
-             info.GetBitsStored() == 16 &&
-             info.GetHighBit() == 15 &&
-             info.GetChannelCount() == 1 &&
-             !info.IsSigned() &&
-             info.GetPhotometricInterpretation() == Orthanc::PhotometricInterpretation_Monochrome2 &&
-             raw.size() == info.GetWidth() * info.GetHeight() * 2)
-    {
-      std::unique_ptr<Orthanc::ImageAccessor> image
-        (new StringImage(Orthanc::PixelFormat_Grayscale16, info.GetWidth(),
-                         info.GetHeight(), raw));
-      
-      // TODO - Big endian ?
-      
-      NotifySliceImageSuccess(operation, *image);
-    }
-    else
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
-    }
-
-  }
-  
-  
-  OrthancSlicesLoader::OrthancSlicesLoader(boost::shared_ptr<OrthancApiClient> orthanc) :
-    orthanc_(orthanc),
-    state_(State_Initialization)
-  {
-  }
-  
-  
-  void OrthancSlicesLoader::ScheduleLoadSeries(const std::string& seriesId)
-  {
-    if (state_ != State_Initialization)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-    else
-    {
-      state_ = State_LoadingGeometry;
-      orthanc_->GetJsonAsync("/series/" + seriesId + "/instances-tags",
-                             new DeprecatedCallable<OrthancSlicesLoader, OrthancApiClient::JsonResponseReadyMessage>(GetSharedObserver(), &OrthancSlicesLoader::ParseSeriesGeometry),
-                             new DeprecatedCallable<OrthancSlicesLoader, IWebService::HttpRequestErrorMessage>(GetSharedObserver(), &OrthancSlicesLoader::OnGeometryError),
-                             NULL);
-    }
-  }
-  
-  void OrthancSlicesLoader::ScheduleLoadInstance(const std::string& instanceId)
-  {
-    if (state_ != State_Initialization)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-    else
-    {
-      state_ = State_LoadingGeometry;
-      
-      // Tag "3004-000c" is "Grid Frame Offset Vector", which is
-      // mandatory to read RT DOSE, but is too long to be returned by default
-      orthanc_->GetJsonAsync("/instances/" + instanceId + "/tags?ignore-length=3004-000c",
-                             new DeprecatedCallable<OrthancSlicesLoader, OrthancApiClient::JsonResponseReadyMessage>(GetSharedObserver(), &OrthancSlicesLoader::ParseInstanceGeometry),
-                             new DeprecatedCallable<OrthancSlicesLoader, IWebService::HttpRequestErrorMessage>(GetSharedObserver(), &OrthancSlicesLoader::OnGeometryError),
-                             Operation::DownloadInstanceGeometry(instanceId));
-    }
-  }
-  
-  
-  void OrthancSlicesLoader::ScheduleLoadFrame(const std::string& instanceId,
-                                              unsigned int frame)
-  {
-    if (state_ != State_Initialization)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-    else
-    {
-      state_ = State_LoadingGeometry;
-
-      orthanc_->GetJsonAsync("/instances/" + instanceId + "/tags",
-                             new DeprecatedCallable<OrthancSlicesLoader, OrthancApiClient::JsonResponseReadyMessage>(GetSharedObserver(), &OrthancSlicesLoader::ParseFrameGeometry),
-                             new DeprecatedCallable<OrthancSlicesLoader, IWebService::HttpRequestErrorMessage>(GetSharedObserver(), &OrthancSlicesLoader::OnGeometryError),
-                             Operation::DownloadFrameGeometry(instanceId, frame));
-    }
-  }
-  
-  
-  bool OrthancSlicesLoader::IsGeometryReady() const
-  {
-    return state_ == State_GeometryReady;
-  }
-  
-  
-  size_t OrthancSlicesLoader::GetSlicesCount() const
-  {
-    if (state_ != State_GeometryReady)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-    
-    return slices_.GetSlicesCount();
-  }
-  
-  
-  const Slice& OrthancSlicesLoader::GetSlice(size_t index) const
-  {
-    if (state_ != State_GeometryReady)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-
-    return dynamic_cast<const Slice&>(slices_.GetSlicePayload(index));
-  }
-  
-  
-  bool OrthancSlicesLoader::LookupSlice(size_t& index,
-                                        const OrthancStone::CoordinateSystem3D& plane) const
-  {
-    if (state_ != State_GeometryReady)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-
-    double distance;
-    return (slices_.LookupClosestSlice(index, distance, plane) &&
-            distance <= GetSlice(index).GetThickness() / 2.0);
-  }
-  
-  
-  void OrthancSlicesLoader::ScheduleSliceImagePng(const Slice& slice,
-                                                  size_t index)
-  {
-    std::string uri = ("/instances/" + slice.GetOrthancInstanceId() + "/frames/" +
-                       boost::lexical_cast<std::string>(slice.GetFrame()));
-    
-    switch (slice.GetConverter().GetExpectedPixelFormat())
-    {
-      case Orthanc::PixelFormat_RGB24:
-        uri += "/preview";
-        break;
-      
-      case Orthanc::PixelFormat_Grayscale16:
-        uri += "/image-uint16";
-        break;
-      
-      case Orthanc::PixelFormat_SignedGrayscale16:
-        uri += "/image-int16";
-        break;
-      
-      default:
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-    
-    orthanc_->GetBinaryAsync(uri, "image/png",
-                             new DeprecatedCallable<OrthancSlicesLoader, 
-                             OrthancApiClient::BinaryResponseReadyMessage>
-                             (GetSharedObserver(), &OrthancSlicesLoader::ParseSliceImagePng),
-                             new DeprecatedCallable<OrthancSlicesLoader, 
-                             IWebService::HttpRequestErrorMessage>
-                             (GetSharedObserver(), &OrthancSlicesLoader::OnSliceImageError),
-                             Operation::DownloadSliceImage(
-                               static_cast<unsigned int>(index), slice, SliceImageQuality_FullPng));
-  }
-  
-  void OrthancSlicesLoader::ScheduleSliceImagePam(const Slice& slice,
-                                                  size_t index)
-  {
-    std::string uri = 
-      ("/instances/" + slice.GetOrthancInstanceId() + "/frames/" +
-       boost::lexical_cast<std::string>(slice.GetFrame()));
-
-    switch (slice.GetConverter().GetExpectedPixelFormat())
-    {
-      case Orthanc::PixelFormat_RGB24:
-        uri += "/preview";
-        break;
-
-      case Orthanc::PixelFormat_Grayscale16:
-        uri += "/image-uint16";
-        break;
-
-      case Orthanc::PixelFormat_SignedGrayscale16:
-        uri += "/image-int16";
-        break;
-
-      default:
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    orthanc_->GetBinaryAsync(uri, "image/x-portable-arbitrarymap",
-                             new DeprecatedCallable<OrthancSlicesLoader, 
-                             OrthancApiClient::BinaryResponseReadyMessage>
-                             (GetSharedObserver(), &OrthancSlicesLoader::ParseSliceImagePam),
-                             new DeprecatedCallable<OrthancSlicesLoader, 
-                             IWebService::HttpRequestErrorMessage>
-                             (GetSharedObserver(), &OrthancSlicesLoader::OnSliceImageError),
-                             Operation::DownloadSliceImage(static_cast<unsigned int>(index), 
-                                                           slice, SliceImageQuality_FullPam));
-  }
-
-
-  
-  void OrthancSlicesLoader::ScheduleSliceImageJpeg(const Slice& slice,
-                                                   size_t index,
-                                                   SliceImageQuality quality)
-  {
-    unsigned int value;
-    
-    switch (quality)
-    {
-      case SliceImageQuality_Jpeg50:
-        value = 50;
-        break;
-
-      case SliceImageQuality_Jpeg90:
-        value = 90;
-        break;
-
-      case SliceImageQuality_Jpeg95:
-        value = 95;
-        break;
-      
-      default:
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-    
-    // This requires the official Web viewer plugin to be installed!
-    std::string uri = ("/web-viewer/instances/jpeg" +
-                       boost::lexical_cast<std::string>(value) +
-                       "-" + slice.GetOrthancInstanceId() + "_" +
-                       boost::lexical_cast<std::string>(slice.GetFrame()));
-
-    orthanc_->GetJsonAsync(uri,
-                           new DeprecatedCallable<OrthancSlicesLoader, 
-                           OrthancApiClient::JsonResponseReadyMessage>
-                           (GetSharedObserver(), &OrthancSlicesLoader::ParseSliceImageJpeg),
-                           new DeprecatedCallable<OrthancSlicesLoader, 
-                           IWebService::HttpRequestErrorMessage>
-                           (GetSharedObserver(), &OrthancSlicesLoader::OnSliceImageError),
-                           Operation::DownloadSliceImage(
-                             static_cast<unsigned int>(index), slice, quality));
-  }
-  
-  
-  
-  void OrthancSlicesLoader::ScheduleLoadSliceImage(size_t index,
-                                                   SliceImageQuality quality)
-  {
-    if (state_ != State_GeometryReady)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-    
-    const Slice& slice = GetSlice(index);
-    
-    if (slice.HasOrthancDecoding())
-    {
-      switch (quality)
-      {
-        case SliceImageQuality_FullPng:
-          ScheduleSliceImagePng(slice, index);
-          break;
-        case SliceImageQuality_FullPam:
-          ScheduleSliceImagePam(slice, index);
-          break;
-        default:
-          ScheduleSliceImageJpeg(slice, index, quality);
-      }
-    }
-    else
-    {
-      std::string uri = ("/instances/" + slice.GetOrthancInstanceId() + "/frames/" +
-                         boost::lexical_cast<std::string>(slice.GetFrame()) + "/raw.gz");
-      orthanc_->GetBinaryAsync(uri, IWebService::HttpHeaders(),
-                               new DeprecatedCallable<OrthancSlicesLoader, 
-                               OrthancApiClient::BinaryResponseReadyMessage>
-                               (GetSharedObserver(), &OrthancSlicesLoader::ParseSliceRawImage),
-                               new DeprecatedCallable<OrthancSlicesLoader,
-                               IWebService::HttpRequestErrorMessage>
-                               (GetSharedObserver(), &OrthancSlicesLoader::OnSliceImageError),
-                               Operation::DownloadSliceRawImage(
-                                 static_cast<unsigned int>(index), slice));
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/OrthancSlicesLoader.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,211 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Messages/IObservable.h"
-#include "../../Messages/ObserverBase.h"
-#include "../../StoneEnumerations.h"
-#include "../../Toolbox/SlicesSorter.h"
-#include "IWebService.h"
-#include "OrthancApiClient.h"
-#include "Slice.h"
-
-#include <Images/Image.h>
-
-
-namespace Deprecated
-{
-  class OrthancSlicesLoader :
-    public OrthancStone::IObservable,
-    public OrthancStone::ObserverBase<OrthancSlicesLoader>
-  {
-  public:
-    ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, SliceGeometryReadyMessage, OrthancSlicesLoader);
-    ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, SliceGeometryErrorMessage, OrthancSlicesLoader);
-
-    
-    class SliceImageReadyMessage : public OrthancStone::OriginMessage<OrthancSlicesLoader>
-    {
-      ORTHANC_STONE_MESSAGE(__FILE__, __LINE__);
-      
-    private:
-      unsigned int                   sliceIndex_;
-      const Slice&                   slice_;
-      const Orthanc::ImageAccessor&  image_;
-      SliceImageQuality              effectiveQuality_;
-
-    public:
-      SliceImageReadyMessage(const OrthancSlicesLoader& origin,
-                             unsigned int sliceIndex,
-                             const Slice& slice,
-                             const Orthanc::ImageAccessor& image,
-                             SliceImageQuality effectiveQuality) :
-        OriginMessage(origin),
-        sliceIndex_(sliceIndex),
-        slice_(slice),
-        image_(image),
-        effectiveQuality_(effectiveQuality)
-      {
-      }
-
-      unsigned int GetSliceIndex() const
-      {
-        return sliceIndex_;
-      }
-
-      const Slice& GetSlice() const
-      {
-        return slice_;
-      }
-
-      const Orthanc::ImageAccessor& GetImage() const
-      {
-        return image_;
-      }
-
-      SliceImageQuality GetEffectiveQuality() const
-      {
-        return effectiveQuality_;
-      }        
-    };
-    
-
-    class SliceImageErrorMessage : public OrthancStone::OriginMessage<OrthancSlicesLoader>
-    {
-      ORTHANC_STONE_MESSAGE(__FILE__, __LINE__);
-      
-    private:
-      const Slice&       slice_;
-      unsigned int       sliceIndex_;
-      SliceImageQuality  effectiveQuality_;
-
-    public:
-      SliceImageErrorMessage(const OrthancSlicesLoader& origin,
-                             unsigned int sliceIndex,
-                             const Slice& slice,
-                             SliceImageQuality effectiveQuality) :
-        OriginMessage(origin),
-        slice_(slice),
-        sliceIndex_(sliceIndex),
-        effectiveQuality_(effectiveQuality)
-      {
-      }
-      unsigned int GetSliceIndex() const
-      {
-        return sliceIndex_;
-      }
-
-      const Slice& GetSlice() const
-      {
-        return slice_;
-      }
-
-      SliceImageQuality GetEffectiveQuality() const
-      {
-        return effectiveQuality_;
-      }        
-    };
-    
-  private:
-    enum State
-    {
-      State_Error,
-      State_Initialization,
-      State_LoadingGeometry,
-      State_GeometryReady
-    };
-    
-    enum Mode
-    {
-      Mode_SeriesGeometry,
-      Mode_InstanceGeometry,
-      Mode_FrameGeometry,
-      Mode_LoadImage,
-      Mode_LoadRawImage,
-      Mode_LoadDicomFile
-    };
-
-    class Operation;
-
-    boost::shared_ptr<OrthancApiClient>  orthanc_;
-    State         state_;
-    OrthancStone::SlicesSorter  slices_;
-
-    void NotifySliceImageSuccess(const Operation& operation,
-                                 const Orthanc::ImageAccessor& image);
-    
-    void NotifySliceImageError(const Operation& operation);
-
-    void OnGeometryError(const IWebService::HttpRequestErrorMessage& message);
-
-    void OnSliceImageError(const IWebService::HttpRequestErrorMessage& message);
-
-    void ParseSeriesGeometry(const OrthancApiClient::JsonResponseReadyMessage& message);
-
-    void ParseInstanceGeometry(const OrthancApiClient::JsonResponseReadyMessage& message);
-
-    void ParseFrameGeometry(const OrthancApiClient::JsonResponseReadyMessage& message);
-
-    void ParseSliceImagePng(const OrthancApiClient::BinaryResponseReadyMessage& message);
-
-    void ParseSliceImagePam(const OrthancApiClient::BinaryResponseReadyMessage& message);
-
-    void ParseSliceImageJpeg(const OrthancApiClient::JsonResponseReadyMessage& message);
-
-    void ParseSliceRawImage(const OrthancApiClient::BinaryResponseReadyMessage& message);
-
-    void ScheduleSliceImagePng(const Slice& slice,
-                               size_t index);
-
-    void ScheduleSliceImagePam(const Slice& slice,
-                               size_t index);
-
-    void ScheduleSliceImageJpeg(const Slice& slice,
-                                size_t index,
-                                SliceImageQuality quality);
-
-    void SortAndFinalizeSlices();
-    
-  public:
-    OrthancSlicesLoader(//ISliceLoaderObserver& callback,
-      boost::shared_ptr<OrthancApiClient> orthancApi);
-
-    void ScheduleLoadSeries(const std::string& seriesId);
-
-    void ScheduleLoadInstance(const std::string& instanceId);
-
-    void ScheduleLoadFrame(const std::string& instanceId,
-                           unsigned int frame);
-
-    bool IsGeometryReady() const;
-
-    size_t GetSlicesCount() const;
-
-    const Slice& GetSlice(size_t index) const;
-
-    bool LookupSlice(size_t& index,
-                     const OrthancStone::CoordinateSystem3D& plane) const;
-
-    void ScheduleLoadSliceImage(size_t index,
-                                SliceImageQuality requestedQuality);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/ParallelSlices.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,215 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "ParallelSlices.h"
-
-#include "../../Toolbox/GeometryToolbox.h"
-#include "../../Volumes/ImageBuffer3D.h"
-
-#include <Logging.h>
-#include <OrthancException.h>
-
-namespace Deprecated
-{
-  ParallelSlices::ParallelSlices()
-  {
-    Clear();
-  }
-
-
-  ParallelSlices::ParallelSlices(const ParallelSlices& other)
-  {
-    normal_ = other.normal_;
-
-    slices_.resize(other.slices_.size());
-
-    for (size_t i = 0; i < slices_.size(); i++)
-    {
-      assert(other.slices_[i] != NULL);
-      slices_[i] = new OrthancStone::CoordinateSystem3D(*other.slices_[i]);
-    }
-  }
-
-
-  void ParallelSlices::Clear()
-  {
-    for (size_t i = 0; i < slices_.size(); i++)
-    {
-      if (slices_[i] != NULL)
-      {
-        delete slices_[i];
-        slices_[i] = NULL;
-      }
-    }
-
-    slices_.clear();
-    OrthancStone::LinearAlgebra::AssignVector(normal_, 0, 0, 1);
-  }
-  
-
-  ParallelSlices::~ParallelSlices()
-  {
-    Clear();
-  }
-
-
-  void ParallelSlices::AddSlice(const OrthancStone::CoordinateSystem3D& slice)
-  {
-    if (slices_.empty())
-    {
-      normal_ = slice.GetNormal();
-      slices_.push_back(new OrthancStone::CoordinateSystem3D(slice));
-    }
-    else if (OrthancStone::GeometryToolbox::IsParallel(slice.GetNormal(), normal_))
-    {
-      slices_.push_back(new OrthancStone::CoordinateSystem3D(slice));
-    }
-    else
-    {
-      LOG(ERROR) << "Trying to add a slice that is not parallel to the previous ones";
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-  }
-
-
-  void ParallelSlices::AddSlice(const OrthancStone::Vector& origin,
-                                const OrthancStone::Vector& axisX,
-                                const OrthancStone::Vector& axisY)
-  {
-    OrthancStone::CoordinateSystem3D slice(origin, axisX, axisY);
-    AddSlice(slice);
-  }
-
-
-  const OrthancStone::CoordinateSystem3D& ParallelSlices::GetSlice(size_t index) const
-  {
-    if (index >= slices_.size())
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-    else
-    {
-      return *slices_[index];
-    }
-  }
-
-
-  bool ParallelSlices::ComputeClosestSlice(size_t& closestSlice,
-                                           double& closestDistance,
-                                           const OrthancStone::Vector& origin) const
-  {
-    if (slices_.empty())
-    {
-      return false;
-    }
-
-    double reference = boost::numeric::ublas::inner_prod(origin, normal_);
-
-    closestSlice = 0;
-    closestDistance = std::numeric_limits<double>::infinity();
-
-    for (size_t i = 0; i < slices_.size(); i++)
-    {
-      double distance = fabs(boost::numeric::ublas::inner_prod(slices_[i]->GetOrigin(), normal_) - reference);
-
-      if (distance < closestDistance)
-      {
-        closestSlice = i;
-        closestDistance = distance;
-      }
-    }
-
-    return true;
-  }
-
-
-  ParallelSlices* ParallelSlices::Reverse() const
-  {
-    std::unique_ptr<ParallelSlices> reversed(new ParallelSlices);
-
-    for (size_t i = slices_.size(); i > 0; i--)
-    {
-      const OrthancStone::CoordinateSystem3D& slice = *slices_[i - 1];
-
-      reversed->AddSlice(slice.GetOrigin(),
-                         -slice.GetAxisX(),
-                         slice.GetAxisY());
-    }
-
-    return reversed.release();
-  }
-
-
-  ParallelSlices* ParallelSlices::FromVolumeImage(const OrthancStone::VolumeImageGeometry& geometry,
-                                                  OrthancStone::VolumeProjection projection)
-  {
-    const OrthancStone::Vector dimensions = geometry.GetVoxelDimensions(OrthancStone::VolumeProjection_Axial);
-    const OrthancStone::CoordinateSystem3D& axial = geometry.GetAxialGeometry();
-    
-    std::unique_ptr<ParallelSlices> result(new ParallelSlices);
-
-    switch (projection)
-    {
-      case OrthancStone::VolumeProjection_Axial:
-        for (unsigned int z = 0; z < geometry.GetDepth(); z++)
-        {
-          OrthancStone::Vector origin = axial.GetOrigin();
-          origin += static_cast<double>(z) * dimensions[2] * axial.GetNormal();
-
-          result->AddSlice(origin,
-                           axial.GetAxisX(),
-                           axial.GetAxisY());
-        }
-        break;
-
-      case OrthancStone::VolumeProjection_Coronal:
-        for (unsigned int y = 0; y < geometry.GetHeight(); y++)
-        {
-          OrthancStone::Vector origin = axial.GetOrigin();
-          origin += static_cast<double>(y) * dimensions[1] * axial.GetAxisY();
-          origin += static_cast<double>(geometry.GetDepth() - 1) * dimensions[2] * axial.GetNormal();
-
-          result->AddSlice(origin,
-                           axial.GetAxisX(),
-                           -axial.GetNormal());
-        }
-        break;
-
-      case OrthancStone::VolumeProjection_Sagittal:
-        for (unsigned int x = 0; x < geometry.GetWidth(); x++)
-        {
-          OrthancStone::Vector origin = axial.GetOrigin();
-          origin += static_cast<double>(x) * dimensions[0] * axial.GetAxisX();
-          origin += static_cast<double>(geometry.GetDepth() - 1) * dimensions[2] * axial.GetNormal();
-
-          result->AddSlice(origin,
-                           axial.GetAxisY(),
-                           -axial.GetNormal());
-        }
-        break;
-
-      default:
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    return result.release();
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/ParallelSlices.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Toolbox/CoordinateSystem3D.h"
-#include "../../Volumes/VolumeImageGeometry.h"
-
-namespace Deprecated
-{
-  class ParallelSlices : public boost::noncopyable
-  {
-  private:
-    OrthancStone::Vector  normal_;
-    std::vector<OrthancStone::CoordinateSystem3D*>  slices_;
-    
-    ParallelSlices& operator= (const ParallelSlices& other);  // Forbidden
-
-    void Clear();
-
-  public:
-    ParallelSlices();
-
-    ParallelSlices(const ParallelSlices& other);
-
-    ~ParallelSlices();
-
-    const OrthancStone::Vector& GetNormal() const
-    {
-      return normal_;
-    }
-
-    void AddSlice(const OrthancStone::CoordinateSystem3D& slice);
-
-    void AddSlice(const OrthancStone::Vector& origin,
-                  const OrthancStone::Vector& axisX,
-                  const OrthancStone::Vector& axisY);
-
-    size_t GetSliceCount() const
-    {
-      return slices_.size();
-    }
-
-    const OrthancStone::CoordinateSystem3D& GetSlice(size_t index) const;
-
-    bool ComputeClosestSlice(size_t& closestSlice,
-                             double& closestDistance,
-                             const OrthancStone::Vector& origin) const;
-
-    ParallelSlices* Reverse() const;
-
-    static ParallelSlices* FromVolumeImage(const OrthancStone::VolumeImageGeometry& geometry,
-                                           OrthancStone::VolumeProjection projection);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/ParallelSlicesCursor.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,221 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "ParallelSlicesCursor.h"
-
-#include <OrthancException.h>
-
-namespace Deprecated
-{
-  size_t ParallelSlicesCursor::GetDefaultSlice()
-  {
-    if (slices_.get() == NULL)
-    {
-      return 0;
-    }
-    else
-    {
-      return slices_->GetSliceCount() / 2;
-    }
-  }
-
-
-  size_t ParallelSlicesCursor::GetSliceCount()
-  {
-    if (slices_.get() == NULL)
-    {
-      return 0;
-    }
-    else
-    {
-      return slices_->GetSliceCount();
-    }
-  }
-
-
-  OrthancStone::CoordinateSystem3D ParallelSlicesCursor::GetSlice(size_t slice)
-  {
-    if (slices_.get() == NULL)
-    {
-      return OrthancStone::CoordinateSystem3D();
-    }
-    else
-    {
-      return slices_->GetSlice(slice);
-    }
-  }
-
-
-  void ParallelSlicesCursor::SetGeometry(const ParallelSlices& slices)
-  {
-    slices_.reset(new ParallelSlices(slices));
-
-    currentSlice_ = GetDefaultSlice();
-  }
-
-
-  OrthancStone::CoordinateSystem3D ParallelSlicesCursor::GetCurrentSlice()
-  {
-    if (slices_.get() != NULL &&
-        currentSlice_ < slices_->GetSliceCount())
-    {
-      return slices_->GetSlice(currentSlice_);
-    }
-    else
-    {
-      return OrthancStone::CoordinateSystem3D();  // No slice is available, return the canonical geometry
-    }
-  }
-
-
-  bool ParallelSlicesCursor::SetDefaultSlice()
-  {
-    size_t slice = GetDefaultSlice();
-
-    if (currentSlice_ != slice)
-    {
-      currentSlice_ = slice;
-      return true;
-    }
-    else
-    {
-      return false;
-    }
-  }
-
-
-  bool ParallelSlicesCursor::ApplyOffset(OrthancStone::SliceOffsetMode mode,
-                                         int offset)
-  {
-    if (slices_.get() == NULL)
-    {
-      return false;
-    }
-
-    int count = static_cast<int>(slices_->GetSliceCount());
-    if (count == 0)
-    {
-      return false;
-    }
-
-    int slice;
-    if (static_cast<int>(currentSlice_) >= count)
-    {
-      slice = count - 1;
-    }
-    else
-    {
-      slice = static_cast<int>(currentSlice_);
-    }
-
-    switch (mode)
-    {
-      case OrthancStone::SliceOffsetMode_Absolute:
-      {
-        slice = offset;
-        break;
-      }
-
-      case OrthancStone::SliceOffsetMode_Relative:
-      {
-        slice += offset;
-        break;
-      }
-
-      case OrthancStone::SliceOffsetMode_Loop:
-      {
-        slice += offset;
-        while (slice < 0)
-        {
-          slice += count;
-        }
-
-        while (slice >= count)
-        {
-          slice -= count;
-        }
-
-        break;
-      }
-
-      default:
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    if (slice < 0)
-    {
-      slice = 0;
-    }
-
-    if (slice >= count)
-    {
-      slice = count - 1;
-    }
-
-    if (slice != static_cast<int>(currentSlice_))
-    {
-      currentSlice_ = static_cast<int>(slice);
-      return true;
-    }
-    else
-    {
-      return false;
-    }
-  }
-
-
-  bool ParallelSlicesCursor::ApplyWheelEvent(OrthancStone::MouseWheelDirection direction,
-                                             OrthancStone::KeyboardModifiers modifiers)
-  {
-    int offset = (modifiers & OrthancStone::KeyboardModifiers_Control ? 10 : 1);
-
-    switch (direction)
-    {
-      case OrthancStone::MouseWheelDirection_Down:
-        return ApplyOffset(OrthancStone::SliceOffsetMode_Relative, -offset);
-
-      case OrthancStone::MouseWheelDirection_Up:
-        return ApplyOffset(OrthancStone::SliceOffsetMode_Relative, offset);
-
-      default:
-        return false;
-    }
-  }
-
-
-  bool ParallelSlicesCursor::LookupSliceContainingPoint(const OrthancStone::Vector& p)
-  {
-    size_t slice;
-    double distance;
-
-    if (slices_.get() != NULL &&
-        slices_->ComputeClosestSlice(slice, distance, p))
-    {
-      if (currentSlice_ != slice)
-      {
-        currentSlice_ = slice;
-        return true;
-      }
-    }
-
-    return false;
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/ParallelSlicesCursor.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "ParallelSlices.h"
-#include "../../StoneEnumerations.h"
-
-#include <Compatibility.h>
-
-namespace Deprecated
-{
-  class ParallelSlicesCursor : public boost::noncopyable
-  {
-  private:
-    std::unique_ptr<ParallelSlices>  slices_;
-    size_t                         currentSlice_;
-
-    size_t GetDefaultSlice();
-
-  public:
-    ParallelSlicesCursor() :
-      currentSlice_(0)
-    {
-    }
-
-    void SetGeometry(const ParallelSlices& slices);
-
-    size_t GetSliceCount();
-
-    OrthancStone::CoordinateSystem3D GetSlice(size_t slice);
-
-    OrthancStone::CoordinateSystem3D GetCurrentSlice();
-
-    // Returns "true" iff. the slice has actually changed
-    bool SetDefaultSlice();
-
-    // Returns "true" iff. the slice has actually changed
-    bool ApplyOffset(OrthancStone::SliceOffsetMode mode,
-                     int offset);
-
-    // Returns "true" iff. the slice has actually changed
-    bool ApplyWheelEvent(OrthancStone::MouseWheelDirection direction,
-                         OrthancStone::KeyboardModifiers modifiers);
-
-    // Returns "true" iff. the slice has actually changed
-    bool LookupSliceContainingPoint(const OrthancStone::Vector& p);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/Slice.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,367 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "Slice.h"
-
-#include "../../StoneEnumerations.h"
-#include "../../Toolbox/GeometryToolbox.h"
-
-#include <Logging.h>
-#include <OrthancException.h>
-#include <Toolbox.h>
-
-#include <boost/lexical_cast.hpp>
-
-namespace Deprecated
-{
-  static bool ParseDouble(double& target,
-                          const std::string& source)
-  {
-    try
-    {
-      target = boost::lexical_cast<double>(source);
-      return true;
-    }
-    catch (boost::bad_lexical_cast&)
-    {
-      return false;
-    }
-  }
-
-  Slice* Slice::Clone() const
-  {
-    std::unique_ptr<Slice> target(new Slice());
-
-    target->type_ = type_;
-    target->orthancInstanceId_ = orthancInstanceId_;
-    target->sopClassUid_ = sopClassUid_;
-    target->frame_ = frame_;
-    target->frameCount_ = frameCount_;
-    target->geometry_ = geometry_;
-    target->pixelSpacingX_ = pixelSpacingX_;
-    target->pixelSpacingY_ = pixelSpacingY_;
-    target->thickness_ = thickness_;
-    target->width_ = width_;
-    target->height_ = height_;
-    target->converter_ = converter_;
-    if (imageInformation_.get() != NULL)
-      target->imageInformation_.reset(imageInformation_->Clone());
-
-    return target.release();
-  }
-  
-  bool Slice::ComputeRTDoseGeometry(const Orthanc::DicomMap& dataset,
-                                    unsigned int frame)
-  {
-    // http://dicom.nema.org/medical/Dicom/2016a/output/chtml/part03/sect_C.8.8.3.2.html
-
-    {
-      std::string increment;
-
-      if (dataset.LookupStringValue(increment, Orthanc::DICOM_TAG_FRAME_INCREMENT_POINTER, false))
-      {
-        Orthanc::Toolbox::ToUpperCase(increment);
-        if (increment != "3004,000C")  // This is the "Grid Frame Offset Vector" tag
-        {
-          LOG(ERROR) << "Bad value for the \"FrameIncrementPointer\" tag";
-          return false;
-        }
-      }
-    }
-
-    std::string offsetTag;
-
-    if (!dataset.LookupStringValue(offsetTag, Orthanc::DICOM_TAG_GRID_FRAME_OFFSET_VECTOR, false) ||
-        offsetTag.empty())
-    {
-      LOG(ERROR) << "Cannot read the \"GridFrameOffsetVector\" tag, check you are using Orthanc >= 1.3.1";
-      return false;
-    }
-
-    std::vector<std::string> offsets;
-    Orthanc::Toolbox::TokenizeString(offsets, offsetTag, '\\');
-
-    if (frameCount_ <= 1 ||
-        offsets.size() < frameCount_ ||
-        offsets.size() < 2 ||
-        frame >= frameCount_)
-    {
-      LOG(ERROR) << "No information about the 3D location of some slice(s) in a RT DOSE";
-      return false;
-    }
-
-    double offset0, offset1, z;
-
-    if (!ParseDouble(offset0, offsets[0]) ||
-        !ParseDouble(offset1, offsets[1]) ||
-        !ParseDouble(z, offsets[frame]))
-    {
-      LOG(ERROR) << "Invalid syntax";
-      return false;
-    }
-
-    if (!OrthancStone::LinearAlgebra::IsCloseToZero(offset0))
-    {
-      LOG(ERROR) << "Invalid syntax";
-      return false;
-    }
-
-    geometry_ = OrthancStone::CoordinateSystem3D(geometry_.GetOrigin() + z * geometry_.GetNormal(),
-                                                 //+ 650 * geometry_.GetAxisX(),
-                                                 geometry_.GetAxisX(),
-                                                 geometry_.GetAxisY());
-
-    thickness_ = offset1 - offset0;
-    if (thickness_ < 0)
-    {
-      thickness_ = -thickness_;
-    }
-
-    return true;
-  }
-
-  
-  bool Slice::ParseOrthancFrame(const Orthanc::DicomMap& dataset,
-                                const std::string& instanceId,
-                                unsigned int frame)
-  {
-    orthancInstanceId_ = instanceId;
-    frame_ = frame;
-    type_ = Type_OrthancDecodableFrame;
-    imageInformation_.reset(new Orthanc::DicomImageInformation(dataset));
-
-    if (!dataset.LookupStringValue(sopClassUid_, Orthanc::DICOM_TAG_SOP_CLASS_UID, false) ||
-        sopClassUid_.empty())
-    {
-      LOG(ERROR) << "Instance without a SOP class UID";
-      return false; 
-    }
-
-    if (!dataset.ParseUnsignedInteger32(frameCount_, Orthanc::DICOM_TAG_NUMBER_OF_FRAMES))
-    {
-      frameCount_ = 1;   // Assume instance with one frame
-    }
-
-    if (frame >= frameCount_)
-    {
-      return false;
-    }
-
-    if (!dataset.ParseUnsignedInteger32(width_, Orthanc::DICOM_TAG_COLUMNS) ||
-        !dataset.ParseUnsignedInteger32(height_, Orthanc::DICOM_TAG_ROWS))
-    {
-      return false;
-    }
-
-    thickness_ = 100.0 * std::numeric_limits<double>::epsilon();
-
-    std::string tmp;
-    if (dataset.LookupStringValue(tmp, Orthanc::DICOM_TAG_SLICE_THICKNESS, false))
-    {
-      if (!tmp.empty() &&
-          !ParseDouble(thickness_, tmp))
-      {
-        return false;  // Syntax error
-      }
-    }
-    
-    converter_.ReadParameters(dataset);
-
-    OrthancStone::GeometryToolbox::GetPixelSpacing(pixelSpacingX_, pixelSpacingY_, dataset);
-
-    std::string position, orientation;
-    if (dataset.LookupStringValue(position, Orthanc::DICOM_TAG_IMAGE_POSITION_PATIENT, false) &&
-        dataset.LookupStringValue(orientation, Orthanc::DICOM_TAG_IMAGE_ORIENTATION_PATIENT, false))
-    {
-      geometry_ = OrthancStone::CoordinateSystem3D(position, orientation);
-
-      bool ok = true;
-
-      switch (OrthancStone::StringToSopClassUid(sopClassUid_))
-      {
-        case OrthancStone::SopClassUid_RTDose:
-          type_ = Type_OrthancRawFrame;
-          ok = ComputeRTDoseGeometry(dataset, frame);
-          break;
-            
-        default:
-          break;
-      }
-
-      if (!ok)
-      {
-        LOG(ERROR) << "Cannot deduce the 3D location of frame " << frame
-                   << " in instance " << instanceId << ", whose SOP class UID is: " << sopClassUid_;
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-  
-  const std::string Slice::GetOrthancInstanceId() const
-  {
-    if (type_ == Type_OrthancDecodableFrame ||
-        type_ == Type_OrthancRawFrame)
-    {
-      return orthancInstanceId_;
-    }
-    else
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }   
-  }
-
-  
-  unsigned int Slice::GetFrame() const
-  {
-    if (type_ == Type_Invalid)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-        
-    return frame_;
-  }
-
-  
-  const OrthancStone::CoordinateSystem3D& Slice::GetGeometry() const
-  {
-    if (type_ == Type_Invalid)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-        
-    return geometry_;
-  }
-
-  
-  double Slice::GetThickness() const
-  {
-    if (type_ == Type_Invalid)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-        
-    return thickness_;
-  }
-
-  
-  double Slice::GetPixelSpacingX() const
-  {
-    if (type_ == Type_Invalid)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-        
-    return pixelSpacingX_;
-  }
-
-  
-  double Slice::GetPixelSpacingY() const
-  {
-    if (type_ == Type_Invalid)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-        
-    return pixelSpacingY_;
-  }
-
-  
-  unsigned int Slice::GetWidth() const
-  {
-    if (type_ == Type_Invalid)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-        
-    return width_;
-  }
-
-  
-  unsigned int Slice::GetHeight() const
-  {
-    if (type_ == Type_Invalid)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-        
-    return height_;
-  }
-
-
-  const DicomFrameConverter& Slice::GetConverter() const
-  {
-    if (type_ == Type_Invalid)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-        
-    return converter_;
-  }
-
-
-  bool Slice::ContainsPlane(const OrthancStone::CoordinateSystem3D& plane) const
-  {
-    if (type_ == Type_Invalid)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-
-    bool opposite;
-    return (OrthancStone::GeometryToolbox::IsParallelOrOpposite(opposite,
-                                                                GetGeometry().GetNormal(),
-                                                                plane.GetNormal()) &&
-            OrthancStone::LinearAlgebra::IsNear(GetGeometry().ProjectAlongNormal(GetGeometry().GetOrigin()),
-                                                GetGeometry().ProjectAlongNormal(plane.GetOrigin()),
-                                                thickness_ / 2.0));
-  }
-
-  
-  void Slice::GetExtent(std::vector<OrthancStone::Vector>& points) const
-  {
-    double sx = GetPixelSpacingX();
-    double sy = GetPixelSpacingY();
-    double w = static_cast<double>(GetWidth());
-    double h = static_cast<double>(GetHeight());
-
-    points.clear();
-    points.push_back(GetGeometry().MapSliceToWorldCoordinates(-0.5      * sx, -0.5      * sy));
-    points.push_back(GetGeometry().MapSliceToWorldCoordinates((w - 0.5) * sx, -0.5      * sy));
-    points.push_back(GetGeometry().MapSliceToWorldCoordinates(-0.5      * sx, (h - 0.5) * sy));
-    points.push_back(GetGeometry().MapSliceToWorldCoordinates((w - 0.5) * sx, (h - 0.5) * sy));
-  }
-
-
-  const Orthanc::DicomImageInformation& Slice::GetImageInformation() const
-  {
-    if (imageInformation_.get() == NULL)
-    {
-      // Only available if constructing the "Slice" object with a DICOM map
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-    else
-    {
-      return *imageInformation_;
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/Slice.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Toolbox/CoordinateSystem3D.h"
-#include "DicomFrameConverter.h"
-
-#include <DicomFormat/DicomImageInformation.h>
-#include <IDynamicObject.h>
-
-namespace Deprecated
-{
-  // TODO - Remove this class
-  class Slice :
-    public Orthanc::IDynamicObject  /* to be used as a payload of SlicesSorter */
-  {
-  private:
-    enum Type
-    {
-      Type_Invalid,
-      Type_Standalone,
-      Type_OrthancDecodableFrame,
-      Type_OrthancRawFrame
-      // TODO A slice could come from some DICOM file (URL)
-    };
-
-    bool ComputeRTDoseGeometry(const Orthanc::DicomMap& dataset,
-                               unsigned int frame);
-
-    Type                 type_;
-    std::string          orthancInstanceId_;
-    std::string          sopClassUid_;
-    unsigned int         frame_;
-    unsigned int         frameCount_;   // TODO : Redundant with "imageInformation_"
-    OrthancStone::CoordinateSystem3D   geometry_;
-    double               pixelSpacingX_;
-    double               pixelSpacingY_;
-    double               thickness_;
-    unsigned int         width_;   // TODO : Redundant with "imageInformation_"
-    unsigned int         height_;   // TODO : Redundant with "imageInformation_"
-    DicomFrameConverter  converter_;   // TODO : Partially redundant with "imageInformation_"
-
-    std::unique_ptr<Orthanc::DicomImageInformation>  imageInformation_;
-
-  public:
-    Slice() :
-      type_(Type_Invalid)
-    {
-    }
-
-
-    // this constructor is used to reference, i.e, a slice that is being loaded
-    Slice(const std::string& orthancInstanceId,
-          unsigned int frame) :
-      type_(Type_Invalid),
-      orthancInstanceId_(orthancInstanceId),
-      frame_(frame)
-    {        
-    }
-
-    // TODO Is this constructor the best way to go to tackle missing
-    // layers within SliceViewerWidget?
-    Slice(const OrthancStone::CoordinateSystem3D& plane,
-          double thickness) :
-      type_(Type_Standalone),
-      frame_(0),
-      frameCount_(0),
-      geometry_(plane),
-      pixelSpacingX_(1),
-      pixelSpacingY_(1),
-      thickness_(thickness),
-      width_(0),
-      height_(0)
-    {      
-    }
-
-    Slice(const OrthancStone::CoordinateSystem3D& plane,
-          double pixelSpacingX,
-          double pixelSpacingY,
-          double thickness,
-          unsigned int width,
-          unsigned int height,
-          const DicomFrameConverter& converter) :
-      type_(Type_Standalone),
-      frameCount_(1),
-      geometry_(plane),
-      pixelSpacingX_(pixelSpacingX),
-      pixelSpacingY_(pixelSpacingY),
-      thickness_(thickness),
-      width_(width),
-      height_(height),
-      converter_(converter)
-    {
-    }
-
-    bool IsValid() const
-    {
-      return type_ != Type_Invalid;
-    } 
-
-    bool ParseOrthancFrame(const Orthanc::DicomMap& dataset,
-                           const std::string& instanceId,
-                           unsigned int frame);
-
-    bool HasOrthancDecoding() const
-    {
-      return type_ == Type_OrthancDecodableFrame;
-    }
-
-    const std::string GetOrthancInstanceId() const;
-
-    unsigned int GetFrame() const;
-
-    const OrthancStone::CoordinateSystem3D& GetGeometry() const;
-
-    double GetThickness() const;
-
-    double GetPixelSpacingX() const;
-
-    double GetPixelSpacingY() const;
-
-    unsigned int GetWidth() const;
-
-    unsigned int GetHeight() const;
-
-    const DicomFrameConverter& GetConverter() const;
-
-    bool ContainsPlane(const OrthancStone::CoordinateSystem3D& plane) const;
-
-    void GetExtent(std::vector<OrthancStone::Vector>& points) const;
-
-    const Orthanc::DicomImageInformation& GetImageInformation() const;
-
-    Slice* Clone() const;
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/ViewportGeometry.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,217 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "ViewportGeometry.h"
-
-#include <Logging.h>
-#include <OrthancException.h>
-
-#include <boost/math/special_functions/round.hpp>
-
-namespace Deprecated
-{
-  void ViewportGeometry::ComputeTransform()
-  {
-    // The following lines must be read in reverse order!
-    cairo_matrix_t tmp;
-    
-    // Bring the center of the scene to the center of the view
-    cairo_matrix_init_translate(&transform_, 
-                                panX_ + static_cast<double>(width_) / 2.0, 
-                                panY_ + static_cast<double>(height_) / 2.0);
-
-    // Apply the zoom around (0,0)
-    cairo_matrix_init_scale(&tmp, zoom_, zoom_);
-    cairo_matrix_multiply(&transform_, &tmp, &transform_);
-
-    // Bring the center of the scene to (0,0)
-    cairo_matrix_init_translate(&tmp,
-                                -(sceneExtent_.GetX1() + sceneExtent_.GetX2()) / 2.0,
-                                -(sceneExtent_.GetY1() + sceneExtent_.GetY2()) / 2.0);
-    cairo_matrix_multiply(&transform_, &tmp, &transform_);
-  }
-
-
-  ViewportGeometry::ViewportGeometry()
-  {
-    width_ = 0;
-    height_ = 0;
-
-    zoom_ = 1;
-    panX_ = 0;
-    panY_ = 0;
-
-    ComputeTransform();
-  }
-
-
-  void ViewportGeometry::SetDisplaySize(unsigned int width,
-                                        unsigned int height)
-  {
-    if (width_ != width ||
-        height_ != height)
-    {
-      LOG(INFO) << "New display size: " << width << "x" << height;
-
-      width_ = width;
-      height_ = height;
-
-      ComputeTransform();
-    }
-  }
-
-
-  void ViewportGeometry::SetSceneExtent(const OrthancStone::Extent2D& extent)
-  {
-//    LOG(INFO) << "New scene extent: ("
-//              << extent.GetX1() << "," << extent.GetY1() << ") => ("
-//              << extent.GetX2() << "," << extent.GetY2() << ")";
-
-    sceneExtent_ = extent;
-    ComputeTransform();
-  }
-
-
-  void ViewportGeometry::MapDisplayToScene(double& sceneX /* out */,
-                                           double& sceneY /* out */,
-                                           double x,
-                                           double y) const
-  {
-    cairo_matrix_t transform = transform_;
-
-    if (cairo_matrix_invert(&transform) != CAIRO_STATUS_SUCCESS)
-    {
-      LOG(ERROR) << "Cannot invert singular matrix";
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-    }
-
-    sceneX = x;
-    sceneY = y;
-    cairo_matrix_transform_point(&transform, &sceneX, &sceneY);
-  }
-
-
-  void ViewportGeometry::MapSceneToDisplay(int& displayX /* out */,
-                                           int& displayY /* out */,
-                                           double x,
-                                           double y) const
-  {
-    cairo_matrix_transform_point(&transform_, &x, &y);
-
-    displayX = static_cast<int>(boost::math::iround(x));
-    displayY = static_cast<int>(boost::math::iround(y));
-  }
-
-
-  void ViewportGeometry::MapPixelCenterToScene(std::vector<Touch>& sceneTouches /* out */,
-                                               const std::vector<Touch>& displayTouches) const
-  {
-    double sceneX, sceneY;
-    sceneTouches.clear();
-    for (size_t t = 0; t < displayTouches.size(); t++)
-    {
-      MapPixelCenterToScene(
-        sceneX,
-        sceneY, 
-        static_cast<int>(displayTouches[t].x), 
-        static_cast<int>(displayTouches[t].y));
-      
-      sceneTouches.push_back(Touch((float)sceneX, (float)sceneY));
-    }
-  }
-
-  void ViewportGeometry::MapPixelCenterToScene(double& sceneX,
-                                               double& sceneY,
-                                               int x,
-                                               int y) const
-  {
-    // Take the center of the pixel
-    MapDisplayToScene(sceneX, sceneY,
-                      static_cast<double>(x) + 0.5,
-                      static_cast<double>(y) + 0.5);
-  }
-
-
-  void ViewportGeometry::FitContent()
-  {
-    if (width_ > 0 &&
-        height_ > 0 &&
-        !sceneExtent_.IsEmpty())
-    {
-      double zoomX = static_cast<double>(width_) / (sceneExtent_.GetX2() - sceneExtent_.GetX1());
-      double zoomY = static_cast<double>(height_) / (sceneExtent_.GetY2() - sceneExtent_.GetY1());
-      zoom_ = zoomX < zoomY ? zoomX : zoomY;
-
-      panX_ = 0;
-      panY_ = 0;
-
-      ComputeTransform();
-    }
-  }
-
-
-  void ViewportGeometry::ApplyTransform(OrthancStone::CairoContext& context) const
-  {
-    cairo_set_matrix(context.GetObject(), &transform_);
-  }
-
-
-  void ViewportGeometry::GetPan(double& x,
-                                double& y) const
-  {
-    x = panX_;
-    y = panY_;
-  }
-
-
-  void ViewportGeometry::SetPan(double x,
-                                double y)
-  {
-    panX_ = x;
-    panY_ = y;
-    ComputeTransform();
-  }
-
-
-  void ViewportGeometry::SetZoom(double zoom)
-  {
-    zoom_ = zoom;
-    ComputeTransform();
-  }
-
-
-  OrthancStone::Matrix ViewportGeometry::GetMatrix() const
-  {
-    OrthancStone::Matrix m(3, 3);
-
-    m(0, 0) = transform_.xx;
-    m(0, 1) = transform_.xy;
-    m(0, 2) = transform_.x0;
-    m(1, 0) = transform_.yx;
-    m(1, 1) = transform_.yy;
-    m(1, 2) = transform_.y0;
-    m(2, 0) = 0;
-    m(2, 1) = 0;
-    m(2, 2) = 1;
-    
-    return m;
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Toolbox/ViewportGeometry.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Wrappers/CairoContext.h"
-#include "../../Toolbox/Extent2D.h"
-#include "../../Toolbox/LinearAlgebra.h"
-#include "../Viewport/IMouseTracker.h"  // to include "Touch" definition
-
-namespace Deprecated
-{
-  class ViewportGeometry
-  {
-  private:
-    // Extent of the scene (in world units)
-    OrthancStone::Extent2D   sceneExtent_;
-
-    // Size of the display (in pixels)
-    unsigned int  width_;
-    unsigned int  height_;
-
-    // Zoom/pan
-    double   zoom_;
-    double   panX_;  // In pixels (display units)
-    double   panY_;
-
-    cairo_matrix_t  transform_;  // Scene-to-display transformation
-
-    void ComputeTransform();
-
-  public:
-    ViewportGeometry();
-
-    void SetDisplaySize(unsigned int width,
-                        unsigned int height);
-
-    void SetSceneExtent(const OrthancStone::Extent2D& extent);
-
-    const OrthancStone::Extent2D& GetSceneExtent() const
-    {
-      return sceneExtent_;
-    }
-
-    void MapDisplayToScene(double& sceneX /* out */,
-                           double& sceneY /* out */,
-                           double x,
-                           double y) const;
-
-    void MapPixelCenterToScene(double& sceneX /* out */,
-                               double& sceneY /* out */,
-                               int x,
-                               int y) const;
-
-    void MapPixelCenterToScene(std::vector<Touch>& sceneTouches /* out */,
-                               const std::vector<Touch>& displayTouches) const;
-
-    void MapSceneToDisplay(int& displayX /* out */,
-                           int& displayY /* out */,
-                           double x,
-                           double y) const;
-
-    unsigned int GetDisplayWidth() const
-    {
-      return width_;
-    }
-
-    unsigned int GetDisplayHeight() const
-    {
-      return height_;
-    }
-
-    double GetZoom() const
-    {
-      return zoom_;
-    }
-
-    void FitContent();
-
-    void ApplyTransform(OrthancStone::CairoContext& context) const;
-
-    void GetPan(double& x,
-                double& y) const;
-
-    void SetPan(double x,
-                double y);
-
-    void SetZoom(double zoom);
-
-    OrthancStone::Matrix GetMatrix() const;
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Viewport/CairoFont.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "CairoFont.h"
-
-#include <Logging.h>
-#include <OrthancException.h>
-
-namespace Deprecated
-{
-  CairoFont::CairoFont(const char* family,
-                       cairo_font_slant_t slant,
-                       cairo_font_weight_t weight)
-  {
-    font_ = cairo_toy_font_face_create(family, slant, weight);
-    if (font_ == NULL)
-    {
-      LOG(ERROR) << "Unknown font: " << family;
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource);
-    }
-  }
-
-
-  CairoFont::~CairoFont()
-  {
-    if (font_ != NULL)
-    {
-      cairo_font_face_destroy(font_);
-    }
-  }
-
-
-  void CairoFont::Draw(OrthancStone::CairoContext& context,
-                       const std::string& text,
-                       double size)
-  {
-    if (size <= 0)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    cairo_t* cr = context.GetObject();
-    cairo_set_font_face(cr, font_);
-    cairo_set_font_size(cr, size);
-    cairo_show_text(cr, text.c_str());    
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Viewport/CairoFont.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#if !defined(ORTHANC_SANDBOXED)
-#  error The macro ORTHANC_SANDBOXED must be defined
-#endif
-
-#if ORTHANC_SANDBOXED == 1
-#  error The class CairoFont cannot be used in sandboxed environments
-#endif
-
-#include "../../Wrappers/CairoContext.h"
-
-namespace Deprecated
-{
-  class CairoFont : public boost::noncopyable
-  {
-  private:
-    cairo_font_face_t*  font_;
-
-  public:
-    CairoFont(const char* family,
-              cairo_font_slant_t slant,
-              cairo_font_weight_t weight);
-
-    ~CairoFont();
-
-    void Draw(OrthancStone::CairoContext& context,
-              const std::string& text,
-              double size);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Viewport/IMouseTracker.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Wrappers/CairoSurface.h"
-#include <vector>
-
-namespace Deprecated
-{
-  struct Touch
-  {
-    float x;
-    float y;
-
-    Touch(float x, float y)
-    : x(x),
-      y(y)
-    {
-    }
-    Touch()
-      : x(0.0f),
-        y(0.0f)
-    {
-    }
-  };
-
-
-  // this is tracking a mouse in screen coordinates/pixels unlike
-  // the IWorldSceneMouseTracker that is tracking a mouse
-  // in scene coordinates/mm.
-  class IMouseTracker : public boost::noncopyable
-  {
-  public:
-    virtual ~IMouseTracker()
-    {
-    }
-    
-    virtual void Render(Orthanc::ImageAccessor& surface) = 0;
-
-    virtual void MouseUp() = 0;
-
-    // Returns "true" iff. the background scene must be repainted
-    virtual void MouseMove(int x, 
-                           int y,
-                           const std::vector<Touch>& displayTouches) = 0;
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Viewport/IStatusBar.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include <string>
-#include <boost/noncopyable.hpp>
-
-namespace Deprecated
-{
-  class IStatusBar : public boost::noncopyable
-  {
-  public:
-    virtual ~IStatusBar()
-    {
-    }
-    
-    virtual void ClearMessage() = 0;
-
-    virtual void SetMessage(const std::string& message) = 0;
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Viewport/IViewport.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "IStatusBar.h"
-#include "../../StoneEnumerations.h"
-#include "../../Messages/IObservable.h"
-#include "../Viewport/IMouseTracker.h" // only to get the "Touch" definition
-
-#include <Images/ImageAccessor.h>
-
-
-namespace Deprecated
-{
-  class IWidget;   // Forward declaration
-  
-  class IViewport : public OrthancStone::IObservable
-  {
-  public:
-    ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, ViewportChangedMessage, IViewport);
-
-    virtual void FitContent() = 0;
-
-    virtual void SetStatusBar(IStatusBar& statusBar) = 0;
-
-    virtual void SetSize(unsigned int width,
-                         unsigned int height) = 0;
-
-    // The function returns "true" iff. a new frame was rendered
-    virtual bool Render(Orthanc::ImageAccessor& surface) = 0;
-
-    virtual void MouseDown(OrthancStone::MouseButton button,
-                           int x,
-                           int y,
-                           OrthancStone::KeyboardModifiers modifiers,
-                           const std::vector<Touch>& touches) = 0;
-
-    virtual void MouseUp() = 0;
-
-    virtual void MouseMove(int x, 
-                           int y,
-                           const std::vector<Touch>& displayTouches) = 0;
-
-    virtual void MouseEnter() = 0;
-
-    virtual void MouseLeave() = 0;
-
-    virtual void MouseWheel(OrthancStone::MouseWheelDirection direction,
-                            int x,
-                            int y,
-                            OrthancStone::KeyboardModifiers modifiers) = 0;
-
-    virtual void KeyPressed(OrthancStone::KeyboardKeys key,
-                            char keyChar,
-                            OrthancStone::KeyboardModifiers modifiers) = 0;
-
-    virtual bool HasAnimation() = 0;
-
-    virtual void DoAnimation() = 0;
-
-    // Should only be called from IWidget
-    // TODO Why should this be virtual?
-    virtual void NotifyContentChanged()
-    {
-      BroadcastMessage(ViewportChangedMessage(*this));
-    }
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Viewport/WidgetViewport.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,286 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "WidgetViewport.h"
-
-#include <Images/ImageProcessing.h>
-#include <OrthancException.h>
-
-namespace Deprecated
-{
-  WidgetViewport::WidgetViewport() :
-    statusBar_(NULL),
-    isMouseOver_(false),
-    lastMouseX_(0),
-    lastMouseY_(0),
-    backgroundChanged_(false)
-  {
-  }
-
-
-  void WidgetViewport::FitContent()
-  {
-    if (centralWidget_.get() != NULL)
-    {
-      centralWidget_->FitContent();
-    }
-  }
-
-
-  void WidgetViewport::SetStatusBar(IStatusBar& statusBar)
-  {
-    statusBar_ = &statusBar;
-
-    if (centralWidget_.get() != NULL)
-    {
-      centralWidget_->SetStatusBar(statusBar);
-    }
-  }
-
-
-  void WidgetViewport::SetCentralWidget(boost::shared_ptr<IWidget> widget)
-  {
-    if (widget == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    mouseTracker_.reset(NULL);
-
-    centralWidget_ = widget;
-    centralWidget_->SetViewport(*this);
-
-    if (statusBar_ != NULL)
-    {
-      centralWidget_->SetStatusBar(*statusBar_);
-    }
-
-    NotifyBackgroundChanged();
-  }
-
-
-  void WidgetViewport::NotifyBackgroundChanged()
-  {
-    backgroundChanged_ = true;
-    NotifyContentChanged();
-  }
-
-
-  void WidgetViewport::SetSize(unsigned int width,
-                               unsigned int height)
-  {
-    background_.SetSize(width, height, false /* no alpha */);
-
-    if (centralWidget_.get() != NULL)
-    {
-      centralWidget_->SetSize(width, height);
-    }
-
-    NotifyBackgroundChanged();
-  }
-
-
-  bool WidgetViewport::Render(Orthanc::ImageAccessor& surface)
-  {
-    if (centralWidget_.get() == NULL)
-    {
-      return false;
-    }
-
-    Orthanc::ImageAccessor background;
-    background_.GetWriteableAccessor(background);
-
-    if (backgroundChanged_ &&
-        !centralWidget_->Render(background))
-    {
-      return false;
-    }
-    
-    if (background.GetWidth() != surface.GetWidth() ||
-        background.GetHeight() != surface.GetHeight())
-    {
-      return false;
-    }
-
-    Orthanc::ImageProcessing::Convert(surface, background);
-    
-    if (mouseTracker_.get() != NULL)
-    {
-      mouseTracker_->Render(surface);
-    }
-    else if (isMouseOver_)
-    {
-      centralWidget_->RenderMouseOver(surface, lastMouseX_, lastMouseY_);
-    }
-
-    return true;
-  }
-
-  void WidgetViewport::TouchStart(const std::vector<Touch>& displayTouches)
-  {
-    MouseDown(OrthancStone::MouseButton_Left, (int)displayTouches[0].x, (int)displayTouches[0].y, OrthancStone::KeyboardModifiers_None, displayTouches); // one touch is equivalent to a mouse tracker without left button -> set the mouse coordinates to the first touch coordinates
-  }
-      
-  void WidgetViewport::TouchMove(const std::vector<Touch>& displayTouches)
-  {
-    MouseMove((int)displayTouches[0].x, (int)displayTouches[0].y, displayTouches); // one touch is equivalent to a mouse tracker without left button -> set the mouse coordinates to the first touch coordinates
-  }
-      
-  void WidgetViewport::TouchEnd(const std::vector<Touch>& displayTouches)
-  {
-    // note: TouchEnd is not triggered when a single touch gesture ends (it is only triggered when
-    // going from 2 touches to 1 touch, ...)
-    MouseUp();
-  }
-
-  void WidgetViewport::MouseDown(OrthancStone::MouseButton button,
-                                 int x,
-                                 int y,
-                                 OrthancStone::KeyboardModifiers modifiers,
-                                 const std::vector<Touch>& displayTouches
-                                 )
-  {
-    lastMouseX_ = x;
-    lastMouseY_ = y;
-
-    if (centralWidget_.get() != NULL)
-    {
-      mouseTracker_.reset(centralWidget_->CreateMouseTracker(button, x, y, modifiers, displayTouches));
-    }
-    else
-    {
-      mouseTracker_.reset(NULL);
-    }      
-
-    NotifyContentChanged();
-  }
-
-
-  void WidgetViewport::MouseUp()
-  {
-    if (mouseTracker_.get() != NULL)
-    {
-      mouseTracker_->MouseUp();
-      mouseTracker_.reset(NULL);
-      NotifyContentChanged();
-    }
-  }
-
-
-  void WidgetViewport::MouseMove(int x, 
-                                 int y,
-                                 const std::vector<Touch>& displayTouches)
-  {
-    if (centralWidget_.get() == NULL)
-    {
-      return;
-    }
-
-    lastMouseX_ = x;
-    lastMouseY_ = y;
-
-    bool repaint = false;
-    
-    if (mouseTracker_.get() != NULL)
-    {
-      mouseTracker_->MouseMove(x, y, displayTouches);
-      repaint = true;
-    }
-    else
-    {
-      repaint = centralWidget_->HasRenderMouseOver();
-    }
-
-    if (repaint)
-    {
-      // The scene must be repainted, notify the observers
-      NotifyContentChanged();
-    }
-  }
-
-
-  void WidgetViewport::MouseEnter()
-  {
-    isMouseOver_ = true;
-    NotifyContentChanged();
-  }
-
-
-  void WidgetViewport::MouseLeave()
-  {
-    isMouseOver_ = false;
-
-    if (mouseTracker_.get() != NULL)
-    {
-      mouseTracker_->MouseUp();
-      mouseTracker_.reset(NULL);
-    }
-
-    NotifyContentChanged();
-  }
-
-
-  void WidgetViewport::MouseWheel(OrthancStone::MouseWheelDirection direction,
-                                  int x,
-                                  int y,
-                                  OrthancStone::KeyboardModifiers modifiers)
-  {
-    if (centralWidget_.get() != NULL &&
-        mouseTracker_.get() == NULL)
-    {
-      centralWidget_->MouseWheel(direction, x, y, modifiers);
-    }
-  }
-
-
-  void WidgetViewport::KeyPressed(OrthancStone::KeyboardKeys key,
-                                  char keyChar,
-                                  OrthancStone::KeyboardModifiers modifiers)
-  {
-    if (centralWidget_.get() != NULL &&
-        mouseTracker_.get() == NULL)
-    {
-      centralWidget_->KeyPressed(key, keyChar, modifiers);
-    }
-  }
-
-
-  bool WidgetViewport::HasAnimation()
-  {
-    if (centralWidget_.get() != NULL)
-    {
-      return centralWidget_->HasAnimation();
-    }
-    else
-    {
-      return false;
-    }
-  }
-   
-
-  void WidgetViewport::DoAnimation()
-  {
-    if (centralWidget_.get() != NULL)
-    {
-      centralWidget_->DoAnimation();
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Viewport/WidgetViewport.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "IViewport.h"
-#include "../Widgets/IWidget.h"
-
-#include <Compatibility.h>
-
-#include <memory>
-
-namespace Deprecated
-{
-  class WidgetViewport : public IViewport
-  {
-  private:
-    boost::shared_ptr<IWidget>    centralWidget_;
-    IStatusBar*                   statusBar_;
-    std::unique_ptr<IMouseTracker>  mouseTracker_;
-    bool                          isMouseOver_;
-    int                           lastMouseX_;
-    int                           lastMouseY_;
-    OrthancStone::CairoSurface    background_;
-    bool                          backgroundChanged_;
-
-  public:
-    WidgetViewport();
-
-    virtual void FitContent();
-
-    virtual void SetStatusBar(IStatusBar& statusBar);
-
-    void SetCentralWidget(boost::shared_ptr<IWidget> widget);
-
-    virtual void NotifyBackgroundChanged();
-
-    virtual void SetSize(unsigned int width,
-                         unsigned int height);
-
-    virtual bool Render(Orthanc::ImageAccessor& surface);
-
-    virtual void MouseDown(OrthancStone::MouseButton button,
-                           int x,
-                           int y,
-                           OrthancStone::KeyboardModifiers modifiers,
-                           const std::vector<Touch>& displayTouches);
-
-    virtual void MouseUp();
-
-    virtual void MouseMove(int x, 
-                           int y,
-                           const std::vector<Touch>& displayTouches);
-
-    virtual void MouseEnter();
-
-    virtual void MouseLeave();
-
-    virtual void TouchStart(const std::vector<Touch>& touches);
-    
-    virtual void TouchMove(const std::vector<Touch>& touches);
-    
-    virtual void TouchEnd(const std::vector<Touch>& touches);
-
-    virtual void MouseWheel(OrthancStone::MouseWheelDirection direction,
-                            int x,
-                            int y,
-                            OrthancStone::KeyboardModifiers modifiers);
-
-    virtual void KeyPressed(OrthancStone::KeyboardKeys key,
-                            char keyChar,
-                            OrthancStone::KeyboardModifiers modifiers);
-
-    virtual bool HasAnimation();
-
-    virtual void DoAnimation();
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Volumes/ISlicedVolume.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Messages/IObservable.h"
-#include "../Toolbox/Slice.h"
-
-namespace Deprecated
-{
-  class ISlicedVolume : public OrthancStone::IObservable
-  {
-  public:
-    ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, ContentChangedMessage, ISlicedVolume);
-    ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, GeometryErrorMessage, ISlicedVolume);
-    ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, GeometryReadyMessage, ISlicedVolume);
-    ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, VolumeReadyMessage, ISlicedVolume);
-
-
-    class SliceContentChangedMessage : public OrthancStone::OriginMessage<ISlicedVolume>
-    {
-      ORTHANC_STONE_MESSAGE(__FILE__, __LINE__);
-      
-    private:
-      size_t        sliceIndex_;
-      const Slice&  slice_;
-      
-    public:
-      SliceContentChangedMessage(ISlicedVolume& origin,
-                                 size_t sliceIndex,
-                                 const Slice& slice) :
-        OriginMessage(origin),
-        sliceIndex_(sliceIndex),
-        slice_(slice)
-      {
-      }
-
-      size_t GetSliceIndex() const
-      {
-        return sliceIndex_;
-      }
-
-      const Slice& GetSlice() const
-      {
-        return slice_;
-      }
-    };
-
-
-    virtual size_t GetSliceCount() const = 0;
-
-    virtual const Slice& GetSlice(size_t slice) const = 0;
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Volumes/IVolumeLoader.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Messages/IObservable.h"
-
-namespace Deprecated
-{
-  class IVolumeLoader : public OrthancStone::IObservable
-  {
-  public:
-    ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, GeometryReadyMessage, IVolumeLoader);
-    ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, GeometryErrorMessage, IVolumeLoader);
-    ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, ContentChangedMessage, IVolumeLoader);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Volumes/StructureSetLoader.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,156 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "StructureSetLoader.h"
-
-#include "../Toolbox/MessagingToolbox.h"
-
-#include <OrthancException.h>
-
-namespace Deprecated
-{
-  StructureSetLoader::StructureSetLoader(OrthancApiClient& orthanc) :
-    orthanc_(orthanc)
-  {
-  }
-  
-
-  void StructureSetLoader::OnReferencedSliceLoaded(const OrthancApiClient::JsonResponseReadyMessage& message)
-  {
-    OrthancPlugins::FullOrthancDataset dataset(message.GetJson());
-
-    Orthanc::DicomMap slice;
-    MessagingToolbox::ConvertDataset(slice, dataset);
-    structureSet_->AddReferencedSlice(slice);
-
-    BroadcastMessage(ContentChangedMessage(*this));
-  }
-  
-
-  void StructureSetLoader::OnStructureSetLoaded(const OrthancApiClient::JsonResponseReadyMessage& message)
-  {
-    OrthancPlugins::FullOrthancDataset dataset(message.GetJson());
-    structureSet_.reset(new OrthancStone::DicomStructureSet(dataset));
-
-    std::set<std::string> instances;
-    structureSet_->GetReferencedInstances(instances);
-
-    for (std::set<std::string>::const_iterator it = instances.begin();
-         it != instances.end(); ++it)
-    {
-      orthanc_.PostBinaryAsyncExpectJson("/tools/lookup", *it,
-                                         new DeprecatedCallable<StructureSetLoader, OrthancApiClient::JsonResponseReadyMessage>(GetSharedObserver(), &StructureSetLoader::OnLookupCompleted));
-    }
-
-    BroadcastMessage(GeometryReadyMessage(*this));
-  }
-
-  
-  void StructureSetLoader::OnLookupCompleted(const OrthancApiClient::JsonResponseReadyMessage& message)
-  {
-    const Json::Value& lookup = message.GetJson();
-
-    if (lookup.type() != Json::arrayValue ||
-        lookup.size() != 1 ||
-        !lookup[0].isMember("Type") ||
-        !lookup[0].isMember("Path") ||
-        lookup[0]["Type"].type() != Json::stringValue ||
-        lookup[0]["ID"].type() != Json::stringValue ||
-        lookup[0]["Type"].asString() != "Instance")
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol);
-    }
-
-    const std::string& instance = lookup[0]["ID"].asString();
-    orthanc_.GetJsonAsync("/instances/" + instance + "/tags",
-                          new DeprecatedCallable<StructureSetLoader, OrthancApiClient::JsonResponseReadyMessage>(GetSharedObserver(), &StructureSetLoader::OnReferencedSliceLoaded));
-  }
-
-  
-  void StructureSetLoader::ScheduleLoadInstance(const std::string& instance)
-  {
-    if (structureSet_.get() != NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-    else
-    {
-      orthanc_.GetJsonAsync("/instances/" + instance + "/tags?ignore-length=3006-0050",
-                            new DeprecatedCallable<StructureSetLoader, OrthancApiClient::JsonResponseReadyMessage>(GetSharedObserver(), &StructureSetLoader::OnStructureSetLoaded));
-    }
-  }
-
-
-  OrthancStone::DicomStructureSet& StructureSetLoader::GetStructureSet()
-  {
-    if (structureSet_.get() == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-    else
-    {
-      return *structureSet_;
-    }
-  }
-
-
-  OrthancStone::DicomStructureSet* StructureSetLoader::SynchronousLoad(
-    OrthancPlugins::IOrthancConnection& orthanc,
-    const std::string& instanceId)
-  {
-    const std::string uri = "/instances/" + instanceId + "/tags?ignore-length=3006-0050";
-    OrthancPlugins::FullOrthancDataset dataset(orthanc, uri);
-
-    std::unique_ptr<OrthancStone::DicomStructureSet> result
-      (new OrthancStone::DicomStructureSet(dataset));
-
-    std::set<std::string> instances;
-    result->GetReferencedInstances(instances);
-
-    for (std::set<std::string>::const_iterator it = instances.begin();
-         it != instances.end(); ++it)
-    {
-      Json::Value lookup;
-      MessagingToolbox::RestApiPost(lookup, orthanc, "/tools/lookup", *it);
-
-      if (lookup.type() != Json::arrayValue ||
-          lookup.size() != 1 ||
-          !lookup[0].isMember("Type") ||
-          !lookup[0].isMember("Path") ||
-          lookup[0]["Type"].type() != Json::stringValue ||
-          lookup[0]["ID"].type() != Json::stringValue ||
-          lookup[0]["Type"].asString() != "Instance")
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource);          
-      }
-
-      OrthancPlugins::FullOrthancDataset slice
-        (orthanc, "/instances/" + lookup[0]["ID"].asString() + "/tags");
-      Orthanc::DicomMap m;
-      MessagingToolbox::ConvertDataset(m, slice);
-      result->AddReferencedSlice(m);
-    }
-
-    result->CheckReferencedSlices();
-
-    return result.release();
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Volumes/StructureSetLoader.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Messages/ObserverBase.h"
-#include "../../Toolbox/DicomStructureSet.h"
-#include "../Toolbox/OrthancApiClient.h"
-#include "IVolumeLoader.h"
-
-#include <Compatibility.h>
-
-namespace Deprecated
-{
-  class StructureSetLoader :
-    public IVolumeLoader,
-    public OrthancStone::ObserverBase<StructureSetLoader>
-  {
-  private:
-    OrthancApiClient&                 orthanc_;
-    std::unique_ptr<OrthancStone::DicomStructureSet>  structureSet_;
-
-    void OnReferencedSliceLoaded(const OrthancApiClient::JsonResponseReadyMessage& message);
-
-    void OnStructureSetLoaded(const OrthancApiClient::JsonResponseReadyMessage& message);
-
-    void OnLookupCompleted(const OrthancApiClient::JsonResponseReadyMessage& message);
-
-  public:
-    StructureSetLoader(OrthancApiClient& orthanc);
-
-    void ScheduleLoadInstance(const std::string& instance);
-
-    bool HasStructureSet() const
-    {
-      return structureSet_.get() != NULL;
-    }
-
-    OrthancStone::DicomStructureSet& GetStructureSet();
-
-    static OrthancStone::DicomStructureSet* SynchronousLoad(
-      OrthancPlugins::IOrthancConnection& orthanc,
-      const std::string& instanceId);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/CairoWidget.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "CairoWidget.h"
-
-#include <Images/ImageProcessing.h>
-#include <OrthancException.h>
-
-namespace Deprecated
-{
-  static bool IsAligned(const Orthanc::ImageAccessor& target)
-  {
-    // TODO
-    return true;
-  }
-
-  CairoWidget::CairoWidget(const std::string& name) :
-    WidgetBase(name)
-  {
-  }
-
-  void CairoWidget::SetSize(unsigned int width,
-                            unsigned int height)
-  {
-    surface_.SetSize(width, height, false /* no alpha */);
-  }
-  
-
-  bool CairoWidget::Render(Orthanc::ImageAccessor& target)
-  {
-    // Don't call the base class here, as
-    // "ClearBackgroundCairo()" is a faster alternative
-
-    if (IsAligned(target))
-    {
-      OrthancStone::CairoSurface surface(target, false /* no alpha */);
-      OrthancStone::CairoContext context(surface);
-      ClearBackgroundCairo(context);
-      return RenderCairo(context);
-    }
-    else
-    {
-      OrthancStone::CairoContext context(surface_);
-      ClearBackgroundCairo(context);
-
-      if (RenderCairo(context))
-      {
-        Orthanc::ImageAccessor surface;
-        surface_.GetReadOnlyAccessor(surface);
-        Orthanc::ImageProcessing::Copy(target, surface);
-        return true;
-      }
-      else
-      {
-        return false;
-      }
-    }
-  }
-
-
-  void CairoWidget::RenderMouseOver(Orthanc::ImageAccessor& target,
-                                    int x,
-                                    int y)
-  {
-    if (IsAligned(target))
-    {
-      OrthancStone::CairoSurface surface(target, false /* no alpha */);
-      OrthancStone::CairoContext context(surface);
-      RenderMouseOverCairo(context, x, y);
-    }
-    else
-    {
-      Orthanc::ImageAccessor accessor;
-      surface_.GetWriteableAccessor(accessor);
-      Orthanc::ImageProcessing::Copy(accessor, target);
-
-      OrthancStone::CairoContext context(surface_);
-      RenderMouseOverCairo(context, x, y);
-
-      Orthanc::ImageProcessing::Copy(target, accessor);
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/CairoWidget.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "WidgetBase.h"
-
-namespace Deprecated
-{
-  class CairoWidget : public WidgetBase
-  {
-  private:
-    OrthancStone::CairoSurface   surface_;
-
-  protected:
-    virtual bool RenderCairo(OrthancStone::CairoContext& context) = 0;
-    
-    virtual void RenderMouseOverCairo(OrthancStone::CairoContext& context,
-                                      int x,
-                                      int y) = 0;
-    
-  public:
-    CairoWidget(const std::string& name);
-
-    virtual void SetSize(unsigned int width,
-                         unsigned int height);
-
-    virtual bool Render(Orthanc::ImageAccessor& target);
-
-    virtual void RenderMouseOver(Orthanc::ImageAccessor& target,
-                                 int x,
-                                 int y);  
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/EmptyWidget.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "EmptyWidget.h"
-
-#include <Images/ImageProcessing.h>
-#include <OrthancException.h>
-
-namespace Deprecated
-{
-  bool EmptyWidget::Render(Orthanc::ImageAccessor& surface)
-  {
-    // Note: This call is slow
-    Orthanc::ImageProcessing::Set(surface, red_, green_, blue_, 255);
-    return true;
-  }
-
-
-  void EmptyWidget::DoAnimation()
-  {
-    throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/EmptyWidget.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,116 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "IWidget.h"
-
-namespace Deprecated
-{
-  /**
-   * This is a test widget that simply fills its surface with an
-   * uniform color.
-   **/
-  class EmptyWidget : public IWidget
-  {
-  private:
-    uint8_t  red_;
-    uint8_t  green_;
-    uint8_t  blue_;
-
-  public:
-    EmptyWidget(uint8_t red,
-                uint8_t green,
-                uint8_t blue) :
-      red_(red),
-      green_(green),
-      blue_(blue)
-    {
-    }
-
-    virtual void FitContent()
-    {
-    }
-
-    virtual void SetParent(IWidget& widget)
-    {
-    }
-
-    virtual void SetViewport(WidgetViewport& viewport)
-    {
-    }
-
-    virtual void NotifyContentChanged()
-    {
-    }
-
-    virtual void SetStatusBar(IStatusBar& statusBar)
-    {
-    }
-
-    virtual void SetSize(unsigned int width,
-                         unsigned int height)
-    {
-    }
-
-    virtual bool Render(Orthanc::ImageAccessor& surface);
-
-    virtual IMouseTracker* CreateMouseTracker(OrthancStone::MouseButton button,
-                                              int x,
-                                              int y,
-                                              OrthancStone::KeyboardModifiers modifiers,
-                                              const std::vector<Touch>& touches)
-    {
-      return NULL;
-    }
-
-    virtual void RenderMouseOver(Orthanc::ImageAccessor& target,
-                                 int x,
-                                 int y)
-    {
-    }
-
-    virtual void MouseWheel(OrthancStone::MouseWheelDirection direction,
-                            int x,
-                            int y,
-                            OrthancStone::KeyboardModifiers modifiers)
-    {
-    }
-
-    virtual void KeyPressed(OrthancStone::KeyboardKeys key,
-                            char keyChar,
-                            OrthancStone::KeyboardModifiers modifiers)
-    {
-    }
-
-    virtual bool HasAnimation() const
-    {
-      return false;
-    }
-
-    virtual void DoAnimation();
-
-    virtual bool HasRenderMouseOver()
-    {
-      return false;
-    }
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/IWidget.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../StoneEnumerations.h"
-#include "../Viewport/IMouseTracker.h"
-#include "../Viewport/IStatusBar.h"
-
-namespace Deprecated
-{
-  class WidgetViewport;  // Forward declaration
-  
-  class IWidget : public boost::noncopyable
-  {
-  public:
-    virtual ~IWidget()
-    {
-    }
-
-    virtual void FitContent() = 0;
-
-    virtual void SetParent(IWidget& parent) = 0;
-    
-    virtual void SetViewport(WidgetViewport& viewport) = 0;
-
-    virtual void SetStatusBar(IStatusBar& statusBar) = 0;
-
-    virtual void SetSize(unsigned int width, 
-                         unsigned int height) = 0;
- 
-    virtual bool Render(Orthanc::ImageAccessor& surface) = 0;
-
-    virtual IMouseTracker* CreateMouseTracker(OrthancStone::MouseButton button,
-                                              int x,
-                                              int y,
-                                              OrthancStone::KeyboardModifiers modifiers,
-                                              const std::vector<Touch>& touches) = 0;
-
-    virtual void RenderMouseOver(Orthanc::ImageAccessor& target,
-                                 int x,
-                                 int y) = 0;
-
-    virtual bool HasRenderMouseOver() = 0;
-
-    virtual void MouseWheel(OrthancStone::MouseWheelDirection direction,
-                            int x,
-                            int y,
-                            OrthancStone::KeyboardModifiers modifiers) = 0;
-
-    virtual void KeyPressed(OrthancStone::KeyboardKeys key,
-                            char keyChar,
-                            OrthancStone::KeyboardModifiers modifiers) = 0;
-
-    virtual bool HasAnimation() const = 0;
-
-    virtual void DoAnimation() = 0;
-
-    // Subclasses can call this method to signal the display of the
-    // widget must be refreshed
-    virtual void NotifyContentChanged() = 0;
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/IWorldSceneInteractor.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "IWorldSceneMouseTracker.h"
-
-#include "../Toolbox/ViewportGeometry.h"
-#include "../../StoneEnumerations.h"
-#include "../Viewport/IStatusBar.h"
-
-namespace Deprecated
-{
-    class WorldSceneWidget;
-
-    class IWorldSceneInteractor : public boost::noncopyable
-    {
-    public:
-        virtual ~IWorldSceneInteractor()
-        {
-        }
-
-        virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget,
-                                                            const ViewportGeometry& view,
-                                                            OrthancStone::MouseButton button,
-                                                            OrthancStone::KeyboardModifiers modifiers,
-                                                            int viewportX,
-                                                            int viewportY,
-                                                            double x,
-                                                            double y,
-                                                            IStatusBar* statusBar,
-                                                            const std::vector<Touch>& touches) = 0;
-
-        virtual void MouseOver(OrthancStone::CairoContext& context,
-                               WorldSceneWidget& widget,
-                               const ViewportGeometry& view,
-                               double x,
-                               double y,
-                               IStatusBar* statusBar) = 0;
-
-        virtual void MouseWheel(WorldSceneWidget& widget,
-                                OrthancStone::MouseWheelDirection direction,
-                                OrthancStone::KeyboardModifiers modifiers,
-                                IStatusBar* statusBar) = 0;
-
-        virtual void KeyPressed(WorldSceneWidget& widget,
-                                OrthancStone::KeyboardKeys key,
-                                char keyChar,
-                                OrthancStone::KeyboardModifiers modifiers,
-                                IStatusBar* statusBar) = 0;
-    };
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/IWorldSceneMouseTracker.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Wrappers/CairoContext.h"
-#include "../Viewport/IMouseTracker.h" // only to get the "Touch" definition
-
-namespace Deprecated
-{
-
-  // this is tracking a mouse in scene coordinates/mm unlike
-  // the IMouseTracker that is tracking a mouse
-  // in screen coordinates/pixels.
-  class IWorldSceneMouseTracker : public boost::noncopyable
-  {
-  public:
-    virtual ~IWorldSceneMouseTracker()
-    {
-    }
-
-    virtual bool HasRender() const = 0;
-
-    virtual void Render(OrthancStone::CairoContext& context,
-                        double zoom) = 0;
-
-    virtual void MouseUp() = 0;
-
-    virtual void MouseMove(int displayX,
-                           int displayY,
-                           double sceneX,
-                           double sceneY,
-                           const std::vector<Touch>& displayTouches,
-                           const std::vector<Touch>& sceneTouches) = 0;
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/LayoutWidget.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,501 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "LayoutWidget.h"
-
-#include <Logging.h>
-#include <OrthancException.h>
-
-#include <boost/math/special_functions/round.hpp>
-
-namespace Deprecated
-{
-  class LayoutWidget::LayoutMouseTracker : public IMouseTracker
-  {
-  private:
-    std::unique_ptr<IMouseTracker>   tracker_;
-    int                            left_;
-    int                            top_;
-    unsigned int                   width_;
-    unsigned int                   height_;
-
-  public:
-    LayoutMouseTracker(IMouseTracker* tracker,
-                       int left,
-                       int top,
-                       unsigned int width,
-                       unsigned int height) :
-      tracker_(tracker),
-      left_(left),
-      top_(top),
-      width_(width),
-      height_(height)
-    {
-      if (tracker == NULL)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-      }
-    }
-
-    virtual void Render(Orthanc::ImageAccessor& surface)
-    {
-      Orthanc::ImageAccessor accessor;
-      surface.GetRegion(accessor, left_, top_, width_, height_);
-      tracker_->Render(accessor);
-    }
-
-    virtual void MouseUp()
-    {
-      tracker_->MouseUp();
-    }
-
-    virtual void MouseMove(int x, 
-                           int y,
-                           const std::vector<Touch>& displayTouches)
-    {
-      std::vector<Touch> relativeTouches;
-      for (size_t t = 0; t < displayTouches.size(); t++)
-      {
-        relativeTouches.push_back(Touch(displayTouches[t].x - left_, displayTouches[t].y - top_));
-      }
-
-      tracker_->MouseMove(x - left_, y - top_, relativeTouches);
-    }
-  };
-
-
-  class LayoutWidget::ChildWidget : public boost::noncopyable
-  {
-  private:
-    boost::shared_ptr<IWidget>  widget_;
-    int                     left_;
-    int                     top_;
-    unsigned int            width_;
-    unsigned int            height_;
-
-  public:
-    ChildWidget(boost::shared_ptr<IWidget> widget) :
-      widget_(widget)
-    {
-      assert(widget != NULL);
-      SetEmpty();
-    }
-
-    void DoAnimation()
-    {
-      if (widget_->HasAnimation())
-      {
-        widget_->DoAnimation();
-      }
-    }
-
-    IWidget& GetWidget() const
-    {
-      return *widget_;
-    }
-
-    void SetRectangle(unsigned int left, 
-                      unsigned int top,
-                      unsigned int width,
-                      unsigned int height)
-    {
-      left_ = left;
-      top_ = top;
-      width_ = width;
-      height_ = height;
-
-      widget_->SetSize(width, height);
-    }
-
-    void SetEmpty()
-    {
-      SetRectangle(0, 0, 0, 0);
-    }
-
-    bool Contains(int x, 
-                  int y) const
-    {
-      return (x >= left_ && 
-              y >= top_ &&
-              x < left_ + static_cast<int>(width_) &&
-              y < top_ + static_cast<int>(height_));
-    }      
-
-    bool Render(Orthanc::ImageAccessor& target)
-    {
-      if (width_ == 0 ||
-          height_ == 0)
-      {
-        return true;
-      }
-      else 
-      {
-        Orthanc::ImageAccessor accessor;
-        target.GetRegion(accessor, left_, top_, width_, height_);
-        return widget_->Render(accessor);
-      }
-    }
-
-    IMouseTracker* CreateMouseTracker(OrthancStone::MouseButton button,
-                                      int x,
-                                      int y,
-                                      OrthancStone::KeyboardModifiers modifiers,
-                                      const std::vector<Touch>& touches)
-    {
-      if (Contains(x, y))
-      {
-        IMouseTracker* tracker = widget_->CreateMouseTracker(button, 
-                                                             x - left_, 
-                                                             y - top_, 
-                                                             modifiers,
-                                                             touches);
-        if (tracker)
-        {
-          return new LayoutMouseTracker(tracker, left_, top_, width_, height_);
-        }
-      }
-
-      return NULL;
-    }
-
-    void RenderMouseOver(Orthanc::ImageAccessor& target,
-                         int x,
-                         int y)
-    {
-      if (Contains(x, y))
-      {
-        Orthanc::ImageAccessor accessor;
-        target.GetRegion(accessor, left_, top_, width_, height_);
-
-        widget_->RenderMouseOver(accessor, x - left_, y - top_);
-      }
-    }
-
-    void MouseWheel(OrthancStone::MouseWheelDirection direction,
-                    int x,
-                    int y,
-                    OrthancStone::KeyboardModifiers modifiers)
-    {
-      if (Contains(x, y))
-      {
-        widget_->MouseWheel(direction, x - left_, y - top_, modifiers);
-      }
-    }
-    
-    bool HasRenderMouseOver()
-    {
-      return widget_->HasRenderMouseOver();
-    }
-  };
-
-
-  void LayoutWidget::ComputeChildrenExtents()
-  {
-    if (children_.size() == 0)
-    {
-      return;
-    }
-
-    float internal = static_cast<float>(paddingInternal_);
-
-    if (width_ <= paddingLeft_ + paddingRight_ ||
-        height_ <= paddingTop_ + paddingBottom_)
-    {
-      for (size_t i = 0; i < children_.size(); i++)
-      {
-        children_[i]->SetEmpty();          
-      }
-    }
-    else if (isHorizontal_)
-    {
-      unsigned int padding = paddingLeft_ + paddingRight_ + (static_cast<unsigned int>(children_.size()) - 1) * paddingInternal_;
-      float childWidth = ((static_cast<float>(width_) - static_cast<float>(padding)) / 
-                          static_cast<float>(children_.size()));
-        
-      for (size_t i = 0; i < children_.size(); i++)
-      {
-        float left = static_cast<float>(paddingLeft_) + static_cast<float>(i) * (childWidth + internal);
-        float right = left + childWidth;
-
-        if (left >= right)
-        {
-          children_[i]->SetEmpty();
-        }
-        else
-        {
-          children_[i]->SetRectangle(static_cast<unsigned int>(left), 
-                                     paddingTop_, 
-                                     boost::math::iround(right - left),
-                                     height_ - paddingTop_ - paddingBottom_);
-        }
-      }
-    }
-    else
-    {
-      unsigned int padding = paddingTop_ + paddingBottom_ + (static_cast<unsigned int>(children_.size()) - 1) * paddingInternal_;
-      float childHeight = ((static_cast<float>(height_) - static_cast<float>(padding)) / 
-                           static_cast<float>(children_.size()));
-        
-      for (size_t i = 0; i < children_.size(); i++)
-      {
-        float top = static_cast<float>(paddingTop_) + static_cast<float>(i) * (childHeight + internal);
-        float bottom = top + childHeight;
-
-        if (top >= bottom)
-        {
-          children_[i]->SetEmpty();
-        }
-        else
-        {
-          children_[i]->SetRectangle(paddingTop_, 
-                                     static_cast<unsigned int>(top), 
-                                     width_ - paddingLeft_ - paddingRight_,
-                                     boost::math::iround(bottom - top));
-        }
-      }
-    }
-
-    NotifyContentChanged(*this);
-  }
-
-
-  LayoutWidget::LayoutWidget(const std::string& name) :
-    WidgetBase(name),
-    isHorizontal_(true),
-    width_(0),
-    height_(0),
-    paddingLeft_(0),
-    paddingTop_(0),
-    paddingRight_(0),
-    paddingBottom_(0),
-    paddingInternal_(0)
-  {
-  }
-
-
-  LayoutWidget::~LayoutWidget()
-  {
-    for (size_t i = 0; i < children_.size(); i++)
-    {
-      delete children_[i];
-    }
-  }
-
-
-  void LayoutWidget::FitContent()
-  {
-    for (size_t i = 0; i < children_.size(); i++)
-    {
-      children_[i]->GetWidget().FitContent();
-    }
-  }
-  
-
-  void LayoutWidget::NotifyContentChanged(const IWidget& widget)
-  {
-    // One of the children has changed
-    WidgetBase::NotifyContentChanged();
-  }
-
-
-  void LayoutWidget::SetHorizontal()
-  {
-    isHorizontal_ = true;
-    ComputeChildrenExtents();
-  }
-
-
-  void LayoutWidget::SetVertical()
-  {
-    isHorizontal_ = false;
-    ComputeChildrenExtents();
-  }
-
-
-  void LayoutWidget::SetPadding(unsigned int left,
-                                unsigned int top,
-                                unsigned int right,
-                                unsigned int bottom,
-                                unsigned int spacing)
-  {
-    paddingLeft_ = left;
-    paddingTop_ = top;
-    paddingRight_ = right;
-    paddingBottom_ = bottom;
-    paddingInternal_ = spacing;
-  }
-    
-
-  void LayoutWidget::SetPadding(unsigned int padding)
-  {
-    paddingLeft_ = padding;
-    paddingTop_ = padding;
-    paddingRight_ = padding;
-    paddingBottom_ = padding;
-    paddingInternal_ = padding;
-  }
-
-
-  void LayoutWidget::AddWidget(boost::shared_ptr<IWidget> widget)  // Takes ownership
-  {
-    if (widget == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    if (GetStatusBar() != NULL)
-    {
-      widget->SetStatusBar(*GetStatusBar());
-    }
-
-    children_.push_back(new ChildWidget(widget));
-    widget->SetParent(*this);
-
-    ComputeChildrenExtents();
-
-    if (widget->HasAnimation())
-    {
-      hasAnimation_ = true;
-    }
-  }
-
-
-  void LayoutWidget::SetStatusBar(IStatusBar& statusBar)
-  {
-    WidgetBase::SetStatusBar(statusBar);
-
-    for (size_t i = 0; i < children_.size(); i++)
-    {
-      children_[i]->GetWidget().SetStatusBar(statusBar);
-    }
-  }
-
-
-  void LayoutWidget::SetSize(unsigned int width,
-                             unsigned int height)
-  {
-    width_ = width;
-    height_ = height;
-    ComputeChildrenExtents();
-  }
-
-
-  bool LayoutWidget::Render(Orthanc::ImageAccessor& surface)
-  {
-    if (!WidgetBase::Render(surface))
-    {
-      return false;
-    }
-
-    for (size_t i = 0; i < children_.size(); i++)
-    {
-      if (!children_[i]->Render(surface))
-      {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-    
-  IMouseTracker* LayoutWidget::CreateMouseTracker(OrthancStone::MouseButton button,
-                                                  int x,
-                                                  int y,
-                                                  OrthancStone::KeyboardModifiers modifiers,
-                                                  const std::vector<Touch>& touches)
-  {
-    for (size_t i = 0; i < children_.size(); i++)
-    {
-      IMouseTracker* tracker = children_[i]->CreateMouseTracker(button, x, y, modifiers, touches);
-      if (tracker != NULL)
-      {
-        return tracker;
-      }
-    }
-
-    return NULL;
-  }
-
-
-  void LayoutWidget::RenderMouseOver(Orthanc::ImageAccessor& target,
-                                     int x,
-                                     int y)
-  {
-    for (size_t i = 0; i < children_.size(); i++)
-    {
-      children_[i]->RenderMouseOver(target, x, y);
-    }
-  }
-
-
-  void LayoutWidget::MouseWheel(OrthancStone::MouseWheelDirection direction,
-                                int x,
-                                int y,
-                                OrthancStone::KeyboardModifiers modifiers)
-  {
-    for (size_t i = 0; i < children_.size(); i++)
-    {
-      children_[i]->MouseWheel(direction, x, y, modifiers);
-    }
-  }
-
-
-  void LayoutWidget::KeyPressed(OrthancStone::KeyboardKeys key,
-                                char keyChar,
-                                OrthancStone::KeyboardModifiers modifiers)
-  {
-    for (size_t i = 0; i < children_.size(); i++)
-    {
-      children_[i]->GetWidget().KeyPressed(key, keyChar, modifiers);
-    }
-  }
-
-  
-  void LayoutWidget::DoAnimation()
-  {
-    if (hasAnimation_)
-    {
-      for (size_t i = 0; i < children_.size(); i++)
-      {
-        children_[i]->DoAnimation();
-      }
-    }
-    else
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-    }
-  }
-
-
-  bool LayoutWidget::HasRenderMouseOver()
-  {
-    for (size_t i = 0; i < children_.size(); i++)
-    {
-      if (children_[i]->HasRenderMouseOver())
-      {
-        return true;
-      }
-    }
-
-    return false;
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/LayoutWidget.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "WidgetBase.h"
-
-#include <vector>
-#include <memory>
-
-namespace Deprecated
-{
-  class LayoutWidget : public WidgetBase
-  {
-  private:
-    class LayoutMouseTracker;
-    class ChildWidget;
-
-    std::vector<ChildWidget*>     children_;
-    bool                          isHorizontal_;
-    unsigned int                  width_;
-    unsigned int                  height_;
-    std::unique_ptr<IMouseTracker>  mouseTracker_;
-    unsigned int                  paddingLeft_;
-    unsigned int                  paddingTop_;
-    unsigned int                  paddingRight_;
-    unsigned int                  paddingBottom_;
-    unsigned int                  paddingInternal_;
-    bool                          hasAnimation_;
-
-    void ComputeChildrenExtents();
-
-  public:
-    LayoutWidget(const std::string& name);
-
-    virtual ~LayoutWidget();
-
-    virtual void FitContent();
-
-    virtual void NotifyContentChanged(const IWidget& widget);
-
-    void SetHorizontal();
-
-    void SetVertical();
-
-    void SetPadding(unsigned int left,
-                    unsigned int top,
-                    unsigned int right,
-                    unsigned int bottom,
-                    unsigned int spacing);
-    
-    void SetPadding(unsigned int padding);
-
-    unsigned int GetPaddingLeft() const
-    {
-      return paddingLeft_;
-    }
-
-    unsigned int GetPaddingTop() const
-    {
-      return paddingTop_;
-    }
-
-    unsigned int GetPaddingRight() const
-    {
-      return paddingRight_;
-    }
-
-    unsigned int GetPaddingBottom() const
-    {
-      return paddingBottom_;
-    }
-
-    unsigned int GetPaddingInternal() const
-    {
-      return paddingInternal_;
-    }
-
-    void AddWidget(boost::shared_ptr<IWidget> widget);
-
-    virtual void SetStatusBar(IStatusBar& statusBar);
-
-    virtual void SetSize(unsigned int width,
-                         unsigned int height);
-
-    virtual bool Render(Orthanc::ImageAccessor& surface);
-    
-    virtual IMouseTracker* CreateMouseTracker(OrthancStone::MouseButton button,
-                                              int x,
-                                              int y,
-                                              OrthancStone::KeyboardModifiers modifiers,
-                                              const std::vector<Touch>& touches);
-
-    virtual void RenderMouseOver(Orthanc::ImageAccessor& target,
-                                 int x,
-                                 int y);
-
-    virtual void MouseWheel(OrthancStone::MouseWheelDirection direction,
-                            int x,
-                            int y,
-                            OrthancStone::KeyboardModifiers modifiers);
-
-    virtual void KeyPressed(OrthancStone::KeyboardKeys key,
-                            char keyChar,
-                            OrthancStone::KeyboardModifiers modifiers);
-
-    virtual bool HasAnimation() const
-    {
-      return hasAnimation_;
-    }
-
-    virtual void DoAnimation();
-
-    virtual bool HasRenderMouseOver();
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/PanMouseTracker.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "PanMouseTracker.h"
-
-#include <Logging.h>
-#include <OrthancException.h>
-
-namespace Deprecated
-{
-  PanMouseTracker::PanMouseTracker(WorldSceneWidget& that,
-                                   int x,
-                                   int y) :
-    that_(that)
-  {
-    that.GetView().GetPan(originalPanX_, originalPanY_);
-    that.GetView().MapPixelCenterToScene(downX_, downY_, x, y);
-  }
-    
-
-  void PanMouseTracker::Render(OrthancStone::CairoContext& context,
-                               double zoom)
-  {
-    throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-  }
-
-
-  void PanMouseTracker::MouseMove(int displayX,
-                                  int displayY,
-                                  double x,
-                                  double y,
-                                  const std::vector<Touch>& displayTouches,
-                                  const std::vector<Touch>& sceneTouches)
-  {
-    ViewportGeometry view = that_.GetView();
-    view.SetPan(originalPanX_ + (x - downX_) * view.GetZoom(),
-                originalPanY_ + (y - downY_) * view.GetZoom());
-    that_.SetView(view);
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/PanMouseTracker.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "WorldSceneWidget.h"
-
-namespace Deprecated
-{
-  class PanMouseTracker : public IWorldSceneMouseTracker
-  {
-  private:
-    WorldSceneWidget&  that_;
-    double             originalPanX_;
-    double             originalPanY_;
-    double             downX_;
-    double             downY_;
-    
-  public:
-    PanMouseTracker(WorldSceneWidget& that,
-                    int x,
-                    int y);
-    
-    virtual bool HasRender() const
-    {
-      return false;
-    }
-
-    virtual void MouseUp()
-    {
-    }
-
-    virtual void Render(OrthancStone::CairoContext& context,
-                        double zoom);
-
-    virtual void MouseMove(int displayX,
-                           int displayY,
-                           double x,
-                           double y,
-                           const std::vector<Touch>& displayTouches,
-                           const std::vector<Touch>& sceneTouches);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/PanZoomMouseTracker.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "PanZoomMouseTracker.h"
-
-#include <Logging.h>
-#include <OrthancException.h>
-#include <math.h>
-
-namespace Deprecated
-{
-  Touch GetCenter(const std::vector<Touch>& touches)
-  {
-    return Touch((touches[0].x + touches[1].x) / 2.0f, (touches[0].y + touches[1].y) / 2.0f);
-  }
-
-  double GetDistance(const std::vector<Touch>& touches)
-  {
-    float dx = touches[0].x - touches[1].x;
-    float dy = touches[0].y - touches[1].y;
-    return sqrt((double)(dx * dx) + (double)(dy * dy));
-  }
-
-
-  PanZoomMouseTracker::PanZoomMouseTracker(WorldSceneWidget& that,
-                                           const std::vector<Touch>& startTouches)
-    : that_(that),
-      originalZoom_(that.GetView().GetZoom())
-  {
-    that.GetView().GetPan(originalPanX_, originalPanY_);
-    that.GetView().MapPixelCenterToScene(originalSceneTouches_, startTouches);
-
-    originalDisplayCenter_ = GetCenter(startTouches);
-    originalSceneCenter_ = GetCenter(originalSceneTouches_);
-    originalDisplayDistanceBetweenTouches_ = GetDistance(startTouches);
-
-//    printf("original Pan %f %f\n", originalPanX_, originalPanY_);
-//    printf("original Zoom %f \n", originalZoom_);
-//    printf("original distance %f \n", (float)originalDisplayDistanceBetweenTouches_);
-//    printf("original display touches 0 %f %f\n", startTouches[0].x, startTouches[0].y);
-//    printf("original display touches 1 %f %f\n", startTouches[1].x, startTouches[1].y);
-//    printf("original Scene center %f %f\n", originalSceneCenter_.x, originalSceneCenter_.y);
-
-    unsigned int height = that.GetView().GetDisplayHeight();
-
-    if (height <= 3)
-    {
-      idle_ = true;
-      LOG(WARNING) << "image is too small to zoom (current height = " << height << ")";
-    }
-    else
-    {
-      idle_ = false;
-      normalization_ = 1.0 / static_cast<double>(height - 1);
-    }
-
-  }
-
-
-  void PanZoomMouseTracker::Render(OrthancStone::CairoContext& context,
-                                   double zoom)
-  {
-    throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-  }
-
-
-  void PanZoomMouseTracker::MouseMove(int displayX,
-                                      int displayY,
-                                      double x,
-                                      double y,
-                                      const std::vector<Touch>& displayTouches,
-                                      const std::vector<Touch>& sceneTouches)
-  {
-    ViewportGeometry view = that_.GetView();
-
-//    printf("Display touches 0 %f %f\n", displayTouches[0].x, displayTouches[0].y);
-//    printf("Display touches 1 %f %f\n", displayTouches[1].x, displayTouches[1].y);
-//    printf("Scene touches 0 %f %f\n", sceneTouches[0].x, sceneTouches[0].y);
-//    printf("Scene touches 1 %f %f\n", sceneTouches[1].x, sceneTouches[1].y);
-
-//    printf("zoom = %f\n", view.GetZoom());
-    Touch currentSceneCenter = GetCenter(sceneTouches);
-    double panX = originalPanX_ + (currentSceneCenter.x - originalSceneCenter_.x) * view.GetZoom();
-    double panY = originalPanY_ + (currentSceneCenter.y - originalSceneCenter_.y) * view.GetZoom();
-
-    view.SetPan(panX, panY);
-
-    static const double MIN_ZOOM = -4;
-    static const double MAX_ZOOM = 4;
-
-    if (!idle_)
-    {
-      double currentDistanceBetweenTouches = GetDistance(displayTouches);
-
-      double dy = static_cast<double>(currentDistanceBetweenTouches - originalDisplayDistanceBetweenTouches_) * normalization_;  // In the range [-1,1]
-      double z;
-
-      // Linear interpolation from [-1, 1] to [MIN_ZOOM, MAX_ZOOM]
-      if (dy < -1.0)
-      {
-        z = MIN_ZOOM;
-      }
-      else if (dy > 1.0)
-      {
-        z = MAX_ZOOM;
-      }
-      else
-      {
-        z = MIN_ZOOM + (MAX_ZOOM - MIN_ZOOM) * (dy + 1.0) / 2.0;
-      }
-
-      z = pow(2.0, z);
-
-      view.SetZoom(z * originalZoom_);
-    }
-
-    that_.SetView(view);
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/PanZoomMouseTracker.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "WorldSceneWidget.h"
-
-namespace Deprecated
-{
-  class PanZoomMouseTracker : public IWorldSceneMouseTracker
-  {
-  private:
-    WorldSceneWidget&  that_;
-    std::vector<Touch> originalSceneTouches_;
-    Touch              originalSceneCenter_;
-    Touch              originalDisplayCenter_;
-    double             originalPanX_;
-    double             originalPanY_;
-    double             originalZoom_;
-    double             originalDisplayDistanceBetweenTouches_;
-    bool               idle_;
-    double             normalization_;
-
-  public:
-    PanZoomMouseTracker(WorldSceneWidget& that,
-                        const std::vector<Touch>& startTouches);
-    
-    virtual bool HasRender() const
-    {
-      return false;
-    }
-
-    virtual void MouseUp()
-    {
-    }
-
-    virtual void Render(OrthancStone::CairoContext& context,
-                        double zoom);
-
-    virtual void MouseMove(int displayX,
-                           int displayY,
-                           double x,
-                           double y,
-                           const std::vector<Touch>& displayTouches,
-                           const std::vector<Touch>& sceneTouches);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/SliceViewerWidget.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,616 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "SliceViewerWidget.h"
-
-#include "../Layers/SliceOutlineRenderer.h"
-#include "../../Toolbox/GeometryToolbox.h"
-#include "../Layers/FrameRenderer.h"
-
-#include <Logging.h>
-#include <OrthancException.h>
-
-#include <boost/math/constants/constants.hpp>
-
-
-static const double THIN_SLICE_THICKNESS = 100.0 * std::numeric_limits<double>::epsilon();
-
-namespace Deprecated
-{
-  void SliceViewerWidget::Scene::DeleteLayer(size_t index)
-  {
-    if (index >= renderers_.size())
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    assert(countMissing_ <= renderers_.size());
-
-    if (renderers_[index] != NULL)
-    {
-      assert(countMissing_ < renderers_.size());
-      delete renderers_[index];
-      renderers_[index] = NULL;
-      countMissing_++;
-    }
-  }
-
-  
-  SliceViewerWidget::Scene::Scene(const OrthancStone::CoordinateSystem3D& plane,
-                                  double thickness,
-                                  size_t countLayers) :
-    plane_(plane),
-    thickness_(thickness),
-    countMissing_(countLayers),
-    renderers_(countLayers, NULL)
-  {
-    if (thickness <= 0)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-  }
-
-  
-  SliceViewerWidget::Scene::~Scene()
-  {
-    for (size_t i = 0; i < renderers_.size(); i++)
-    {
-      DeleteLayer(i);
-    }
-  }
-
-  void SliceViewerWidget::Scene::SetLayer(size_t index,
-                                          ILayerRenderer* renderer)  // Takes ownership
-  {
-    if (renderer == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
-    }
-
-    DeleteLayer(index);
-
-    renderers_[index] = renderer;
-    countMissing_--;
-  }
-
-
-  bool SliceViewerWidget::Scene::RenderScene(OrthancStone::CairoContext& context,
-                                             const ViewportGeometry& view,
-                                             const OrthancStone::CoordinateSystem3D& viewportPlane)
-  {
-    bool fullQuality = true;
-    cairo_t *cr = context.GetObject();
-
-    for (size_t i = 0; i < renderers_.size(); i++)
-    {
-      if (renderers_[i] != NULL)
-      {
-        const OrthancStone::CoordinateSystem3D& framePlane = renderers_[i]->GetLayerPlane();
-          
-        double x0, y0, x1, y1, x2, y2;
-        viewportPlane.ProjectPoint(x0, y0, framePlane.GetOrigin());
-        viewportPlane.ProjectPoint(x1, y1, framePlane.GetOrigin() + framePlane.GetAxisX());
-        viewportPlane.ProjectPoint(x2, y2, framePlane.GetOrigin() + framePlane.GetAxisY());
-
-        /**
-         * Now we solve the system of linear equations Ax + b = x', given:
-         *   A [0 ; 0] + b = [x0 ; y0]
-         *   A [1 ; 0] + b = [x1 ; y1]
-         *   A [0 ; 1] + b = [x2 ; y2]
-         * <=>
-         *   b = [x0 ; y0]
-         *   A [1 ; 0] = [x1 ; y1] - b = [x1 - x0 ; y1 - y0]
-         *   A [0 ; 1] = [x2 ; y2] - b = [x2 - x0 ; y2 - y0]
-         * <=>
-         *   b = [x0 ; y0]
-         *   [a11 ; a21] = [x1 - x0 ; y1 - y0]
-         *   [a12 ; a22] = [x2 - x0 ; y2 - y0]
-         **/
-
-        cairo_matrix_t transform;
-        cairo_matrix_init(&transform, x1 - x0, y1 - y0, x2 - x0, y2 - y0, x0, y0);
-
-        cairo_save(cr);
-        cairo_transform(cr, &transform);
-          
-        if (!renderers_[i]->RenderLayer(context, view))
-        {
-          cairo_restore(cr);
-          return false;
-        }
-
-        cairo_restore(cr);
-      }
-
-      if (renderers_[i] != NULL &&
-          !renderers_[i]->IsFullQuality())
-      {
-        fullQuality = false;
-      }
-    }
-
-    if (!fullQuality)
-    {
-      double x, y;
-      view.MapDisplayToScene(x, y, static_cast<double>(view.GetDisplayWidth()) / 2.0, 10);
-
-      cairo_translate(cr, x, y);
-
-#if 1
-      double s = 5.0 / view.GetZoom();
-      cairo_rectangle(cr, -s, -s, 2.0 * s, 2.0 * s);
-#else
-      // TODO Drawing filled circles makes WebAssembly crash!
-      cairo_arc(cr, 0, 0, 5.0 / view.GetZoom(), 0, 2.0 * boost::math::constants::pi<double>());
-#endif
-        
-      cairo_set_line_width(cr, 2.0 / view.GetZoom());
-      cairo_set_source_rgb(cr, 1, 1, 1);
-      cairo_stroke_preserve(cr);
-      cairo_set_source_rgb(cr, 1, 0, 0);
-      cairo_fill(cr);
-    }
-
-    return true;
-  }
-
-  void SliceViewerWidget::Scene::SetLayerStyle(size_t index,
-                                               const RenderStyle& style)
-  {
-    if (renderers_[index] != NULL)
-    {
-      renderers_[index]->SetLayerStyle(style);
-    }
-  }
-
-  bool SliceViewerWidget::Scene::ContainsPlane(const OrthancStone::CoordinateSystem3D& plane) const
-  {
-    bool isOpposite;
-    if (!OrthancStone::GeometryToolbox::IsParallelOrOpposite(isOpposite,
-                                                             plane.GetNormal(),
-                                                             plane_.GetNormal()))
-    {
-      return false;
-    }
-    else
-    {
-      double z = (plane_.ProjectAlongNormal(plane.GetOrigin()) -
-                  plane_.ProjectAlongNormal(plane_.GetOrigin()));
-
-      if (z < 0)
-      {
-        z = -z;
-      }
-
-      return z <= thickness_;
-    }
-  }
-
-  
-  bool SliceViewerWidget::LookupLayer(size_t& index /* out */,
-                                      const IVolumeSlicer& layer) const
-  {
-    LayersIndex::const_iterator found = layersIndex_.find(&layer);
-
-    if (found == layersIndex_.end())
-    {
-      return false;
-    }
-    else
-    {
-      index = found->second;
-      assert(index < layers_.size() &&
-             layers_[index].get() == &layer);
-      return true;
-    }
-  }
-
-
-  void SliceViewerWidget::GetLayerExtent(OrthancStone::Extent2D& extent,
-                                         IVolumeSlicer& source) const
-  {
-    extent.Reset();
-
-    std::vector<OrthancStone::Vector> points;
-    if (source.GetExtent(points, plane_))
-    {
-      for (size_t i = 0; i < points.size(); i++)
-      {
-        double x, y;
-        plane_.ProjectPoint(x, y, points[i]);
-        extent.AddPoint(x, y);
-      }
-    }
-  }
-
-
-  OrthancStone::Extent2D SliceViewerWidget::GetSceneExtent()
-  {
-    OrthancStone::Extent2D sceneExtent;
-
-    for (size_t i = 0; i < layers_.size(); i++)
-    {
-      assert(layers_[i] != NULL);
-      OrthancStone::Extent2D layerExtent;
-      GetLayerExtent(layerExtent, *layers_[i]);
-
-      sceneExtent.Union(layerExtent);
-    }
-
-    return sceneExtent;
-  }
-
-  
-  bool SliceViewerWidget::RenderScene(OrthancStone::CairoContext& context,
-                                      const ViewportGeometry& view)
-  {
-    if (currentScene_.get() != NULL)
-    {
-      return currentScene_->RenderScene(context, view, plane_);
-    }
-    else
-    {
-      return true;
-    }
-  }
-
-  
-  void SliceViewerWidget::ResetPendingScene()
-  {
-    double thickness;
-    if (pendingScene_.get() == NULL)
-    {
-      thickness = 1.0;
-    }
-    else
-    {
-      thickness = pendingScene_->GetThickness();
-    }
-    
-    pendingScene_.reset(new Scene(plane_, thickness, layers_.size()));
-  }
-  
-
-  void SliceViewerWidget::UpdateLayer(size_t index,
-                                      ILayerRenderer* renderer,
-                                      const OrthancStone::CoordinateSystem3D& plane)
-  {
-    LOG(INFO) << "Updating layer " << index;
-    
-    std::unique_ptr<ILayerRenderer> tmp(renderer);
-
-    if (renderer == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
-    }
-
-    if (index >= layers_.size())
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    assert(layers_.size() == styles_.size());
-    renderer->SetLayerStyle(styles_[index]);
-
-    if (currentScene_.get() != NULL &&
-        currentScene_->ContainsPlane(plane))
-    {
-      currentScene_->SetLayer(index, tmp.release());
-      NotifyContentChanged();
-    }
-    else if (pendingScene_.get() != NULL &&
-             pendingScene_->ContainsPlane(plane))
-    {
-      pendingScene_->SetLayer(index, tmp.release());
-
-      if (currentScene_.get() == NULL ||
-          !currentScene_->IsComplete() ||
-          pendingScene_->IsComplete())
-      {
-#if __cplusplus < 201103L
-        currentScene_.reset(pendingScene_.release());
-#else
-        currentScene_ = std::move(pendingScene_);
-#endif
-
-        NotifyContentChanged();
-      }
-    }
-  }
-
-  
-  SliceViewerWidget::SliceViewerWidget(const std::string& name) :
-    WorldSceneWidget(name),
-    started_(false)
-  {
-    SetBackgroundCleared(true);
-  }
-  
-  
-  void SliceViewerWidget::ObserveLayer(IVolumeSlicer& layer)
-  {
-    // currently ignoring errors of type IVolumeSlicer::GeometryErrorMessage
-
-    Register<IVolumeSlicer::GeometryReadyMessage>(layer, &SliceViewerWidget::OnGeometryReady);
-    Register<IVolumeSlicer::SliceContentChangedMessage>(layer, &SliceViewerWidget::OnSliceChanged);
-    Register<IVolumeSlicer::ContentChangedMessage>(layer, &SliceViewerWidget::OnContentChanged);
-    Register<IVolumeSlicer::LayerReadyMessage>(layer, &SliceViewerWidget::OnLayerReady);
-    Register<IVolumeSlicer::LayerErrorMessage>(layer, &SliceViewerWidget::OnLayerError);
-  }
-
-
-  size_t SliceViewerWidget::AddLayer(boost::shared_ptr<IVolumeSlicer> layer)
-  {
-    if (layer == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
-    }
-
-    size_t index = layers_.size();
-    layers_.push_back(layer);
-    styles_.push_back(RenderStyle());
-    layersIndex_[layer.get()] = index;
-
-    ResetPendingScene();
-
-    ObserveLayer(*layer);
-
-    ResetChangedLayers();
-
-    return index;
-  }
-
-
-  void SliceViewerWidget::ReplaceLayer(size_t index,
-                                       boost::shared_ptr<IVolumeSlicer> layer)
-  {
-    if (layer == NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
-    }
-
-    if (index >= layers_.size())
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    layers_[index] = layer;
-    layersIndex_[layer.get()] = index;
-
-    ResetPendingScene();
-
-    ObserveLayer(*layer);
-
-    InvalidateLayer(index);
-  }
-
-
-  void SliceViewerWidget::RemoveLayer(size_t index)
-  {
-    if (index >= layers_.size())
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    IVolumeSlicer* previousLayer = layers_[index].get();
-    layersIndex_.erase(layersIndex_.find(previousLayer));
-    layers_.erase(layers_.begin() + index);
-    changedLayers_.erase(changedLayers_.begin() + index);
-    styles_.erase(styles_.begin() + index);
-
-    layers_[index].reset();
-
-    currentScene_->DeleteLayer(index);
-    ResetPendingScene();
-
-    NotifyContentChanged();
-  }
-
-
-  const RenderStyle& SliceViewerWidget::GetLayerStyle(size_t layer) const
-  {
-    if (layer >= layers_.size())
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    assert(layers_.size() == styles_.size());
-    return styles_[layer];
-  }
-  
-
-  void SliceViewerWidget::SetLayerStyle(size_t layer,
-                                        const RenderStyle& style)
-  {
-    if (layer >= layers_.size())
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    assert(layers_.size() == styles_.size());
-    styles_[layer] = style;
-
-    if (currentScene_.get() != NULL)
-    {
-      currentScene_->SetLayerStyle(layer, style);
-    }
-
-    if (pendingScene_.get() != NULL)
-    {
-      pendingScene_->SetLayerStyle(layer, style);
-    }
-
-    NotifyContentChanged();
-  }
-  
-
-  void SliceViewerWidget::SetSlice(const OrthancStone::CoordinateSystem3D& plane)
-  {
-    LOG(INFO) << "Setting slice origin: (" << plane.GetOrigin()[0]
-              << "," << plane.GetOrigin()[1]
-              << "," << plane.GetOrigin()[2] << ")";
-    
-    Deprecated::Slice displayedSlice(plane_, THIN_SLICE_THICKNESS);
-
-    //if (!displayedSlice.ContainsPlane(slice))
-    {
-      if (currentScene_.get() == NULL ||
-          (pendingScene_.get() != NULL &&
-           pendingScene_->IsComplete()))
-      {
-#if __cplusplus < 201103L
-        currentScene_.reset(pendingScene_.release());
-#else
-        currentScene_ = std::move(pendingScene_);
-#endif
-      }
-
-      plane_ = plane;
-      ResetPendingScene();
-
-      InvalidateAllLayers();   // TODO Removing this line avoid loading twice the image in WASM
-    }
-
-    BroadcastMessage(DisplayedSliceMessage(*this, displayedSlice));
-  }
-
-
-  void SliceViewerWidget::OnGeometryReady(const IVolumeSlicer::GeometryReadyMessage& message)
-  {
-    size_t i;
-    if (LookupLayer(i, message.GetOrigin()))
-    {
-      LOG(INFO) << ": Geometry ready for layer " << i << " in " << GetName();
-
-      changedLayers_[i] = true;
-      //layers_[i]->ScheduleLayerCreation(plane_);
-    }
-    BroadcastMessage(GeometryChangedMessage(*this));
-  }
-  
-
-  void SliceViewerWidget::InvalidateAllLayers()
-  {
-    for (size_t i = 0; i < layers_.size(); i++)
-    {
-      assert(layers_[i] != NULL);
-      changedLayers_[i] = true;
-      
-      //layers_[i]->ScheduleLayerCreation(plane_);
-    }
-  }
-
-
-  void SliceViewerWidget::InvalidateLayer(size_t layer)
-  {
-    if (layer >= layers_.size())
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-    }
-
-    assert(layers_[layer] != NULL);
-    changedLayers_[layer] = true;
-
-    //layers_[layer]->ScheduleLayerCreation(plane_);
-  }
-
-
-  void SliceViewerWidget::OnContentChanged(const IVolumeSlicer::ContentChangedMessage& message)
-  {
-    size_t index;
-    if (LookupLayer(index, message.GetOrigin()))
-    {
-      InvalidateLayer(index);
-    }
-    
-    BroadcastMessage(SliceViewerWidget::ContentChangedMessage(*this));
-  }
-  
-
-  void SliceViewerWidget::OnSliceChanged(const IVolumeSlicer::SliceContentChangedMessage& message)
-  {
-    if (message.GetSlice().ContainsPlane(plane_))
-    {
-      size_t index;
-      if (LookupLayer(index, message.GetOrigin()))
-      {
-        InvalidateLayer(index);
-      }
-    }
-    
-    BroadcastMessage(SliceViewerWidget::ContentChangedMessage(*this));
-  }
-  
-  
-  void SliceViewerWidget::OnLayerReady(const IVolumeSlicer::LayerReadyMessage& message)
-  {
-    size_t index;
-    if (LookupLayer(index, message.GetOrigin()))
-    {
-      LOG(INFO) << "Renderer ready for layer " << index;
-      UpdateLayer(index, message.CreateRenderer(), message.GetSlice());
-    }
-    
-    BroadcastMessage(SliceViewerWidget::ContentChangedMessage(*this));
-  }
-
-
-  void SliceViewerWidget::OnLayerError(const IVolumeSlicer::LayerErrorMessage& message)
-  {
-    size_t index;
-    if (LookupLayer(index, message.GetOrigin()))
-    {
-      LOG(ERROR) << "Using error renderer on layer " << index;
-
-      // TODO
-      //UpdateLayer(index, new SliceOutlineRenderer(slice), slice);
-
-      BroadcastMessage(SliceViewerWidget::ContentChangedMessage(*this));
-    }
-  }
-
-
-  void SliceViewerWidget::ResetChangedLayers()
-  {
-    changedLayers_.resize(layers_.size());
-
-    for (size_t i = 0; i < changedLayers_.size(); i++)
-    {
-      changedLayers_[i] = false;
-    }
-  }
-
-
-  void SliceViewerWidget::DoAnimation()
-  {
-    assert(changedLayers_.size() <= layers_.size());
-    
-    for (size_t i = 0; i < changedLayers_.size(); i++)
-    {
-      if (changedLayers_[i])
-      {
-        layers_[i]->ScheduleLayerCreation(plane_);
-      }
-    }
-    
-    ResetChangedLayers();
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/SliceViewerWidget.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "WorldSceneWidget.h"
-#include "../Layers/IVolumeSlicer.h"
-#include "../../Toolbox/Extent2D.h"
-#include "../../Messages/ObserverBase.h"
-
-#include <map>
-
-namespace Deprecated
-{
-  class SliceViewerWidget :
-    public WorldSceneWidget,
-    public OrthancStone::ObserverBase<SliceViewerWidget>,
-    public OrthancStone::IObservable
-  {
-  public:
-    ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, GeometryChangedMessage, SliceViewerWidget);
-    ORTHANC_STONE_DEFINE_ORIGIN_MESSAGE(__FILE__, __LINE__, ContentChangedMessage, SliceViewerWidget);
-
-
-    // TODO - Use this message in ReferenceLineSource
-    class DisplayedSliceMessage : public OrthancStone::OriginMessage<SliceViewerWidget>
-    {
-      ORTHANC_STONE_MESSAGE(__FILE__, __LINE__);
-      
-    private:
-      const Deprecated::Slice& slice_;
-
-    public:
-      DisplayedSliceMessage(SliceViewerWidget& origin,
-                            const Deprecated::Slice& slice) :
-        OriginMessage(origin),
-        slice_(slice)
-      {
-      }
-
-      const Deprecated::Slice& GetSlice() const
-      {
-        return slice_;
-      }
-    };
-
-  private:
-    SliceViewerWidget(const SliceViewerWidget&);
-    SliceViewerWidget& operator=(const SliceViewerWidget&);
-
-    class Scene : public boost::noncopyable
-    {
-    private:
-      OrthancStone::CoordinateSystem3D  plane_;
-      double                            thickness_;
-      size_t                            countMissing_;
-      std::vector<ILayerRenderer*>      renderers_;
-
-    public:
-      void DeleteLayer(size_t index);
-
-      Scene(const OrthancStone::CoordinateSystem3D& plane,
-            double thickness,
-            size_t countLayers);
-
-      ~Scene();
-
-      void SetLayer(size_t index,
-                    ILayerRenderer* renderer);  // Takes ownership
-
-      const OrthancStone::CoordinateSystem3D& GetPlane() const
-      {
-        return plane_;
-      }
-
-      bool HasRenderer(size_t index)
-      {
-        return renderers_[index] != NULL;
-      }
-
-      bool IsComplete() const
-      {
-        return countMissing_ == 0;
-      }
-
-      unsigned int GetCountMissing() const
-      {
-        return static_cast<unsigned int>(countMissing_);
-      }
-
-      bool RenderScene(OrthancStone::CairoContext& context,
-                       const ViewportGeometry& view,
-                       const OrthancStone::CoordinateSystem3D& viewportPlane);
-
-      void SetLayerStyle(size_t index,
-                         const RenderStyle& style);
-
-      bool ContainsPlane(const OrthancStone::CoordinateSystem3D& plane) const;
-
-      double GetThickness() const
-      {
-        return thickness_;
-      }
-    };
-
-    
-    typedef std::map<const IVolumeSlicer*, size_t>  LayersIndex;
-
-    bool                         started_;
-    LayersIndex                  layersIndex_;
-    std::vector<boost::shared_ptr<IVolumeSlicer> >  layers_;
-    std::vector<RenderStyle>     styles_;
-    OrthancStone::CoordinateSystem3D           plane_;
-    std::unique_ptr<Scene>         currentScene_;
-    std::unique_ptr<Scene>         pendingScene_;
-    std::vector<bool>            changedLayers_;
-
-    bool LookupLayer(size_t& index /* out */,
-                     const IVolumeSlicer& layer) const;
-
-    void GetLayerExtent(OrthancStone::Extent2D& extent,
-                        IVolumeSlicer& source) const;
-
-    void OnGeometryReady(const IVolumeSlicer::GeometryReadyMessage& message);
-
-    virtual void OnContentChanged(const IVolumeSlicer::ContentChangedMessage& message);
-
-    virtual void OnSliceChanged(const IVolumeSlicer::SliceContentChangedMessage& message);
-
-    virtual void OnLayerReady(const IVolumeSlicer::LayerReadyMessage& message);
-
-    virtual void OnLayerError(const IVolumeSlicer::LayerErrorMessage& message);
-
-    void ObserveLayer(IVolumeSlicer& source);
-
-    void ResetChangedLayers();
-
-  public:
-    SliceViewerWidget(const std::string& name);
-
-    virtual OrthancStone::Extent2D GetSceneExtent();
-
-  protected:
-    virtual bool RenderScene(OrthancStone::CairoContext& context,
-                             const ViewportGeometry& view);
-
-    void ResetPendingScene();
-
-    void UpdateLayer(size_t index,
-                     ILayerRenderer* renderer,
-                     const OrthancStone::CoordinateSystem3D& plane);
-
-    void InvalidateAllLayers();
-
-    void InvalidateLayer(size_t layer);
-    
-  public:
-    virtual ~SliceViewerWidget()
-    {
-    }
-
-    size_t AddLayer(boost::shared_ptr<IVolumeSlicer> layer);
-
-    void ReplaceLayer(size_t layerIndex, boost::shared_ptr<IVolumeSlicer> layer); // Takes ownership
-
-    void RemoveLayer(size_t layerIndex);
-
-    size_t GetLayerCount() const
-    {
-      return layers_.size();
-    }
-
-    const RenderStyle& GetLayerStyle(size_t layer) const;
-
-    void SetLayerStyle(size_t layer,
-                       const RenderStyle& style);
-
-    void SetSlice(const OrthancStone::CoordinateSystem3D& plane);
-
-    const OrthancStone::CoordinateSystem3D& GetSlice() const
-    {
-      return plane_;
-    }
-
-    virtual bool HasAnimation() const
-    {
-      return true;
-    }
-
-    virtual void DoAnimation();
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/TestCairoWidget.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "TestCairoWidget.h"
-
-#include <stdio.h>
-
-
-namespace Deprecated
-{
-  namespace Samples
-  {
-    void TestCairoWidget::DoAnimation() 
-    {
-      value_ -= 0.01f;
-      if (value_ < 0)
-      {
-        value_ = 1;
-      }
-
-      NotifyContentChanged();
-    }
-
-
-    bool TestCairoWidget::RenderCairo(OrthancStone::CairoContext& context)
-    {
-      cairo_t* cr = context.GetObject();
-
-      cairo_set_source_rgb (cr, .3, 0, 0);
-      cairo_paint(cr);
-
-      cairo_set_source_rgb(cr, 0, 1, 0);
-      cairo_rectangle(cr, width_ / 4, height_ / 4, width_ / 2, height_ / 2);
-      cairo_set_line_width(cr, 1.0);
-      cairo_fill(cr);
-
-      cairo_set_source_rgb(cr, 0, 1, value_);
-      cairo_rectangle(cr, width_ / 2 - 50, height_ / 2 - 50, 100, 100);
-      cairo_fill(cr);
-
-      return true;
-    }
-
-
-    void TestCairoWidget::RenderMouseOverCairo(OrthancStone::CairoContext& context,
-                                               int x,
-                                               int y)
-    {
-      cairo_t* cr = context.GetObject();
-
-      cairo_set_source_rgb (cr, 1, 0, 0);
-      cairo_rectangle(cr, x - 5, y - 5, 10, 10);
-      cairo_set_line_width(cr, 1.0);
-      cairo_stroke(cr);
-
-      char buf[64];
-      sprintf(buf, "(%d,%d)", x, y);
-      UpdateStatusBar(buf);
-    }
-
-
-    TestCairoWidget::TestCairoWidget(const std::string& name, bool animate) :
-      CairoWidget(name),
-      width_(0),
-      height_(0),
-      value_(1),
-      animate_(animate)
-    {
-    }
-
-
-    void TestCairoWidget::SetSize(unsigned int width, 
-                                  unsigned int height)
-    {
-      CairoWidget::SetSize(width, height);
-      width_ = width;
-      height_ = height;
-    }
- 
-
-    IMouseTracker* TestCairoWidget::CreateMouseTracker(OrthancStone::MouseButton button,
-                                                       int x,
-                                                       int y,
-                                                       OrthancStone::KeyboardModifiers modifiers,
-                                                       const std::vector<Touch>& touches)
-    {
-      UpdateStatusBar("Click");
-      return NULL;
-    }
-
-
-    void TestCairoWidget::MouseWheel(OrthancStone::MouseWheelDirection direction,
-                                     int x,
-                                     int y,
-                                     OrthancStone::KeyboardModifiers modifiers) 
-    {
-      UpdateStatusBar(direction == OrthancStone::MouseWheelDirection_Down ? "Wheel down" : "Wheel up");
-    }
-
-    
-    void TestCairoWidget::KeyPressed(OrthancStone::KeyboardKeys key,
-                                     char keyChar,
-                                     OrthancStone::KeyboardModifiers modifiers)
-    {
-      UpdateStatusBar("Key pressed: \"" + std::string(1, keyChar) + "\"");
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/TestCairoWidget.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "CairoWidget.h"
-
-namespace Deprecated
-{
-  namespace Samples
-  {
-    class TestCairoWidget : public CairoWidget
-    {
-    private:
-      unsigned int  width_;
-      unsigned int  height_;
-      float         value_;
-      bool          animate_;
-
-    protected:
-      virtual bool RenderCairo(OrthancStone::CairoContext& context);
-
-      virtual void RenderMouseOverCairo(OrthancStone::CairoContext& context,
-                                        int x,
-                                        int y);
-
-    public:
-      TestCairoWidget(const std::string& name, bool animate);
-
-      virtual void SetSize(unsigned int width, 
-                           unsigned int height);
- 
-      virtual IMouseTracker* CreateMouseTracker(OrthancStone::MouseButton button,
-                                                int x,
-                                                int y,
-                                                OrthancStone::KeyboardModifiers modifiers,
-                                                const std::vector<Touch>& touches);
-
-      virtual void MouseWheel(OrthancStone::MouseWheelDirection direction,
-                              int x,
-                              int y,
-                              OrthancStone::KeyboardModifiers modifiers);
-    
-      virtual void KeyPressed(OrthancStone::KeyboardKeys key,
-                              char keyChar,
-                              OrthancStone::KeyboardModifiers modifiers);
-
-      virtual bool HasAnimation() const
-      {
-        return animate_;
-      }
-      
-      virtual void DoAnimation();
-
-      virtual bool HasRenderMouseOver()
-      {
-        return true;
-      }
-    };
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/TestWorldSceneWidget.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "TestWorldSceneWidget.h"
-
-#include <OrthancException.h>
-
-#include <math.h>
-#include <stdio.h>
-
-namespace Deprecated
-{
-  namespace Samples
-  {
-    class TestWorldSceneWidget::Interactor : public IWorldSceneInteractor
-    {
-    public:
-      virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget,
-                                                          const ViewportGeometry& view,
-                                                          OrthancStone::MouseButton button,
-                                                          OrthancStone::KeyboardModifiers modifiers,
-                                                          int viewportX,
-                                                          int viewportY,
-                                                          double x,
-                                                          double y,
-                                                          IStatusBar* statusBar,
-                                                          const std::vector<Touch>& touches)
-      {
-        if (statusBar)
-        {
-          char buf[64];
-          sprintf(buf, "X = %0.2f, Y = %0.2f", x, y);
-          statusBar->SetMessage(buf);
-        }
-
-        return NULL;
-      }
-
-      virtual void MouseOver(OrthancStone::CairoContext& context,
-                             WorldSceneWidget& widget,
-                             const ViewportGeometry& view,
-                             double x,
-                             double y,
-                             IStatusBar* statusBar)
-      {
-        double S = 0.5;
-
-        if (fabs(x) <= S &&
-            fabs(y) <= S)
-        {
-          cairo_t* cr = context.GetObject();
-          cairo_set_source_rgb(cr, 1, 0, 0);
-          cairo_rectangle(cr, -S, -S , 2.0 * S, 2.0 * S);
-          cairo_set_line_width(cr, 1.0 / view.GetZoom());
-          cairo_stroke(cr);
-        }
-      }
-
-      virtual void MouseWheel(WorldSceneWidget& widget,
-                              OrthancStone::MouseWheelDirection direction,
-                              OrthancStone::KeyboardModifiers modifiers,
-                              IStatusBar* statusBar)
-      {
-        if (statusBar)
-        {
-          statusBar->SetMessage(direction == OrthancStone::MouseWheelDirection_Down ? "Wheel down" : "Wheel up");
-        }
-      }
-
-      virtual void KeyPressed(WorldSceneWidget& widget,
-                              OrthancStone::KeyboardKeys key,
-                              char keyChar,
-                              OrthancStone::KeyboardModifiers modifiers,
-                              IStatusBar* statusBar)
-      {
-        if (statusBar)
-        {
-          statusBar->SetMessage("Key pressed: \"" + std::string(1, keyChar) + "\"");
-        }
-      }
-    };
-
-
-    bool TestWorldSceneWidget::RenderScene(OrthancStone::CairoContext& context,
-                                           const ViewportGeometry& view)
-    {
-      cairo_t* cr = context.GetObject();
-
-      // Clear background
-      cairo_set_source_rgb(cr, 0, 0, 0);
-      cairo_paint(cr);
-
-      float color = static_cast<float>(count_ % 16) / 15.0f;
-      cairo_set_source_rgb(cr, 0, 1.0f - color, color);
-      cairo_rectangle(cr, -10, -.5, 20, 1);
-      cairo_fill(cr);
-
-      return true;
-    }
-
-
-    TestWorldSceneWidget::TestWorldSceneWidget(const std::string& name, bool animate) :
-      WorldSceneWidget(name),
-      interactor_(new Interactor),
-      animate_(animate),
-      count_(0)
-    {
-      SetInteractor(*interactor_);
-    }
-
-
-    OrthancStone::Extent2D TestWorldSceneWidget::GetSceneExtent()
-    {
-      return OrthancStone::Extent2D(-10, -.5, 10, .5);
-    }
-
-
-    void TestWorldSceneWidget::DoAnimation()
-    {
-      if (animate_)
-      {
-        count_++;
-        NotifyContentChanged();
-      }
-      else
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-      }
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/TestWorldSceneWidget.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "WorldSceneWidget.h"
-
-#include <memory>
-
-namespace Deprecated
-{
-  namespace Samples
-  {
-    class TestWorldSceneWidget : public WorldSceneWidget
-    {
-    private:
-      class Interactor;
-
-      std::unique_ptr<Interactor>   interactor_;
-      bool                        animate_;
-      unsigned int                count_;
-
-    protected:
-      virtual bool RenderScene(OrthancStone::CairoContext& context,
-                               const ViewportGeometry& view);
-
-    public:
-      TestWorldSceneWidget(const std::string& name, bool animate);
-
-      virtual OrthancStone::Extent2D GetSceneExtent();
-
-      virtual bool HasAnimation() const
-      {
-        return animate_;
-      }
-
-      virtual void DoAnimation();
-
-      virtual bool HasRenderMouseOver()
-      {
-        return true;
-      }
-    };
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/WidgetBase.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,166 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "WidgetBase.h"
-
-#include <OrthancException.h>
-#include <Images/ImageProcessing.h>
-#include <Logging.h>
-
-namespace Deprecated
-{
-  void WidgetBase::NotifyContentChanged()
-  {
-    if (parent_ != NULL)
-    {
-      parent_->NotifyContentChanged();
-    }
-
-    if (viewport_ != NULL)
-    {
-      viewport_->NotifyBackgroundChanged();
-    }
-  }
-
-
-  void WidgetBase::SetParent(IWidget& parent)
-  {
-    if (parent_ != NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-    else
-    {
-      parent_ = &parent;
-    }
-  }    
-
-  
-  void WidgetBase::ClearBackgroundOrthanc(Orthanc::ImageAccessor& target) const 
-  {
-    // Clear the background using Orthanc
-
-    if (backgroundCleared_)
-    {
-      Orthanc::ImageProcessing::Set(target, 
-                                    backgroundColor_[0],
-                                    backgroundColor_[1],
-                                    backgroundColor_[2],
-                                    255 /* alpha */);
-    }
-  }
-
-
-  void WidgetBase::ClearBackgroundCairo(OrthancStone::CairoContext& context) const
-  {
-    // Clear the background using Cairo
-
-    if (IsBackgroundCleared())
-    {
-      uint8_t red, green, blue;
-      GetBackgroundColor(red, green, blue);
-
-      context.SetSourceColor(red, green, blue);
-      cairo_paint(context.GetObject());
-    }
-  }
-
-
-  void WidgetBase::ClearBackgroundCairo(Orthanc::ImageAccessor& target) const
-  {
-    OrthancStone::CairoSurface surface(target, false /* no alpha */);
-    OrthancStone::CairoContext context(surface);
-    ClearBackgroundCairo(context);
-  }
-
-
-  void WidgetBase::UpdateStatusBar(const std::string& message)
-  {
-    if (statusBar_ != NULL)
-    {
-      statusBar_->SetMessage(message);
-    }
-  }
-
-
-  WidgetBase::WidgetBase(const std::string& name) :
-    parent_(NULL),
-    viewport_(NULL),
-    statusBar_(NULL),
-    backgroundCleared_(false),
-    transmitMouseOver_(false),
-    name_(name)
-  {
-    backgroundColor_[0] = 0;
-    backgroundColor_[1] = 0;
-    backgroundColor_[2] = 0;
-  }
-
-
-  void WidgetBase::SetViewport(WidgetViewport& viewport)
-  {
-    if (viewport_ != NULL)
-    {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-    }
-    else
-    {
-      viewport_ = &viewport;
-    }
-  }
-
-  
-  void WidgetBase::SetBackgroundColor(uint8_t red,
-                                      uint8_t green,
-                                      uint8_t blue)
-  {
-    backgroundColor_[0] = red;
-    backgroundColor_[1] = green;
-    backgroundColor_[2] = blue;
-  }
-
-  void WidgetBase::GetBackgroundColor(uint8_t& red,
-                                      uint8_t& green,
-                                      uint8_t& blue) const
-  {
-    red = backgroundColor_[0];
-    green = backgroundColor_[1];
-    blue = backgroundColor_[2];
-  }
-
-
-  bool WidgetBase::Render(Orthanc::ImageAccessor& surface)
-  {
-#if 0
-    ClearBackgroundOrthanc(surface);
-#else
-    ClearBackgroundCairo(surface);  // Faster than Orthanc
-#endif
-
-    return true;
-  }
-
-  
-  void WidgetBase::DoAnimation()
-  {
-    throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/WidgetBase.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- * 
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "IWidget.h"
-
-#include "../../Wrappers/CairoContext.h"
-#include "../Viewport/WidgetViewport.h"
-
-namespace Deprecated
-{
-  class WidgetBase : public IWidget
-  {
-  private:
-    IWidget*         parent_;
-    WidgetViewport*  viewport_;
-    IStatusBar*      statusBar_;
-    bool             backgroundCleared_;
-    uint8_t          backgroundColor_[3];
-    bool             transmitMouseOver_;
-    std::string      name_;
-
-  protected:
-    void ClearBackgroundOrthanc(Orthanc::ImageAccessor& target) const;
-
-    void ClearBackgroundCairo(OrthancStone::CairoContext& context) const;
-
-    void ClearBackgroundCairo(Orthanc::ImageAccessor& target) const;
-
-    void UpdateStatusBar(const std::string& message);
-
-    IStatusBar* GetStatusBar() const
-    {
-      return statusBar_;
-    }
-
-  public:
-    WidgetBase(const std::string& name);
-
-    virtual void FitContent()
-    {
-    }
-  
-    virtual void SetParent(IWidget& parent);
-    
-    virtual void SetViewport(WidgetViewport& viewport);
-
-    void SetBackgroundCleared(bool clear)
-    {
-      backgroundCleared_ = clear;
-    }
-
-    bool IsBackgroundCleared() const
-    {
-      return backgroundCleared_;
-    }
-
-    void SetTransmitMouseOver(bool transmit)
-    {
-      transmitMouseOver_ = transmit;
-    }
-
-    void SetBackgroundColor(uint8_t red,
-                            uint8_t green,
-                            uint8_t blue);
-
-    void GetBackgroundColor(uint8_t& red,
-                            uint8_t& green,
-                            uint8_t& blue) const;
-
-    virtual void SetStatusBar(IStatusBar& statusBar)
-    {
-      statusBar_ = &statusBar;
-    }
-
-    virtual bool Render(Orthanc::ImageAccessor& surface);
-
-    virtual bool HasAnimation() const
-    {
-      return false;
-    }
-
-    virtual void DoAnimation();
-
-    virtual bool HasRenderMouseOver()
-    {
-      return transmitMouseOver_;
-    }
-
-    virtual void NotifyContentChanged();
-
-    const std::string& GetName() const
-    {
-      return name_;
-    }
-
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/WorldSceneWidget.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,229 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "WorldSceneWidget.h"
-
-#include "PanMouseTracker.h"
-#include "ZoomMouseTracker.h"
-#include "PanZoomMouseTracker.h"
-
-#include <Logging.h>
-#include <OrthancException.h>
-
-#include <math.h>
-#include <memory>
-#include <cassert>
-
-namespace Deprecated
-{
-  // this is an adapter between a IWorldSceneMouseTracker
-  // that is tracking a mouse in scene coordinates/mm and
-  // an IMouseTracker that is tracking a mouse
-  // in screen coordinates/pixels.
-  class WorldSceneWidget::SceneMouseTracker : public IMouseTracker
-  {
-  private:
-    ViewportGeometry                        view_;
-    std::unique_ptr<IWorldSceneMouseTracker>  tracker_;
-
-  public:
-    SceneMouseTracker(const ViewportGeometry& view,
-                      IWorldSceneMouseTracker* tracker) :
-      view_(view),
-      tracker_(tracker)
-    {
-      if (tracker == NULL)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer);
-      }
-    }
-
-    virtual void Render(Orthanc::ImageAccessor& target)
-    {
-      if (tracker_->HasRender())
-      {
-        OrthancStone::CairoSurface surface(target, false /* no alpha */);
-        OrthancStone::CairoContext context(surface);
-        view_.ApplyTransform(context);
-        tracker_->Render(context, view_.GetZoom());
-      }
-    }
-
-    virtual void MouseUp()
-    {
-      tracker_->MouseUp();
-    }
-
-    virtual void MouseMove(int x,
-                           int y,
-                           const std::vector<Touch>& displayTouches)
-    {
-      double sceneX, sceneY;
-      view_.MapPixelCenterToScene(sceneX, sceneY, x, y);
-
-      std::vector<Touch> sceneTouches;
-      for (size_t t = 0; t < displayTouches.size(); t++)
-      {
-        double sx, sy;
-        
-        view_.MapPixelCenterToScene(
-          sx, sy, (int)displayTouches[t].x, (int)displayTouches[t].y);
-        
-        sceneTouches.push_back(
-          Touch(static_cast<float>(sx), static_cast<float>(sy)));
-      }
-      tracker_->MouseMove(x, y, sceneX, sceneY, displayTouches, sceneTouches);
-    }
-  };
-
-
-  bool WorldSceneWidget::RenderCairo(OrthancStone::CairoContext& context)
-  {
-    view_.ApplyTransform(context);
-    return RenderScene(context, view_);
-  }
-
-
-  void WorldSceneWidget::RenderMouseOverCairo(OrthancStone::CairoContext& context,
-                                              int x,
-                                              int y)
-  {
-    ViewportGeometry view = GetView();
-    view.ApplyTransform(context);
-
-    double sceneX, sceneY;
-    view.MapPixelCenterToScene(sceneX, sceneY, x, y);
-
-    if (interactor_)
-    {
-      interactor_->MouseOver(context, *this, view, sceneX, sceneY, GetStatusBar());
-    }
-  }
-
-
-  void WorldSceneWidget::SetSceneExtent(ViewportGeometry& view)
-  {
-    view.SetSceneExtent(GetSceneExtent());
-  }
-
-
-  void WorldSceneWidget::SetSize(unsigned int width,
-                                 unsigned int height)
-  {
-    CairoWidget::SetSize(width, height);
-    view_.SetDisplaySize(width, height);
-  }
-
-
-  void WorldSceneWidget::SetInteractor(IWorldSceneInteractor& interactor)
-  {
-    interactor_ = &interactor;
-  }
-
-
-  void WorldSceneWidget::FitContent()
-  {
-    SetSceneExtent(view_);
-    view_.FitContent();
-
-    NotifyContentChanged();
-  }
-
-
-  void WorldSceneWidget::SetView(const ViewportGeometry& view)
-  {
-    view_ = view;
-
-    NotifyContentChanged();
-  }
-
-
-  IMouseTracker* WorldSceneWidget::CreateMouseTracker(OrthancStone::MouseButton button,
-                                                      int x,
-                                                      int y,
-                                                      OrthancStone::KeyboardModifiers modifiers,
-                                                      const std::vector<Touch>& touches)
-  {
-    double sceneX, sceneY;
-    view_.MapPixelCenterToScene(sceneX, sceneY, x, y);
-
-    // asks the Widget Interactor to provide a mouse tracker
-    std::unique_ptr<IWorldSceneMouseTracker> tracker;
-
-    if (interactor_)
-    {
-      tracker.reset(interactor_->CreateMouseTracker(*this, view_, button, modifiers, x, y, sceneX, sceneY, GetStatusBar(), touches));
-    }
-    
-    if (tracker.get() != NULL)
-    {
-      return new SceneMouseTracker(view_, tracker.release());
-    }
-    else if (hasDefaultMouseEvents_)
-    {
-      if (touches.size() == 2)
-      {
-        return new SceneMouseTracker(view_, new PanZoomMouseTracker(*this, touches));
-      }
-      else
-      {
-        switch (button)
-        {
-          case OrthancStone::MouseButton_Middle:
-            return new SceneMouseTracker(view_, new PanMouseTracker(*this, x, y));
-
-          case OrthancStone::MouseButton_Right:
-            return new SceneMouseTracker(view_, new ZoomMouseTracker(*this, x, y));
-
-          default:
-            return NULL;
-        }
-      }
-    }
-    else
-    {
-      return NULL;
-    }
-  }
-
-
-  void WorldSceneWidget::MouseWheel(OrthancStone::MouseWheelDirection direction,
-                                    int x,
-                                    int y,
-                                    OrthancStone::KeyboardModifiers modifiers)
-  {
-    if (interactor_)
-    {
-      interactor_->MouseWheel(*this, direction, modifiers, GetStatusBar());
-    }
-  }
-
-
-  void WorldSceneWidget::KeyPressed(OrthancStone::KeyboardKeys key,
-                                    char keyChar,
-                                    OrthancStone::KeyboardModifiers modifiers)
-  {
-    if (interactor_)
-    {
-      interactor_->KeyPressed(*this, key, keyChar, modifiers, GetStatusBar());
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/WorldSceneWidget.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "CairoWidget.h"
-#include "IWorldSceneInteractor.h"
-
-#include "../Toolbox/ViewportGeometry.h"
-
-namespace Deprecated
-{
-  class WorldSceneWidget : public CairoWidget
-  {
-  private:
-    class SceneMouseTracker;
-
-    ViewportGeometry       view_;
-    IWorldSceneInteractor* interactor_;
-    bool                   hasDefaultMouseEvents_;
-
-  protected:
-    virtual OrthancStone::Extent2D GetSceneExtent() = 0;
-
-    virtual bool RenderScene(OrthancStone::CairoContext& context,
-                             const ViewportGeometry& view) = 0;
-
-    // From CairoWidget
-    virtual bool RenderCairo(OrthancStone::CairoContext& context);
-
-    // From CairoWidget
-    virtual void RenderMouseOverCairo(OrthancStone::CairoContext& context,
-                                      int x,
-                                      int y);
-
-    void SetSceneExtent(ViewportGeometry& geometry);
-
-  public:
-    WorldSceneWidget(const std::string& name) :
-      CairoWidget(name),
-      interactor_(NULL),
-      hasDefaultMouseEvents_(true)
-    {
-    }
-
-    void SetDefaultMouseEvents(bool value)
-    {
-      hasDefaultMouseEvents_ = value;
-    }
-
-    bool HasDefaultMouseEvents() const
-    {
-      return hasDefaultMouseEvents_;
-    }
-
-    void SetInteractor(IWorldSceneInteractor& interactor);
-
-    void SetView(const ViewportGeometry& view);
-
-    const ViewportGeometry& GetView() const
-    {
-      return view_;
-    }
-
-    virtual void SetSize(unsigned int width,
-                         unsigned int height);
-
-    virtual void FitContent();
-
-    virtual IMouseTracker* CreateMouseTracker(OrthancStone::MouseButton button,
-                                              int x,
-                                              int y,
-                                              OrthancStone::KeyboardModifiers modifiers,
-                                              const std::vector<Touch>& touches);
-
-    virtual void MouseWheel(OrthancStone::MouseWheelDirection direction,
-                            int x,
-                            int y,
-                            OrthancStone::KeyboardModifiers modifiers);
-
-    virtual void KeyPressed(OrthancStone::KeyboardKeys key,
-                            char keyChar,
-                            OrthancStone::KeyboardModifiers modifiers);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/ZoomMouseTracker.cpp	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "ZoomMouseTracker.h"
-
-#include <Logging.h>
-#include <OrthancException.h>
-
-namespace Deprecated
-{
-  ZoomMouseTracker::ZoomMouseTracker(WorldSceneWidget& that,
-                                     int x,
-                                     int y) :
-    that_(that),
-    originalZoom_(that.GetView().GetZoom()),
-    downX_(x),
-    downY_(y)
-  {
-    that.GetView().MapPixelCenterToScene(centerX_, centerY_, x, y);
-
-    unsigned int height = that.GetView().GetDisplayHeight();
-      
-    if (height <= 3)
-    {
-      idle_ = true;
-      LOG(WARNING) << "image is too small to zoom (current height = " << height << ")";
-    }
-    else
-    {
-      idle_ = false;
-      normalization_ = 1.0 / static_cast<double>(height - 1);
-    }
-  }
-    
-
-  void ZoomMouseTracker::Render(OrthancStone::CairoContext& context,
-                                double zoom)
-  {
-    throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-  }
-
-
-  void ZoomMouseTracker::MouseMove(int displayX,
-                                   int displayY,
-                                   double x,
-                                   double y,
-                                   const std::vector<Touch>& displayTouches,
-                                   const std::vector<Touch>& sceneTouches)
-  {
-    static const double MIN_ZOOM = -4;
-    static const double MAX_ZOOM = 4;
-
-      
-    if (!idle_)
-    {
-      double dy = static_cast<double>(displayY - downY_) * normalization_;  // In the range [-1,1]
-      double z;
-
-      // Linear interpolation from [-1, 1] to [MIN_ZOOM, MAX_ZOOM]
-      if (dy < -1.0)
-      {
-        z = MIN_ZOOM;
-      }
-      else if (dy > 1.0)
-      {
-        z = MAX_ZOOM;
-      }
-      else
-      {
-        z = MIN_ZOOM + (MAX_ZOOM - MIN_ZOOM) * (dy + 1.0) / 2.0;
-      }
-
-      z = pow(2.0, z);
-
-      ViewportGeometry view = that_.GetView();
-        
-      view.SetZoom(z * originalZoom_);
-        
-      // Correct the pan so that the original click point is kept at
-      // the same location on the display
-      double panX, panY;
-      view.GetPan(panX, panY);
-
-      int tx, ty;
-      view.MapSceneToDisplay(tx, ty, centerX_, centerY_);
-      view.SetPan(panX + static_cast<double>(downX_ - tx),
-                  panY + static_cast<double>(downY_ - ty));
-        
-      that_.SetView(view);
-    }
-  }
-}
--- a/OrthancStone/Sources/Deprecated/Widgets/ZoomMouseTracker.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "WorldSceneWidget.h"
-
-namespace Deprecated
-{
-  class ZoomMouseTracker : public IWorldSceneMouseTracker
-  {
-  private:
-    WorldSceneWidget&  that_;
-    double             originalZoom_;
-    int                downX_;
-    int                downY_;
-    double             centerX_;
-    double             centerY_;
-    bool               idle_;
-    double             normalization_;
-    
-  public:
-    ZoomMouseTracker(WorldSceneWidget& that,
-                     int x,
-                     int y);
-    
-    virtual bool HasRender() const
-    {
-      return false;
-    }
-
-    virtual void MouseUp()
-    {
-    }
-
-    virtual void Render(OrthancStone::CairoContext& context,
-                        double zoom);
-
-    virtual void MouseMove(int displayX,
-                           int displayY,
-                           double x,
-                           double y,
-                           const std::vector<Touch>& displayTouches,
-                           const std::vector<Touch>& sceneTouches);
-  };
-}
--- a/OrthancStone/Sources/Deprecated/dev.h	Thu Sep 17 15:39:33 2020 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,958 +0,0 @@
-/**
- * Stone of Orthanc
- * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
- * Department, University Hospital of Liege, Belgium
- * Copyright (C) 2017-2020 Osimis S.A., Belgium
- *
- * This program is free software: you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "Layers/FrameRenderer.h"
-#include "Layers/LineLayerRenderer.h"
-#include "Layers/SliceOutlineRenderer.h"
-#include "Toolbox/DownloadStack.h"
-#include "Toolbox/GeometryToolbox.h"
-#include "Toolbox/OrthancSlicesLoader.h"
-#include "Volumes/ISlicedVolume.h"
-#include "Volumes/ImageBuffer3D.h"
-#include "Widgets/SliceViewerWidget.h"
-
-#include <Logging.h>
-#include <Images/ImageProcessing.h>
-#include <OrthancException.h>
-
-#include <boost/math/special_functions/round.hpp>
-
-
-namespace Deprecated
-{
-  // TODO: Handle errors while loading
-  class OrthancVolumeImage :
-    public ISlicedVolume,
-    public OrthancStone::IObserver
-  {
-  private:
-    OrthancSlicesLoader           loader_;
-    std::unique_ptr<OrthancStone::ImageBuffer3D>  image_;
-    std::unique_ptr<DownloadStack>  downloadStack_;
-    bool                          computeRange_;
-    size_t                        pendingSlices_;
-
-    void ScheduleSliceDownload()
-    {
-      assert(downloadStack_.get() != NULL);
-
-      unsigned int slice;
-      if (downloadStack_->Pop(slice))
-      {
-        loader_.ScheduleLoadSliceImage(slice, OrthancStone::SliceImageQuality_Jpeg90);
-      }
-    }
-
-
-    static bool IsCompatible(const Slice& a,
-                             const Slice& b)
-    {
-      if (!OrthancStone::GeometryToolbox::IsParallel(a.GetGeometry().GetNormal(),
-                                                     b.GetGeometry().GetNormal()))
-      {
-        LOG(ERROR) << "A slice in the volume image is not parallel to the others.";
-        return false;
-      }
-
-      if (a.GetConverter().GetExpectedPixelFormat() != b.GetConverter().GetExpectedPixelFormat())
-      {
-        LOG(ERROR) << "The pixel format changes across the slices of the volume image.";
-        return false;
-      }
-
-      if (a.GetWidth() != b.GetWidth() ||
-          a.GetHeight() != b.GetHeight())
-      {
-        LOG(ERROR) << "The slices dimensions (width/height) are varying throughout the volume image";
-        return false;
-      }
-
-      if (!OrthancStone::LinearAlgebra::IsNear(a.GetPixelSpacingX(), b.GetPixelSpacingX()) ||
-          !OrthancStone::LinearAlgebra::IsNear(a.GetPixelSpacingY(), b.GetPixelSpacingY()))
-      {
-        LOG(ERROR) << "The pixel spacing of the slices change across the volume image";
-        return false;
-      }
-
-      return true;
-    }
-
-
-    static double GetDistance(const Slice& a,
-                              const Slice& b)
-    {
-      return fabs(a.GetGeometry().ProjectAlongNormal(a.GetGeometry().GetOrigin()) -
-                  a.GetGeometry().ProjectAlongNormal(b.GetGeometry().GetOrigin()));
-    }
-
-
-    void OnSliceGeometryReady(const OrthancSlicesLoader::SliceGeometryReadyMessage& message)
-    {
-      assert(&message.GetOrigin() == &loader_);
-
-      if (loader_.GetSlicesCount() == 0)
-      {
-        LOG(ERROR) << "Empty volume image";
-        BroadcastMessage(ISlicedVolume::GeometryErrorMessage(*this));
-        return;
-      }
-
-      for (size_t i = 1; i < loader_.GetSlicesCount(); i++)
-      {
-        if (!IsCompatible(loader_.GetSlice(0), loader_.GetSlice(i)))
-        {
-          BroadcastMessage(ISlicedVolume::GeometryErrorMessage(*this));
-          return;
-        }
-      }
-
-      double spacingZ;
-
-      if (loader_.GetSlicesCount() > 1)
-      {
-        spacingZ = GetDistance(loader_.GetSlice(0), loader_.GetSlice(1));
-      }
-      else
-      {
-        // This is a volume with one single slice: Choose a dummy
-        // z-dimension for voxels
-        spacingZ = 1;
-      }
-
-      for (size_t i = 1; i < loader_.GetSlicesCount(); i++)
-      {
-        if (!OrthancStone::LinearAlgebra::IsNear(spacingZ, GetDistance(loader_.GetSlice(i - 1), loader_.GetSlice(i)),
-                                                 0.001 /* this is expressed in mm */))
-        {
-          LOG(ERROR) << "The distance between successive slices is not constant in a volume image";
-          BroadcastMessage(ISlicedVolume::GeometryErrorMessage(*this));
-          return;
-        }
-      }
-
-      unsigned int width = loader_.GetSlice(0).GetWidth();
-      unsigned int height = loader_.GetSlice(0).GetHeight();
-      Orthanc::PixelFormat format = loader_.GetSlice(0).GetConverter().GetExpectedPixelFormat();
-      LOG(INFO) << "Creating a volume image of size " << width << "x" << height
-                << "x" << loader_.GetSlicesCount() << " in " << Orthanc::EnumerationToString(format);
-
-      image_.reset(new OrthancStone::ImageBuffer3D(format, width, height, static_cast<unsigned int>(loader_.GetSlicesCount()), computeRange_));
-      image_->GetGeometry().SetAxialGeometry(loader_.GetSlice(0).GetGeometry());
-      image_->GetGeometry().SetVoxelDimensions(loader_.GetSlice(0).GetPixelSpacingX(),
-                                               loader_.GetSlice(0).GetPixelSpacingY(), spacingZ);
-      image_->Clear();
-
-      downloadStack_.reset(new DownloadStack(static_cast<unsigned int>(loader_.GetSlicesCount())));
-      pendingSlices_ = loader_.GetSlicesCount();
-
-      for (unsigned int i = 0; i < 4; i++)  // Limit to 4 simultaneous downloads
-      {
-        ScheduleSliceDownload();
-      }
-
-      // TODO Check the DicomFrameConverter are constant
-
-      BroadcastMessage(ISlicedVolume::GeometryReadyMessage(*this));
-    }
-
-
-    void OnSliceGeometryError(const OrthancSlicesLoader::SliceGeometryErrorMessage& message)
-    {
-      assert(&message.GetOrigin() == &loader_);
-
-      LOG(ERROR) << "Unable to download a volume image";
-      BroadcastMessage(ISlicedVolume::GeometryErrorMessage(*this));
-    }
-
-
-    void OnSliceImageReady(const OrthancSlicesLoader::SliceImageReadyMessage& message)
-    {
-      assert(&message.GetOrigin() == &loader_);
-
-      {
-        OrthancStone::ImageBuffer3D::SliceWriter writer(*image_, OrthancStone::VolumeProjection_Axial, message.GetSliceIndex());
-        Orthanc::ImageProcessing::Copy(writer.GetAccessor(), message.GetImage());
-      }
-
-      BroadcastMessage(ISlicedVolume::SliceContentChangedMessage
-                       (*this, message.GetSliceIndex(), message.GetSlice()));
-
-      if (pendingSlices_ == 1)
-      {
-        BroadcastMessage(ISlicedVolume::VolumeReadyMessage(*this));
-        pendingSlices_ = 0;
-      }
-      else if (pendingSlices_ > 1)
-      {
-        pendingSlices_ -= 1;
-      }
-
-      ScheduleSliceDownload();
-    }
-
-
-    void OnSliceImageError(const OrthancSlicesLoader::SliceImageErrorMessage& message)
-    {
-      assert(&message.GetOrigin() == &loader_);
-
-      LOG(ERROR) << "Cannot download slice " << message.GetSliceIndex() << " in a volume image";
-      ScheduleSliceDownload();
-    }
-
-
-  public:
-    OrthancVolumeImage(OrthancStone::MessageBroker& broker,
-                       OrthancApiClient& orthanc,
-                       bool computeRange) :
-      ISlicedVolume(broker),
-      IObserver(broker),
-      loader_(broker, orthanc),
-      computeRange_(computeRange),
-      pendingSlices_(0)
-    {
-      loader_.RegisterObserverCallback(
-        new OrthancStone::Callable<OrthancVolumeImage, OrthancSlicesLoader::SliceGeometryReadyMessage>
-        (*this, &OrthancVolumeImage::OnSliceGeometryReady));
-
-      loader_.RegisterObserverCallback(
-        new OrthancStone::Callable<OrthancVolumeImage, OrthancSlicesLoader::SliceGeometryErrorMessage>
-        (*this, &OrthancVolumeImage::OnSliceGeometryError));
-
-      loader_.RegisterObserverCallback(
-        new OrthancStone::Callable<OrthancVolumeImage, OrthancSlicesLoader::SliceImageReadyMessage>
-        (*this, &OrthancVolumeImage::OnSliceImageReady));
-
-      loader_.RegisterObserverCallback(
-        new OrthancStone::Callable<OrthancVolumeImage, OrthancSlicesLoader::SliceImageErrorMessage>
-        (*this, &OrthancVolumeImage::OnSliceImageError));
-    }
-
-    void ScheduleLoadSeries(const std::string& seriesId)
-    {
-      loader_.ScheduleLoadSeries(seriesId);
-    }
-
-    void ScheduleLoadInstance(const std::string& instanceId)
-    {
-      loader_.ScheduleLoadInstance(instanceId);
-    }
-
-    void ScheduleLoadFrame(const std::string& instanceId,
-                           unsigned int frame)
-    {
-      loader_.ScheduleLoadFrame(instanceId, frame);
-    }
-
-    virtual size_t GetSlicesCount() const
-    {
-      return loader_.GetSlicesCount();
-    }
-
-    virtual const Slice& GetSlice(size_t index) const
-    {
-      return loader_.GetSlice(index);
-    }
-
-    OrthancStone::ImageBuffer3D& GetImage() const
-    {
-      if (image_.get() == NULL)
-      {
-        // The geometry is not ready yet
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-      }
-      else
-      {
-        return *image_;
-      }
-    }
-
-    bool FitWindowingToRange(RenderStyle& style,
-                             const DicomFrameConverter& converter) const
-    {
-      if (image_.get() == NULL)
-      {
-        return false;
-      }
-      else
-      {
-        return image_->FitWindowingToRange(style, converter);
-      }
-    }
-  };
-
-
-  class VolumeImageGeometry
-  {
-  private:
-    unsigned int         width_;
-    unsigned int         height_;
-    size_t               depth_;
-    double               pixelSpacingX_;
-    double               pixelSpacingY_;
-    double               sliceThickness_;
-    OrthancStone::CoordinateSystem3D   reference_;
-    DicomFrameConverter  converter_;
-
-    double ComputeAxialThickness(const OrthancVolumeImage& volume) const
-    {
-      double thickness;
-
-      size_t n = volume.GetSlicesCount();
-      if (n > 1)
-      {
-        const Slice& a = volume.GetSlice(0);
-        const Slice& b = volume.GetSlice(n - 1);
-        thickness = ((reference_.ProjectAlongNormal(b.GetGeometry().GetOrigin()) -
-                      reference_.ProjectAlongNormal(a.GetGeometry().GetOrigin())) /
-                     (static_cast<double>(n) - 1.0));
-      }
-      else
-      {
-        thickness = volume.GetSlice(0).GetThickness();
-      }
-
-      if (thickness <= 0)
-      {
-        // The slices should have been sorted with increasing Z
-        // (along the normal) by the OrthancSlicesLoader
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
-      }
-      else
-      {
-        return thickness;
-      }
-    }
-
-    void SetupAxial(const OrthancVolumeImage& volume)
-    {
-      const Slice& axial = volume.GetSlice(0);
-
-      width_ = axial.GetWidth();
-      height_ = axial.GetHeight();
-      depth_ = volume.GetSlicesCount();
-
-      pixelSpacingX_ = axial.GetPixelSpacingX();
-      pixelSpacingY_ = axial.GetPixelSpacingY();
-      sliceThickness_ = ComputeAxialThickness(volume);
-
-      reference_ = axial.GetGeometry();
-    }
-
-    void SetupCoronal(const OrthancVolumeImage& volume)
-    {
-      const Slice& axial = volume.GetSlice(0);
-      double axialThickness = ComputeAxialThickness(volume);
-
-      width_ = axial.GetWidth();
-      height_ = static_cast<unsigned int>(volume.GetSlicesCount());
-      depth_ = axial.GetHeight();
-
-      pixelSpacingX_ = axial.GetPixelSpacingX();
-      pixelSpacingY_ = axialThickness;
-      sliceThickness_ = axial.GetPixelSpacingY();
-
-      OrthancStone::Vector origin = axial.GetGeometry().GetOrigin();
-      origin += (static_cast<double>(volume.GetSlicesCount() - 1) *
-                 axialThickness * axial.GetGeometry().GetNormal());
-
-      reference_ = OrthancStone::CoordinateSystem3D(origin,
-                                                    axial.GetGeometry().GetAxisX(),
-                                                    - axial.GetGeometry().GetNormal());
-    }
-
-    void SetupSagittal(const OrthancVolumeImage& volume)
-    {
-      const Slice& axial = volume.GetSlice(0);
-      double axialThickness = ComputeAxialThickness(volume);
-
-      width_ = axial.GetHeight();
-      height_ = static_cast<unsigned int>(volume.GetSlicesCount());
-      depth_ = axial.GetWidth();
-
-      pixelSpacingX_ = axial.GetPixelSpacingY();
-      pixelSpacingY_ = axialThickness;
-      sliceThickness_ = axial.GetPixelSpacingX();
-
-      OrthancStone::Vector origin = axial.GetGeometry().GetOrigin();
-      origin += (static_cast<double>(volume.GetSlicesCount() - 1) *
-                 axialThickness * axial.GetGeometry().GetNormal());
-
-      reference_ = OrthancStone::CoordinateSystem3D(origin,
-                                                    axial.GetGeometry().GetAxisY(),
-                                                    axial.GetGeometry().GetNormal());
-    }
-
-  public:
-    VolumeImageGeometry(const OrthancVolumeImage& volume,
-                        OrthancStone::VolumeProjection projection)
-    {
-      if (volume.GetSlicesCount() == 0)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-      }
-
-      converter_ = volume.GetSlice(0).GetConverter();
-
-      switch (projection)
-      {
-        case OrthancStone::VolumeProjection_Axial:
-          SetupAxial(volume);
-          break;
-
-        case OrthancStone::VolumeProjection_Coronal:
-          SetupCoronal(volume);
-          break;
-
-        case OrthancStone::VolumeProjection_Sagittal:
-          SetupSagittal(volume);
-          break;
-
-        default:
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-      }
-    }
-
-    size_t GetSlicesCount() const
-    {
-      return depth_;
-    }
-
-    const OrthancStone::Vector& GetNormal() const
-    {
-      return reference_.GetNormal();
-    }
-
-    bool LookupSlice(size_t& index,
-                     const OrthancStone::CoordinateSystem3D& slice) const
-    {
-      bool opposite;
-      if (!OrthancStone::GeometryToolbox::IsParallelOrOpposite(opposite,
-                                                               reference_.GetNormal(),
-                                                               slice.GetNormal()))
-      {
-        return false;
-      }
-
-      double z = (reference_.ProjectAlongNormal(slice.GetOrigin()) -
-                  reference_.ProjectAlongNormal(reference_.GetOrigin())) / sliceThickness_;
-
-      int s = static_cast<int>(boost::math::iround(z));
-
-      if (s < 0 ||
-          s >= static_cast<int>(depth_))
-      {
-        return false;
-      }
-      else
-      {
-        index = static_cast<size_t>(s);
-        return true;
-      }
-    }
-
-    Slice* GetSlice(size_t slice) const
-    {
-      if (slice >= depth_)
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
-      }
-      else
-      {
-        OrthancStone::CoordinateSystem3D origin(reference_.GetOrigin() +
-                                                static_cast<double>(slice) * sliceThickness_ * reference_.GetNormal(),
-                                                reference_.GetAxisX(),
-                                                reference_.GetAxisY());
-
-        return new Slice(origin, pixelSpacingX_, pixelSpacingY_, sliceThickness_,
-                         width_, height_, converter_);
-      }
-    }
-  };
-
-
-
-  class VolumeImageMPRSlicer :
-    public IVolumeSlicer,
-    public OrthancStone::IObserver
-  {
-  private:
-    class RendererFactory : public LayerReadyMessage::IRendererFactory
-    {
-    private:
-      const Orthanc::ImageAccessor&  frame_;
-      const Slice&                   slice_;
-      bool                           isFullQuality_;
-
-    public:
-      RendererFactory(const Orthanc::ImageAccessor& frame,
-                      const Slice& slice,
-                      bool isFullQuality) :
-        frame_(frame),
-        slice_(slice),
-        isFullQuality_(isFullQuality)
-      {
-      }
-
-      virtual ILayerRenderer* CreateRenderer() const
-      {
-        return FrameRenderer::CreateRenderer(frame_, slice_, isFullQuality_);
-      }
-    };
-
-
-    OrthancVolumeImage&                 volume_;
-    std::unique_ptr<VolumeImageGeometry>  axialGeometry_;
-    std::unique_ptr<VolumeImageGeometry>  coronalGeometry_;
-    std::unique_ptr<VolumeImageGeometry>  sagittalGeometry_;
-
-
-    bool IsGeometryReady() const
-    {
-      return axialGeometry_.get() != NULL;
-    }
-
-    void OnGeometryReady(const ISlicedVolume::GeometryReadyMessage& message)
-    {
-      assert(&message.GetOrigin() == &volume_);
-
-      // These 3 values are only used to speed up the IVolumeSlicer
-      axialGeometry_.reset(new VolumeImageGeometry(volume_, OrthancStone::VolumeProjection_Axial));
-      coronalGeometry_.reset(new VolumeImageGeometry(volume_, OrthancStone::VolumeProjection_Coronal));
-      sagittalGeometry_.reset(new VolumeImageGeometry(volume_, OrthancStone::VolumeProjection_Sagittal));
-
-      BroadcastMessage(IVolumeSlicer::GeometryReadyMessage(*this));
-    }
-
-    void OnGeometryError(const ISlicedVolume::GeometryErrorMessage& message)
-    {
-      assert(&message.GetOrigin() == &volume_);
-
-      BroadcastMessage(IVolumeSlicer::GeometryErrorMessage(*this));
-    }
-
-    void OnContentChanged(const ISlicedVolume::ContentChangedMessage& message)
-    {
-      assert(&message.GetOrigin() == &volume_);
-
-      BroadcastMessage(IVolumeSlicer::ContentChangedMessage(*this));
-    }
-
-    void OnSliceContentChanged(const ISlicedVolume::SliceContentChangedMessage& message)
-    {
-      assert(&message.GetOrigin() == &volume_);
-
-      //IVolumeSlicer::OnSliceContentChange(slice);
-
-      // TODO Improve this?
-      BroadcastMessage(IVolumeSlicer::ContentChangedMessage(*this));
-    }
-
-    const VolumeImageGeometry& GetProjectionGeometry(OrthancStone::VolumeProjection projection)
-    {
-      if (!IsGeometryReady())
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
-      }
-
-      switch (projection)
-      {
-        case OrthancStone::VolumeProjection_Axial:
-          return *axialGeometry_;
-
-        case OrthancStone::VolumeProjection_Sagittal:
-          return *sagittalGeometry_;
-
-        case OrthancStone::VolumeProjection_Coronal:
-          return *coronalGeometry_;
-
-        default:
-          throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
-      }
-    }
-
-
-    bool DetectProjection(OrthancStone::VolumeProjection& projection,
-                          const OrthancStone::CoordinateSystem3D& viewportSlice)
-    {
-      bool isOpposite;  // Ignored
-
-      if (OrthancStone::GeometryToolbox::IsParallelOrOpposite(isOpposite,
-                                                              viewportSlice.GetNormal(),
-                                                              axialGeometry_->GetNormal()))
-      {
-        projection = OrthancStone::VolumeProjection_Axial;
-        return true;
-      }
-      else if (OrthancStone::GeometryToolbox::IsParallelOrOpposite(isOpposite,
-                                                                   viewportSlice.GetNormal(),
-                                                                   sagittalGeometry_->GetNormal()))
-      {
-        projection = OrthancStone::VolumeProjection_Sagittal;
-        return true;
-      }
-      else if (OrthancStone::GeometryToolbox::IsParallelOrOpposite(isOpposite,
-                                                                   viewportSlice.GetNormal(),
-                                                                   coronalGeometry_->GetNormal()))
-      {
-        projection = OrthancStone::VolumeProjection_Coronal;
-        return true;
-      }
-      else
-      {
-        return false;
-      }
-    }
-
-
-  public:
-    VolumeImageMPRSlicer(OrthancStone::MessageBroker& broker,
-                         OrthancVolumeImage&  volume) :
-      IVolumeSlicer(broker),
-      IObserver(broker),
-      volume_(volume)
-    {
-      volume_.RegisterObserverCallback(
-        new OrthancStone::Callable<VolumeImageMPRSlicer, ISlicedVolume::GeometryReadyMessage>
-        (*this, &VolumeImageMPRSlicer::OnGeometryReady));
-
-      volume_.RegisterObserverCallback(
-        new OrthancStone::Callable<VolumeImageMPRSlicer, ISlicedVolume::GeometryErrorMessage>
-        (*this, &VolumeImageMPRSlicer::OnGeometryError));
-
-      volume_.RegisterObserverCallback(
-        new OrthancStone::Callable<VolumeImageMPRSlicer, ISlicedVolume::ContentChangedMessage>
-        (*this, &VolumeImageMPRSlicer::OnContentChanged));
-
-      volume_.RegisterObserverCallback(
-        new OrthancStone::Callable<VolumeImageMPRSlicer, ISlicedVolume::SliceContentChangedMessage>
-        (*this, &VolumeImageMPRSlicer::OnSliceContentChanged));
-    }
-
-    virtual bool GetExtent(std::vector<OrthancStone::Vector>& points,
-                           const OrthancStone::CoordinateSystem3D& viewportSlice) ORTHANC_OVERRIDE
-    {
-      OrthancStone::VolumeProjection projection;
-
-      if (!IsGeometryReady() ||
-          !DetectProjection(projection, viewportSlice))
-      {
-        return false;
-      }
-      else
-      {
-        // As the slices of the volumic image are arranged in a box,
-        // we only consider one single reference slice (the one with index 0).
-        std::unique_ptr<Slice> slice(GetProjectionGeometry(projection).GetSlice(0));
-        slice->GetExtent(points);
-
-        return true;
-      }
-    }
-
-    virtual void ScheduleLayerCreation(const OrthancStone::CoordinateSystem3D& viewportSlice) ORTHANC_OVERRIDE
-    {
-      OrthancStone::VolumeProjection projection;
-
-      if (IsGeometryReady() &&
-          DetectProjection(projection, viewportSlice))
-      {
-        const VolumeImageGeometry& geometry = GetProjectionGeometry(projection);
-
-        size_t closest;
-
-        if (geometry.LookupSlice(closest, viewportSlice))
-        {
-          bool isFullQuality = true;  // TODO
-
-          std::unique_ptr<Orthanc::Image> frame;
-
-          {
-            OrthancStone::ImageBuffer3D::SliceReader reader(volume_.GetImage(), projection, static_cast<unsigned int>(closest));
-
-            // TODO Transfer ownership if non-axial, to avoid memcpy
-            frame.reset(Orthanc::Image::Clone(reader.GetAccessor()));
-          }
-
-          std::unique_ptr<Slice> slice(geometry.GetSlice(closest));
-
-          RendererFactory factory(*frame, *slice, isFullQuality);
-
-          BroadcastMessage(IVolumeSlicer::LayerReadyMessage(*this, factory, slice->GetGeometry()));
-          return;
-        }
-      }
-
-      // Error
-      OrthancStone::CoordinateSystem3D slice;
-      BroadcastMessage(IVolumeSlicer::LayerErrorMessage(*this, slice));
-    }
-  };
-
-
-  class VolumeImageInteractor :
-    public IWorldSceneInteractor,
-    public OrthancStone::IObserver
-  {
-  private:
-    SliceViewerWidget&                  widget_;
-    OrthancStone::VolumeProjection      projection_;
-    std::unique_ptr<VolumeImageGeometry>  slices_;
-    size_t                              slice_;
-
-  protected:
-    void OnGeometryReady(const ISlicedVolume::GeometryReadyMessage& message)
-    {
-      if (slices_.get() == NULL)
-      {
-        const OrthancVolumeImage& image =
-          dynamic_cast<const OrthancVolumeImage&>(message.GetOrigin());
-
-        slices_.reset(new VolumeImageGeometry(image, projection_));
-        SetSlice(slices_->GetSlicesCount() / 2);
-
-        widget_.FitContent();
-      }
-    }
-
-    virtual IWorldSceneMouseTracker* CreateMouseTracker(WorldSceneWidget& widget,
-                                                        const ViewportGeometry& view,
-                                                        OrthancStone::MouseButton button,
-                                                        OrthancStone::KeyboardModifiers modifiers,
-                                                        int viewportX,
-                                                        int viewportY,
-                                                        double x,
-                                                        double y,
-                                                        IStatusBar* statusBar,
-                                                        const std::vector<Touch>& touches) ORTHANC_OVERRIDE
-    {
-      return  NULL;
-    }
-
-    virtual void MouseOver(OrthancStone::CairoContext& context,
-                           WorldSceneWidget& widget,
-                           const ViewportGeometry& view,
-                           double x,
-                           double y,
-                           IStatusBar* statusBar) ORTHANC_OVERRIDE
-    {
-    }
-
-    virtual void MouseWheel(WorldSceneWidget& widget,
-                            OrthancStone::MouseWheelDirection direction,
-                            OrthancStone::KeyboardModifiers modifiers,
-                            IStatusBar* statusBar) ORTHANC_OVERRIDE
-    {
-      int scale = (modifiers & OrthancStone::KeyboardModifiers_Control ? 10 : 1);
-
-      switch (direction)
-      {
-        case OrthancStone::MouseWheelDirection_Up:
-          OffsetSlice(-scale);
-          break;
-
-        case OrthancStone::MouseWheelDirection_Down:
-          OffsetSlice(scale);
-          break;
-
-        default:
-          break;
-      }
-    }
-
-    virtual void KeyPressed(WorldSceneWidget& widget,
-                            OrthancStone::KeyboardKeys key,
-                            char keyChar,
-                            OrthancStone::KeyboardModifiers modifiers,
-                            IStatusBar* statusBar) ORTHANC_OVERRIDE
-    {
-      switch (keyChar)
-      {
-        case 's':
-          widget.FitContent();
-          break;
-
-        default:
-          break;
-      }
-    }
-
-  public:
-    VolumeImageInteractor(OrthancStone::MessageBroker& broker,
-                          OrthancVolumeImage& volume,
-                          SliceViewerWidget& widget,
-                          OrthancStone::VolumeProjection projection) :
-      IObserver(broker),
-      widget_(widget),
-      projection_(projection)
-    {
-      widget.SetInteractor(*this);
-
-      volume.RegisterObserverCallback(
-        new OrthancStone::Callable<VolumeImageInteractor, ISlicedVolume::GeometryReadyMessage>
-        (*this, &VolumeImageInteractor::OnGeometryReady));
-    }
-
-    bool IsGeometryReady() const
-    {
-      return slices_.get() != NULL;
-    }
-
-    size_t GetSlicesCount() const
-    {
-      if (slices_.get() == NULL)
-      {
-        return 0;
-      }
-      else
-      {
-        return slices_->GetSlicesCount();
-      }
-    }
-
-    void OffsetSlice(int offset)
-    {
-      if (slices_.get() != NULL)
-      {
-        int slice = static_cast<int>(slice_) + offset;
-
-        if (slice < 0)
-        {
-          slice = 0;
-        }
-
-        if (slice >= static_cast<int>(slices_->GetSlicesCount()))
-        {
-          slice = static_cast<unsigned int>(slices_->GetSlicesCount()) - 1;
-        }
-
-        if (slice != static_cast<int>(slice_))
-        {
-          SetSlice(slice);
-        }
-      }
-    }
-
-    void SetSlice(size_t slice)
-    {
-      if (slices_.get() != NULL)
-      {
-        slice_ = slice;
-
-        std::unique_ptr<Slice> tmp(slices_->GetSlice(slice_));
-        widget_.SetSlice(tmp->GetGeometry());
-      }
-    }
-  };
-
-
-
-  class ReferenceLineSource : public IVolumeSlicer
-  {
-  private:
-    class RendererFactory : public LayerReadyMessage::IRendererFactory
-    {
-    private:
-      double                     x1_;
-      double                     y1_;
-      double                     x2_;
-      double                     y2_;
-      const OrthancStone::CoordinateSystem3D&  slice_;
-
-    public:
-      RendererFactory(double x1,
-                      double y1,
-                      double x2,
-                      double y2,
-                      const OrthancStone::CoordinateSystem3D& slice) :
-        x1_(x1),
-        y1_(y1),
-        x2_(x2),
-        y2_(y2),
-        slice_(slice)
-      {
-      }
-
-      virtual ILayerRenderer* CreateRenderer() const
-      {
-        return new LineLayerRenderer(x1_, y1_, x2_, y2_, slice_);
-      }
-    };
-
-    SliceViewerWidget&  otherPlane_;
-
-  public:
-    ReferenceLineSource(OrthancStone::MessageBroker& broker,
-                        SliceViewerWidget&  otherPlane) :
-      IVolumeSlicer(broker),
-      otherPlane_(otherPlane)
-    {
-      BroadcastMessage(IVolumeSlicer::GeometryReadyMessage(*this));
-    }
-
-    virtual bool GetExtent(std::vector<OrthancStone::Vector>& points,
-                           const OrthancStone::CoordinateSystem3D& viewportSlice)
-    {
-      return false;
-    }
-
-    virtual void ScheduleLayerCreation(const OrthancStone::CoordinateSystem3D& viewportSlice)
-    {
-      Slice reference(viewportSlice, 0.001);
-
-      OrthancStone::Vector p, d;
-
-      const OrthancStone::CoordinateSystem3D& slice = otherPlane_.GetSlice();
-
-      // Compute the line of intersection between the two slices
-      if (!OrthancStone::GeometryToolbox::IntersectTwoPlanes(p, d,
-                                                             slice.GetOrigin(), slice.GetNormal(),
-                                                             viewportSlice.GetOrigin(), viewportSlice.GetNormal()))
-      {
-        // The two slice are parallel, don't try and display the intersection
-        BroadcastMessage(IVolumeSlicer::LayerErrorMessage(*this, reference.GetGeometry()));
-      }
-      else
-      {
-        double x1, y1, x2, y2;
-        viewportSlice.ProjectPoint(x1, y1, p);
-        viewportSlice.ProjectPoint(x2, y2, p + 1000.0 * d);
-
-        const OrthancStone::Extent2D extent = otherPlane_.GetSceneExtent();
-
-        if (OrthancStone::GeometryToolbox::ClipLineToRectangle(x1, y1, x2, y2,
-                                                               x1, y1, x2, y2,
-                                                               extent.GetX1(), extent.GetY1(),
-                                                               extent.GetX2(), extent.GetY2()))
-        {
-          RendererFactory factory(x1, y1, x2, y2, slice);
-          BroadcastMessage(IVolumeSlicer::LayerReadyMessage(*this, factory, reference.GetGeometry()));
-        }
-        else
-        {
-          // Error: Parallel slices
-          BroadcastMessage(IVolumeSlicer::LayerErrorMessage(*this, reference.GetGeometry()));
-        }
-      }
-    }
-  };
-}