[med-svn] [orthanc] 01/03: New upstream version 1.3.0

Sebastien Jodogne jodogne-guest at moszumanska.debian.org
Thu Jul 20 07:07:04 UTC 2017


This is an automated email from the git hooks/post-receive script.

jodogne-guest pushed a commit to branch master
in repository orthanc.

commit be52ff7920a626956070595ee558fa3d6f7be5fd
Author: jodogne-guest <s.jodogne at gmail.com>
Date:   Thu Jul 20 08:51:30 2017 +0200

    New upstream version 1.3.0
---
 .hg_archival.txt                                   |   9 +-
 .hgignore                                          |   2 +
 .hgtags                                            |   1 +
 .travis.yml                                        |   8 +-
 AUTHORS                                            |  29 +-
 CMakeLists.txt                                     |  11 +-
 Core/Cache/ICachePageProvider.h                    |   1 +
 Core/Cache/LeastRecentlyUsedIndex.h                |   1 +
 Core/Cache/MemoryCache.cpp                         |   1 +
 Core/Cache/MemoryCache.h                           |   1 +
 Core/Cache/SharedArchive.cpp                       |   1 +
 Core/Cache/SharedArchive.h                         |   1 +
 Core/ChunkedBuffer.cpp                             |   1 +
 Core/ChunkedBuffer.h                               |   1 +
 Core/Compression/DeflateBaseCompressor.cpp         |   1 +
 Core/Compression/DeflateBaseCompressor.h           |   1 +
 Core/Compression/GzipCompressor.cpp                |   1 +
 Core/Compression/GzipCompressor.h                  |   1 +
 Core/Compression/HierarchicalZipWriter.cpp         |   1 +
 Core/Compression/HierarchicalZipWriter.h           |   1 +
 Core/Compression/IBufferCompressor.h               |   1 +
 Core/Compression/ZipWriter.cpp                     |   1 +
 Core/Compression/ZipWriter.h                       |   1 +
 Core/Compression/ZlibCompressor.cpp                |   1 +
 Core/Compression/ZlibCompressor.h                  |   1 +
 Core/DicomFormat/DicomArray.cpp                    |   1 +
 Core/DicomFormat/DicomArray.h                      |   1 +
 Core/DicomFormat/DicomElement.h                    |   1 +
 Core/DicomFormat/DicomImageInformation.cpp         |   8 +-
 Core/DicomFormat/DicomImageInformation.h           |   1 +
 Core/DicomFormat/DicomInstanceHasher.cpp           |   1 +
 Core/DicomFormat/DicomInstanceHasher.h             |   1 +
 Core/DicomFormat/DicomIntegerPixelAccessor.cpp     |   8 +
 Core/DicomFormat/DicomIntegerPixelAccessor.h       |   1 +
 Core/DicomFormat/DicomMap.cpp                      |   1 +
 Core/DicomFormat/DicomMap.h                        |   1 +
 Core/DicomFormat/DicomTag.cpp                      |   1 +
 Core/DicomFormat/DicomTag.h                        |   1 +
 Core/DicomFormat/DicomValue.cpp                    |   1 +
 Core/DicomFormat/DicomValue.h                      |   1 +
 Core/Endianness.h                                  |   1 +
 Core/EnumerationDictionary.h                       |   1 +
 Core/Enumerations.cpp                              |  93 ++-
 Core/Enumerations.h                                |   3 +
 Core/FileStorage/FileInfo.h                        |   1 +
 Core/FileStorage/FilesystemStorage.cpp             |   1 +
 Core/FileStorage/FilesystemStorage.h               |   1 +
 Core/FileStorage/IStorageArea.h                    |   1 +
 Core/FileStorage/StorageAccessor.cpp               |   1 +
 Core/FileStorage/StorageAccessor.h                 |   1 +
 Core/HttpClient.cpp                                |   5 +-
 Core/HttpClient.h                                  |   1 +
 Core/HttpServer/BufferHttpSender.cpp               |   1 +
 Core/HttpServer/BufferHttpSender.h                 |   1 +
 Core/HttpServer/EmbeddedResourceHttpHandler.cpp    |   1 +
 Core/HttpServer/EmbeddedResourceHttpHandler.h      |   1 +
 Core/HttpServer/FilesystemHttpHandler.cpp          |   1 +
 Core/HttpServer/FilesystemHttpHandler.h            |   1 +
 Core/HttpServer/FilesystemHttpSender.cpp           |   3 +-
 Core/HttpServer/FilesystemHttpSender.h             |   1 +
 Core/HttpServer/HttpContentNegociation.cpp         |   1 +
 Core/HttpServer/HttpContentNegociation.h           |   1 +
 Core/HttpServer/HttpFileSender.cpp                 |   1 +
 Core/HttpServer/HttpFileSender.h                   |   1 +
 Core/HttpServer/HttpOutput.cpp                     |   1 +
 Core/HttpServer/HttpOutput.h                       |   1 +
 Core/HttpServer/HttpStreamTranscoder.cpp           |   1 +
 Core/HttpServer/HttpStreamTranscoder.h             |   1 +
 Core/HttpServer/HttpToolbox.cpp                    |   1 +
 Core/HttpServer/HttpToolbox.h                      |   1 +
 Core/HttpServer/IHttpHandler.h                     |   1 +
 Core/HttpServer/IHttpOutputStream.h                |   1 +
 Core/HttpServer/IHttpStreamAnswer.h                |   1 +
 Core/HttpServer/IIncomingHttpRequestFilter.h       |   4 +-
 Core/HttpServer/MongooseServer.cpp                 |   4 +-
 Core/HttpServer/MongooseServer.h                   |   1 +
 Core/HttpServer/StringHttpOutput.cpp               |   1 +
 Core/HttpServer/StringHttpOutput.h                 |   1 +
 Core/ICommand.h                                    |   1 +
 Core/IDynamicObject.h                              |   1 +
 Core/Images/Font.cpp                               |   1 +
 Core/Images/Font.h                                 |   1 +
 Core/Images/FontRegistry.cpp                       |   1 +
 Core/Images/FontRegistry.h                         |   1 +
 Core/Images/IImageWriter.cpp                       |   1 +
 Core/Images/IImageWriter.h                         |   1 +
 Core/Images/Image.cpp                              |   1 +
 Core/Images/Image.h                                |   1 +
 Core/Images/ImageAccessor.cpp                      |   1 +
 Core/Images/ImageAccessor.h                        |   1 +
 Core/Images/ImageBuffer.cpp                        |   1 +
 Core/Images/ImageBuffer.h                          |   1 +
 Core/Images/ImageProcessing.cpp                    |  46 ++
 Core/Images/ImageProcessing.h                      |   3 +
 Core/Images/JpegErrorManager.cpp                   |   1 +
 Core/Images/JpegErrorManager.h                     |   1 +
 Core/Images/JpegReader.cpp                         |   1 +
 Core/Images/JpegReader.h                           |   1 +
 Core/Images/JpegWriter.cpp                         |   1 +
 Core/Images/JpegWriter.h                           |   1 +
 Core/Images/PngReader.cpp                          |   1 +
 Core/Images/PngReader.h                            |   1 +
 Core/Images/PngWriter.cpp                          |   1 +
 Core/Images/PngWriter.h                            |   1 +
 Core/Logging.cpp                                   |  75 ++-
 Core/Logging.h                                     |  53 +-
 Core/Lua/LuaContext.cpp                            |  41 +-
 Core/Lua/LuaContext.h                              |  11 +
 Core/Lua/LuaFunctionCall.cpp                       |   1 +
 Core/Lua/LuaFunctionCall.h                         |   1 +
 Core/MultiThreading/BagOfTasks.h                   |   1 +
 Core/MultiThreading/BagOfTasksProcessor.cpp        |   1 +
 Core/MultiThreading/BagOfTasksProcessor.h          |   1 +
 Core/MultiThreading/ILockable.h                    |   1 +
 Core/MultiThreading/IRunnableBySteps.h             |   1 +
 Core/MultiThreading/Locker.h                       |   1 +
 Core/MultiThreading/Mutex.cpp                      |   1 +
 Core/MultiThreading/Mutex.h                        |   1 +
 Core/MultiThreading/ReaderWriterLock.cpp           |   1 +
 Core/MultiThreading/ReaderWriterLock.h             |   1 +
 Core/MultiThreading/RunnableWorkersPool.cpp        |   5 +
 Core/MultiThreading/RunnableWorkersPool.h          |   1 +
 Core/MultiThreading/Semaphore.cpp                  |   1 +
 Core/MultiThreading/Semaphore.h                    |   1 +
 Core/MultiThreading/SharedMessageQueue.cpp         |   1 +
 Core/MultiThreading/SharedMessageQueue.h           |   1 +
 Core/OrthancException.h                            |   1 +
 Core/Pkcs11.cpp                                    |   1 +
 Core/Pkcs11.h                                      |   1 +
 Core/PrecompiledHeaders.cpp                        |   1 +
 Core/PrecompiledHeaders.h                          |   1 +
 Core/RestApi/RestApi.cpp                           |   1 +
 Core/RestApi/RestApi.h                             |   1 +
 Core/RestApi/RestApiCall.cpp                       |   1 +
 Core/RestApi/RestApiCall.h                         |   1 +
 Core/RestApi/RestApiDeleteCall.h                   |   1 +
 Core/RestApi/RestApiGetCall.cpp                    |   1 +
 Core/RestApi/RestApiGetCall.h                      |   1 +
 Core/RestApi/RestApiHierarchy.cpp                  |   1 +
 Core/RestApi/RestApiHierarchy.h                    |   1 +
 Core/RestApi/RestApiOutput.cpp                     |   1 +
 Core/RestApi/RestApiOutput.h                       |   1 +
 Core/RestApi/RestApiPath.cpp                       |   1 +
 Core/RestApi/RestApiPath.h                         |   1 +
 Core/RestApi/RestApiPostCall.h                     |   1 +
 Core/RestApi/RestApiPutCall.h                      |   1 +
 Core/SQLite/Connection.h                           |   4 +-
 Core/SQLite/FunctionContext.cpp                    |   2 +-
 Core/SQLite/FunctionContext.h                      |   7 +-
 Core/SQLite/{FunctionContext.h => SQLiteTypes.h}   |  73 +--
 Core/SQLite/Statement.h                            |   2 -
 Core/SQLite/StatementReference.h                   |   3 +-
 Core/SystemToolbox.cpp                             |  19 +-
 Core/SystemToolbox.h                               |   3 +
 Core/TemporaryFile.cpp                             |   1 +
 Core/TemporaryFile.h                               |   1 +
 Core/Toolbox.cpp                                   | 134 +++-
 Core/Toolbox.h                                     |   9 +-
 Core/WebServiceParameters.cpp                      |   2 +-
 Core/WebServiceParameters.h                        |   1 +
 NEWS                                               |  63 ++
 OrthancExplorer/explorer.html                      |   1 +
 OrthancExplorer/explorer.js                        | 170 +++---
 OrthancExplorer/query-retrieve.js                  |  46 +-
 OrthancServer/DatabaseWrapper.cpp                  |   1 +
 OrthancServer/DatabaseWrapper.h                    |   1 +
 OrthancServer/DatabaseWrapperBase.cpp              |   1 +
 OrthancServer/DatabaseWrapperBase.h                |   1 +
 OrthancServer/DefaultDicomImageDecoder.h           |   1 +
 OrthancServer/DicomDirWriter.cpp                   |   1 +
 OrthancServer/DicomDirWriter.h                     |   1 +
 OrthancServer/DicomInstanceToStore.cpp             |   1 +
 OrthancServer/DicomInstanceToStore.h               |   1 +
 OrthancServer/DicomModification.cpp                | 672 ++++++++++++++++++++-
 OrthancServer/DicomModification.h                  |  19 +-
 OrthancServer/DicomProtocol/DicomFindAnswers.cpp   |   1 +
 OrthancServer/DicomProtocol/DicomFindAnswers.h     |   1 +
 OrthancServer/DicomProtocol/DicomServer.cpp        |   1 +
 OrthancServer/DicomProtocol/DicomServer.h          |   1 +
 .../DicomProtocol/DicomUserConnection.cpp          |  30 +-
 OrthancServer/DicomProtocol/DicomUserConnection.h  |   1 +
 .../DicomProtocol/IApplicationEntityFilter.h       |   1 +
 OrthancServer/DicomProtocol/IFindRequestHandler.h  |   4 +-
 .../DicomProtocol/IFindRequestHandlerFactory.h     |   1 +
 OrthancServer/DicomProtocol/IMoveRequestHandler.h  |   1 +
 .../DicomProtocol/IMoveRequestHandlerFactory.h     |   1 +
 OrthancServer/DicomProtocol/IStoreRequestHandler.h |   1 +
 .../DicomProtocol/IStoreRequestHandlerFactory.h    |   1 +
 .../DicomProtocol/IWorklistRequestHandler.h        |   4 +-
 .../DicomProtocol/IWorklistRequestHandlerFactory.h |   1 +
 .../DicomProtocol/RemoteModalityParameters.cpp     |   1 +
 .../DicomProtocol/RemoteModalityParameters.h       |   1 +
 .../DicomProtocol/ReusableDicomUserConnection.cpp  |   1 +
 .../DicomProtocol/ReusableDicomUserConnection.h    |   1 +
 OrthancServer/ExportedResource.cpp                 |   1 +
 OrthancServer/ExportedResource.h                   |   1 +
 OrthancServer/FromDcmtkBridge.cpp                  |   9 +-
 OrthancServer/FromDcmtkBridge.h                    |  16 +-
 OrthancServer/IDatabaseListener.h                  |   1 +
 OrthancServer/IDatabaseWrapper.h                   |   1 +
 OrthancServer/IDicomImageDecoder.h                 |   1 +
 OrthancServer/IServerListener.h                    |   1 +
 OrthancServer/Internals/CommandDispatcher.cpp      |  10 +-
 OrthancServer/Internals/CommandDispatcher.h        |   1 +
 OrthancServer/Internals/DicomFrameIndex.cpp        |   1 +
 OrthancServer/Internals/DicomFrameIndex.h          |   1 +
 OrthancServer/Internals/DicomImageDecoder.cpp      |  17 +-
 OrthancServer/Internals/DicomImageDecoder.h        |   8 +-
 OrthancServer/Internals/FindScp.cpp                |  19 +-
 OrthancServer/Internals/FindScp.h                  |   1 +
 OrthancServer/Internals/MoveScp.cpp                |   1 +
 OrthancServer/Internals/MoveScp.h                  |   1 +
 OrthancServer/Internals/StoreScp.cpp               |   1 +
 OrthancServer/Internals/StoreScp.h                 |   1 +
 OrthancServer/LuaScripting.cpp                     |   1 +
 OrthancServer/LuaScripting.h                       |   1 +
 OrthancServer/OrthancFindRequestHandler.cpp        |  41 +-
 OrthancServer/OrthancFindRequestHandler.h          |   4 +-
 OrthancServer/OrthancHttpHandler.cpp               |   1 +
 OrthancServer/OrthancHttpHandler.h                 |   1 +
 OrthancServer/OrthancInitialization.cpp            |  36 +-
 OrthancServer/OrthancInitialization.h              |   4 +-
 OrthancServer/OrthancMoveRequestHandler.cpp        |   1 +
 OrthancServer/OrthancMoveRequestHandler.h          |   1 +
 .../OrthancRestApi/OrthancRestAnonymizeModify.cpp  | 138 +++--
 OrthancServer/OrthancRestApi/OrthancRestApi.cpp    |   1 +
 OrthancServer/OrthancRestApi/OrthancRestApi.h      |   1 +
 .../OrthancRestApi/OrthancRestArchive.cpp          |   1 +
 .../OrthancRestApi/OrthancRestChanges.cpp          |   1 +
 .../OrthancRestApi/OrthancRestModalities.cpp       |   1 +
 .../OrthancRestApi/OrthancRestResources.cpp        |  59 +-
 OrthancServer/OrthancRestApi/OrthancRestSystem.cpp |   1 +
 OrthancServer/ParsedDicomFile.cpp                  |  44 ++
 OrthancServer/ParsedDicomFile.h                    |   7 +
 OrthancServer/PrecompiledHeadersServer.cpp         |   1 +
 OrthancServer/PrecompiledHeadersServer.h           |   1 +
 OrthancServer/QueryRetrieveHandler.cpp             |   1 +
 OrthancServer/QueryRetrieveHandler.h               |   1 +
 OrthancServer/Scheduler/CallSystemCommand.cpp      |   1 +
 OrthancServer/Scheduler/CallSystemCommand.h        |   1 +
 OrthancServer/Scheduler/DeleteInstanceCommand.cpp  |   1 +
 OrthancServer/Scheduler/DeleteInstanceCommand.h    |   1 +
 OrthancServer/Scheduler/IServerCommand.h           |   1 +
 OrthancServer/Scheduler/ModifyInstanceCommand.cpp  |   1 +
 OrthancServer/Scheduler/ModifyInstanceCommand.h    |   1 +
 OrthancServer/Scheduler/ServerCommandInstance.cpp  |   1 +
 OrthancServer/Scheduler/ServerCommandInstance.h    |   1 +
 OrthancServer/Scheduler/ServerJob.cpp              |   1 +
 OrthancServer/Scheduler/ServerJob.h                |   1 +
 OrthancServer/Scheduler/ServerScheduler.cpp        |   1 +
 OrthancServer/Scheduler/ServerScheduler.h          |   1 +
 OrthancServer/Scheduler/StorePeerCommand.cpp       |   1 +
 OrthancServer/Scheduler/StorePeerCommand.h         |   1 +
 OrthancServer/Scheduler/StoreScuCommand.cpp        |   1 +
 OrthancServer/Scheduler/StoreScuCommand.h          |   1 +
 OrthancServer/Search/HierarchicalMatcher.cpp       |   9 +-
 OrthancServer/Search/HierarchicalMatcher.h         |   4 +-
 OrthancServer/Search/IFindConstraint.cpp           |   1 +
 OrthancServer/Search/IFindConstraint.h             |   1 +
 OrthancServer/Search/ListConstraint.cpp            |  19 +-
 OrthancServer/Search/ListConstraint.h              |   1 +
 OrthancServer/Search/LookupIdentifierQuery.cpp     |   1 +
 OrthancServer/Search/LookupIdentifierQuery.h       |   1 +
 OrthancServer/Search/LookupResource.cpp            |   1 +
 OrthancServer/Search/LookupResource.h              |   1 +
 OrthancServer/Search/RangeConstraint.cpp           |  24 +-
 OrthancServer/Search/RangeConstraint.h             |   1 +
 OrthancServer/Search/SetOfResources.cpp            |   1 +
 OrthancServer/Search/SetOfResources.h              |   1 +
 OrthancServer/Search/ValueConstraint.cpp           |  14 +-
 OrthancServer/Search/ValueConstraint.h             |   1 +
 OrthancServer/Search/WildcardConstraint.cpp        |  38 +-
 OrthancServer/Search/WildcardConstraint.h          |   1 +
 OrthancServer/ServerContext.cpp                    |  19 +-
 OrthancServer/ServerContext.h                      |   6 +-
 OrthancServer/ServerEnumerations.cpp               | 100 ++-
 OrthancServer/ServerEnumerations.h                 |  20 +-
 OrthancServer/ServerIndex.cpp                      |   1 +
 OrthancServer/ServerIndex.h                        |   1 +
 OrthancServer/ServerIndexChange.h                  |   1 +
 OrthancServer/ServerToolbox.cpp                    |   1 +
 OrthancServer/ServerToolbox.h                      |   1 +
 OrthancServer/SliceOrdering.cpp                    |   1 +
 OrthancServer/SliceOrdering.h                      |   1 +
 OrthancServer/ToDcmtkBridge.cpp                    |   1 +
 OrthancServer/ToDcmtkBridge.h                      |   1 +
 OrthancServer/main.cpp                             | 115 ++--
 Plugins/Engine/IPluginServiceProvider.h            |   1 +
 Plugins/Engine/OrthancPluginDatabase.cpp           |   1 +
 Plugins/Engine/OrthancPluginDatabase.h             |   1 +
 Plugins/Engine/OrthancPlugins.cpp                  |  83 ++-
 Plugins/Engine/OrthancPlugins.h                    |   6 +-
 Plugins/Engine/PluginsEnumerations.cpp             |   1 +
 Plugins/Engine/PluginsEnumerations.h               |   1 +
 Plugins/Engine/PluginsErrorDictionary.cpp          |   1 +
 Plugins/Engine/PluginsErrorDictionary.h            |   1 +
 Plugins/Engine/PluginsManager.cpp                  |   1 +
 Plugins/Engine/PluginsManager.h                    |   1 +
 Plugins/Engine/SharedLibrary.cpp                   |   1 +
 Plugins/Engine/SharedLibrary.h                     |   1 +
 Plugins/Include/orthanc/OrthancCDatabasePlugin.h   |   1 +
 Plugins/Include/orthanc/OrthancCPlugin.h           |  68 ++-
 Plugins/Include/orthanc/OrthancCppDatabasePlugin.h |   1 +
 .../Samples/AutomatedJpeg2kCompression/Plugin.cpp  |   1 +
 Plugins/Samples/Basic/Plugin.c                     |   1 +
 Plugins/Samples/Common/DicomDatasetReader.cpp      |  83 ++-
 Plugins/Samples/Common/DicomDatasetReader.h        |  25 +-
 Plugins/Samples/Common/DicomPath.cpp               |   5 +-
 Plugins/Samples/Common/DicomPath.h                 |   1 +
 Plugins/Samples/Common/DicomTag.cpp                |   5 +-
 Plugins/Samples/Common/DicomTag.h                  |  15 +-
 Plugins/Samples/Common/FullOrthancDataset.cpp      |  31 +-
 Plugins/Samples/Common/FullOrthancDataset.h        |   6 +
 Plugins/Samples/Common/IDicomDataset.h             |   1 +
 Plugins/Samples/Common/IOrthancConnection.cpp      |  19 +-
 Plugins/Samples/Common/IOrthancConnection.h        |   5 +
 Plugins/Samples/Common/OrthancHttpConnection.cpp   |   1 +
 Plugins/Samples/Common/OrthancHttpConnection.h     |   1 +
 Plugins/Samples/Common/OrthancPluginConnection.cpp |   9 +-
 Plugins/Samples/Common/OrthancPluginConnection.h   |   1 +
 Plugins/Samples/Common/OrthancPluginCppWrapper.cpp | 332 ++++++----
 Plugins/Samples/Common/OrthancPluginCppWrapper.h   |  98 +--
 Plugins/Samples/Common/OrthancPluginException.h    | 101 ++++
 .../Samples/Common/SimplifiedOrthancDataset.cpp    |  15 +-
 Plugins/Samples/Common/SimplifiedOrthancDataset.h  |   1 +
 Plugins/Samples/CustomImageDecoder/Plugin.cpp      |   1 +
 Plugins/Samples/DatabasePlugin/Database.cpp        |   1 +
 Plugins/Samples/DatabasePlugin/Database.h          |   1 +
 Plugins/Samples/DatabasePlugin/Plugin.cpp          |   1 +
 Plugins/Samples/GdcmDecoder/GdcmDecoderCache.cpp   |   1 +
 Plugins/Samples/GdcmDecoder/GdcmDecoderCache.h     |   1 +
 Plugins/Samples/GdcmDecoder/GdcmImageDecoder.cpp   |   1 +
 Plugins/Samples/GdcmDecoder/GdcmImageDecoder.h     |   1 +
 .../Samples/GdcmDecoder/OrthancImageWrapper.cpp    |   1 +
 Plugins/Samples/GdcmDecoder/OrthancImageWrapper.h  |   1 +
 Plugins/Samples/GdcmDecoder/Plugin.cpp             |   1 +
 Plugins/Samples/ModalityWorklists/Plugin.cpp       | 144 +++--
 Plugins/Samples/ServeFolders/Plugin.cpp            |  26 +-
 Plugins/Samples/StorageArea/Plugin.cpp             |   1 +
 Plugins/Samples/WebSkeleton/Configuration.h        |   1 +
 .../WebSkeleton/Framework/EmbedResources.py        |   1 +
 .../Samples/WebSkeleton/Framework/Framework.cmake  |   1 +
 Plugins/Samples/WebSkeleton/Framework/Plugin.cpp   |   1 +
 Resources/CMake/BoostConfiguration.cmake           |  24 +-
 Resources/CMake/BoostConfiguration.sh              |  23 +-
 Resources/CMake/DcmtkConfiguration.cmake           | 163 +++--
 Resources/CMake/LibIconvConfiguration.cmake        |   6 +-
 Resources/CMake/SQLiteConfiguration.cmake          |   9 +-
 Resources/Configuration.json                       |  49 +-
 Resources/DicomConformanceStatement.py             |   1 +
 Resources/EmbedResources.py                        |   1 +
 Resources/EncodingTests.h                          |   2 +
 Resources/EncodingTests.py                         |   6 +
 Resources/Fonts/GenerateFont.py                    |   1 +
 Resources/GenerateAnonymizationProfile.py          | 110 ++++
 Resources/GenerateErrorCodes.py                    |   1 +
 Resources/Patches/dcmtk-3.6.0-speed.patch          |  28 +-
 Resources/Patches/dcmtk-3.6.1-speed.patch          |  26 -
 ...k-3.6.1-private.dic => dcmtk-3.6.2-private.dic} |   0
 Resources/Patches/dcmtk.txt                        |   6 +-
 Resources/RetrieveCACertificates.py                |   1 +
 .../Samples/ImportDicomFiles/ImportDicomFiles.py   |   3 +-
 .../Samples/Lua/AutomatedJpeg2kCompression.lua     |   2 +-
 Resources/Samples/Lua/CallWebService.js            |   1 +
 .../Samples/Lua/ModifyInstanceWithSequence.lua     |   2 +-
 Resources/Samples/Lua/OnStableStudy.lua            |   2 +-
 Resources/Samples/Python/AnonymizeAllPatients.py   |   1 +
 Resources/Samples/Python/ArchiveAllPatients.py     |   1 +
 .../Samples/Python/ArchiveStudiesInTimeRange.py    |   1 +
 Resources/Samples/Python/AutoClassify.py           |   1 +
 Resources/Samples/Python/ChangesLoop.py            |   1 +
 .../Python/ContinuousPatientAnonymization.py       |   1 +
 Resources/Samples/Python/DownloadAnonymized.py     |   1 +
 .../Samples/Python/HighPerformanceAutoRouting.py   |   1 +
 Resources/Samples/Python/ManualModification.py     |   1 +
 Resources/Samples/Python/Replicate.py              |   1 +
 Resources/Samples/Python/RestToolbox.py            |   1 +
 Resources/Samples/Tools/RecoverCompressedFile.cpp  |   1 +
 .../Samples/WebApplications/DrawingDicomizer.js    |   1 +
 .../WebApplications/DrawingDicomizer/orthanc.js    |   1 +
 Resources/Samples/WebApplications/NodeToolbox.js   |   1 +
 Resources/WindowsResources.py                      |   1 +
 TODO                                               |  18 +-
 UnitTestsSources/DicomMapTests.cpp                 |   1 +
 UnitTestsSources/FileStorageTests.cpp              |   1 +
 UnitTestsSources/FromDcmtkTests.cpp                |  13 +-
 UnitTestsSources/ImageProcessingTests.cpp          |   1 +
 UnitTestsSources/ImageTests.cpp                    |   1 +
 UnitTestsSources/JpegLosslessTests.cpp             |   1 +
 UnitTestsSources/LuaTests.cpp                      |   1 +
 UnitTestsSources/MemoryCacheTests.cpp              |   1 +
 UnitTestsSources/MultiThreadingTests.cpp           |   9 +-
 UnitTestsSources/PluginsTests.cpp                  |   1 +
 UnitTestsSources/PrecompiledHeadersUnitTests.cpp   |   1 +
 UnitTestsSources/PrecompiledHeadersUnitTests.h     |   1 +
 UnitTestsSources/RestApiTests.cpp                  |   1 +
 UnitTestsSources/SQLiteChromiumTests.cpp           |   1 +
 UnitTestsSources/SQLiteTests.cpp                   |   1 +
 UnitTestsSources/ServerIndexTests.cpp              |   1 +
 UnitTestsSources/StreamTests.cpp                   |   1 +
 UnitTestsSources/UnitTestsMain.cpp                 |  32 +-
 UnitTestsSources/VersionsTests.cpp                 |   3 +-
 UnitTestsSources/ZipTests.cpp                      |   1 +
 403 files changed, 3425 insertions(+), 952 deletions(-)

diff --git a/.hg_archival.txt b/.hg_archival.txt
index 68a52ba..185a01a 100644
--- a/.hg_archival.txt
+++ b/.hg_archival.txt
@@ -1,5 +1,6 @@
 repo: 3959d33612ccaadc0d4d707227fbed09ac35e5fe
-node: 2bdc29af95895479178be61a219977e861c90645
-branch: Orthanc-1.2.0
-latesttag: null
-latesttagdistance: 1946
+node: ed050cfd5898523069a3304daee76a1822769ba1
+branch: Orthanc-1.3.0
+latesttag: dcmtk-3.6.1
+latesttagdistance: 21
+changessincelatesttag: 22
diff --git a/.hgignore b/.hgignore
new file mode 100644
index 0000000..a136e22
--- /dev/null
+++ b/.hgignore
@@ -0,0 +1,2 @@
+syntax: glob
+ThirdPartyDownloads/
\ No newline at end of file
diff --git a/.hgtags b/.hgtags
new file mode 100644
index 0000000..9ce432a
--- /dev/null
+++ b/.hgtags
@@ -0,0 +1 @@
+a95beca72e99f3a1110cffd252bcf3abf5a2db27 dcmtk-3.6.1
diff --git a/.travis.yml b/.travis.yml
index b69d750..1da1cfa 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -31,8 +31,12 @@ before_install:
     -qq build-essential unzip cmake mercurial uuid-dev libcurl4-openssl-dev liblua5.1-0-dev
     libgtest-dev libpng-dev libsqlite3-dev libssl-dev zlib1g-dev libdcmtk2-dev libwrap0-dev
     libcharls-dev; fi
-  - if [ $TRAVIS_OS_NAME == linux -a $TRAVIS_MINGW == ON ]; then sudo apt-get install mingw32; fi
+  # For DCMTK 3.6.2 - Can't make it compile in static mode with MinGW32 on the
+  # Ubuntu Precise (12.04) that is used by Travis:
+  # - if [ $TRAVIS_OS_NAME == linux -a $TRAVIS_MINGW == ON ]; then sudo apt-get install mingw-w64 gcc-mingw-w64-i686 g++-mingw-w64-i686 wine; fi
 
+  # For DCMTK 3.6.0: 
+  - if [ $TRAVIS_OS_NAME == linux -a $TRAVIS_MINGW == ON ]; then sudo apt-get install mingw32; fi
 
 before_script:
   - mkdir Build
@@ -44,7 +48,7 @@ before_script:
     ..; fi
   - if [ $TRAVIS_OS_NAME == linux -a $TRAVIS_MINGW == ON ]; then cmake
     -DCMAKE_BUILD_TYPE=Debug -DSTATIC_BUILD=ON -DSTANDALONE_BUILD=ON -DALLOW_DOWNLOADS=ON
-    -DCMAKE_TOOLCHAIN_FILE=Resources/MinGWToolchain.cmake
+    -DCMAKE_TOOLCHAIN_FILE=Resources/MinGWToolchain.cmake -DUSE_DCMTK_360=ON
     ..; fi
   - if [ $TRAVIS_OS_NAME == osx ]; then cmake 
     -DCMAKE_BUILD_TYPE=Debug -DSTATIC_BUILD=ON -DSTANDALONE_BUILD=ON -DALLOW_DOWNLOADS=ON
diff --git a/AUTHORS b/AUTHORS
index 357dfc1..da003e3 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -6,28 +6,15 @@ Authors of Orthanc
 ------------------
 
 * Sebastien Jodogne <s.jodogne at gmail.com>
-  Department of Medical Physics
-  University Hospital of Liege
-  Belgium
 
   Overall design and lead developer.
 
+* Department of Medical Physics
+  University Hospital of Liege
+  4000 Liege
+  Belgium
 
-Client library
---------------
-
-The client library of Orthanc is automatically wrapped from the C++
-code using the LAAW software. LAAW is the Lightweight, Automated API
-Wrapper from the Jomago team, that comes from the following authors:
-
-* Sebastien Jodogne <s.jodogne at gmail.com>
-* Alain Mazy <alain at mazy.be>
-* Benjamin Golinvaux <golinvauxb at gmail.com>
-
-LAAW should be soon released as a separate open-source project.
-
-
-Contributors
-------------
-
-See the file "THANKS" for the occasional contributors.
+* Osimis <info at osimis.io>
+  Rue des Chasseurs Ardennais 3
+  4031 Liege 
+  Belgium
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5b75105..d66b960 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8)
 project(Orthanc)
 
 # Version of the build, should always be "mainline" except in release branches
-set(ORTHANC_VERSION "1.2.0")
+set(ORTHANC_VERSION "1.3.0")
 
 # Version of the database schema. History:
 #   * Orthanc 0.1.0 -> Orthanc 0.3.0 = no versioning
@@ -53,8 +53,8 @@ SET(USE_SYSTEM_LIBP11 OFF CACHE BOOL "Use the system version of libp11 (PKCS#11
 
 # Advanced parameters
 SET(USE_PUGIXML ON CACHE BOOL "Use the Pugixml parser (turn off only for debug)")
-SET(USE_DCMTK_361 OFF CACHE BOOL "Use forthcoming DCMTK version 3.6.1 in static builds (instead of 3.6.0)")
-SET(USE_DCMTK_361_PRIVATE_DIC ON CACHE BOOL "Use the dictionary of private tags from DCMTK 3.6.1 in static builds (which is more up-to-date)")
+SET(USE_DCMTK_360 OFF CACHE BOOL "Use older DCMTK version 3.6.0 in static builds (instead of default 3.6.2)")
+SET(USE_DCMTK_362_PRIVATE_DIC ON CACHE BOOL "Use the dictionary of private tags from DCMTK 3.6.2 if using DCMTK 3.6.0")
 
 # Distribution-specific settings
 SET(USE_GTEST_DEBIAN_SOURCE_PACKAGE OFF CACHE BOOL "Use the sources of Google Test shipped with libgtest-dev (Debian only)")
@@ -69,6 +69,7 @@ mark_as_advanced(USE_PUGIXML)
 # Path to the root folder of the Orthanc distribution
 set(ORTHANC_ROOT ${CMAKE_SOURCE_DIR})
 set(ENABLE_DCMTK_NETWORK ON)
+set(USE_BOOST_LOCALE_BACKEND OFF)
 
 # Some basic inclusions
 include(CheckIncludeFiles)
@@ -267,7 +268,7 @@ set(ORTHANC_ALL_SOURCES
 
 if (CMAKE_COMPILER_IS_GNUCXX
     AND NOT CMAKE_CROSSCOMPILING 
-    AND NOT USE_DCMTK_361)
+    AND USE_DCMTK_360)
   # Add the "-pedantic" flag only on the Orthanc sources, and only if
   # using DCMTK 3.6.0
   set_source_files_properties(${ORTHANC_ALL_SOURCES}
@@ -412,6 +413,8 @@ add_definitions(
   -DORTHANC_BUILD_UNIT_TESTS=1
   -DORTHANC_ENABLE_BASE64=1
   -DORTHANC_ENABLE_LOGGING=1
+  -DORTHANC_ENABLE_LOGGING_PLUGIN=0
+  -DORTHANC_ENABLE_LUA=1
   -DORTHANC_ENABLE_MD5=1
   -DORTHANC_MAXIMUM_TAG_LENGTH=256
   -DORTHANC_SANDBOXED=0
diff --git a/Core/Cache/ICachePageProvider.h b/Core/Cache/ICachePageProvider.h
index e795655..b53c956 100644
--- a/Core/Cache/ICachePageProvider.h
+++ b/Core/Cache/ICachePageProvider.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Cache/LeastRecentlyUsedIndex.h b/Core/Cache/LeastRecentlyUsedIndex.h
index a5bf7b2..63ed2d4 100644
--- a/Core/Cache/LeastRecentlyUsedIndex.h
+++ b/Core/Cache/LeastRecentlyUsedIndex.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Cache/MemoryCache.cpp b/Core/Cache/MemoryCache.cpp
index a2d5450..758234d 100644
--- a/Core/Cache/MemoryCache.cpp
+++ b/Core/Cache/MemoryCache.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Cache/MemoryCache.h b/Core/Cache/MemoryCache.h
index d29bc1f..bb90b94 100644
--- a/Core/Cache/MemoryCache.h
+++ b/Core/Cache/MemoryCache.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Cache/SharedArchive.cpp b/Core/Cache/SharedArchive.cpp
index b3cafb5..6f50c0b 100644
--- a/Core/Cache/SharedArchive.cpp
+++ b/Core/Cache/SharedArchive.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Cache/SharedArchive.h b/Core/Cache/SharedArchive.h
index c4c0f8b..19cab4a 100644
--- a/Core/Cache/SharedArchive.h
+++ b/Core/Cache/SharedArchive.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/ChunkedBuffer.cpp b/Core/ChunkedBuffer.cpp
index 5d2c2c8..22a3c0e 100644
--- a/Core/ChunkedBuffer.cpp
+++ b/Core/ChunkedBuffer.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/ChunkedBuffer.h b/Core/ChunkedBuffer.h
index 552c1ec..05c724e 100644
--- a/Core/ChunkedBuffer.h
+++ b/Core/ChunkedBuffer.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Compression/DeflateBaseCompressor.cpp b/Core/Compression/DeflateBaseCompressor.cpp
index b605a3a..c19f15d 100644
--- a/Core/Compression/DeflateBaseCompressor.cpp
+++ b/Core/Compression/DeflateBaseCompressor.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Compression/DeflateBaseCompressor.h b/Core/Compression/DeflateBaseCompressor.h
index 9b8298c..1ec0991 100644
--- a/Core/Compression/DeflateBaseCompressor.h
+++ b/Core/Compression/DeflateBaseCompressor.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Compression/GzipCompressor.cpp b/Core/Compression/GzipCompressor.cpp
index 1557eb8..d2b453b 100644
--- a/Core/Compression/GzipCompressor.cpp
+++ b/Core/Compression/GzipCompressor.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Compression/GzipCompressor.h b/Core/Compression/GzipCompressor.h
index d43a6f2..66a5f4a 100644
--- a/Core/Compression/GzipCompressor.h
+++ b/Core/Compression/GzipCompressor.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Compression/HierarchicalZipWriter.cpp b/Core/Compression/HierarchicalZipWriter.cpp
index c3d1048..594beb1 100644
--- a/Core/Compression/HierarchicalZipWriter.cpp
+++ b/Core/Compression/HierarchicalZipWriter.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Compression/HierarchicalZipWriter.h b/Core/Compression/HierarchicalZipWriter.h
index ea384cf..f77d735 100644
--- a/Core/Compression/HierarchicalZipWriter.h
+++ b/Core/Compression/HierarchicalZipWriter.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Compression/IBufferCompressor.h b/Core/Compression/IBufferCompressor.h
index dceab2e..6e43a47 100644
--- a/Core/Compression/IBufferCompressor.h
+++ b/Core/Compression/IBufferCompressor.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Compression/ZipWriter.cpp b/Core/Compression/ZipWriter.cpp
index b36c88a..b0594e7 100644
--- a/Core/Compression/ZipWriter.cpp
+++ b/Core/Compression/ZipWriter.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Compression/ZipWriter.h b/Core/Compression/ZipWriter.h
index e6b8db7..f4db7d4 100644
--- a/Core/Compression/ZipWriter.h
+++ b/Core/Compression/ZipWriter.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Compression/ZlibCompressor.cpp b/Core/Compression/ZlibCompressor.cpp
index acba7c0..3c18ac0 100644
--- a/Core/Compression/ZlibCompressor.cpp
+++ b/Core/Compression/ZlibCompressor.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Compression/ZlibCompressor.h b/Core/Compression/ZlibCompressor.h
index 3b9e898..59acafd 100644
--- a/Core/Compression/ZlibCompressor.h
+++ b/Core/Compression/ZlibCompressor.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/DicomFormat/DicomArray.cpp b/Core/DicomFormat/DicomArray.cpp
index 4900419..800c4cf 100644
--- a/Core/DicomFormat/DicomArray.cpp
+++ b/Core/DicomFormat/DicomArray.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/DicomFormat/DicomArray.h b/Core/DicomFormat/DicomArray.h
index 97a7d9c..5f66f07 100644
--- a/Core/DicomFormat/DicomArray.h
+++ b/Core/DicomFormat/DicomArray.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/DicomFormat/DicomElement.h b/Core/DicomFormat/DicomElement.h
index c6f47e5..a50d5c3 100644
--- a/Core/DicomFormat/DicomElement.h
+++ b/Core/DicomFormat/DicomElement.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/DicomFormat/DicomImageInformation.cpp b/Core/DicomFormat/DicomImageInformation.cpp
index d498583..cc68131 100644
--- a/Core/DicomFormat/DicomImageInformation.cpp
+++ b/Core/DicomFormat/DicomImageInformation.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -199,13 +200,6 @@ namespace Orthanc
       throw OrthancException(ErrorCode_NotImplemented);
     }
 
-    if (bitsAllocated_ > 32 ||
-        bitsStored_ >= 32)
-    {
-      // Not available, as the accessor internally uses int32_t values
-      throw OrthancException(ErrorCode_NotImplemented);
-    }
-
     if (samplesPerPixel_ == 0)
     {
       throw OrthancException(ErrorCode_NotImplemented);
diff --git a/Core/DicomFormat/DicomImageInformation.h b/Core/DicomFormat/DicomImageInformation.h
index e27db09..4c9f63d 100644
--- a/Core/DicomFormat/DicomImageInformation.h
+++ b/Core/DicomFormat/DicomImageInformation.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/DicomFormat/DicomInstanceHasher.cpp b/Core/DicomFormat/DicomInstanceHasher.cpp
index 4577258..8bc0f48 100644
--- a/Core/DicomFormat/DicomInstanceHasher.cpp
+++ b/Core/DicomFormat/DicomInstanceHasher.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/DicomFormat/DicomInstanceHasher.h b/Core/DicomFormat/DicomInstanceHasher.h
index feb22ec..4a4e98e 100644
--- a/Core/DicomFormat/DicomInstanceHasher.h
+++ b/Core/DicomFormat/DicomInstanceHasher.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/DicomFormat/DicomIntegerPixelAccessor.cpp b/Core/DicomFormat/DicomIntegerPixelAccessor.cpp
index 1ef43ed..d9fba78 100644
--- a/Core/DicomFormat/DicomIntegerPixelAccessor.cpp
+++ b/Core/DicomFormat/DicomIntegerPixelAccessor.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -53,6 +54,13 @@ namespace Orthanc
     pixelData_(pixelData),
     size_(size)
   {
+    if (information_.GetBitsAllocated() > 32 ||
+        information_.GetBitsStored() >= 32)
+    {
+      // Not available, as the accessor internally uses int32_t values
+      throw OrthancException(ErrorCode_NotImplemented);
+    }
+
     frame_ = 0;
     frameOffset_ = information_.GetFrameSize();
 
diff --git a/Core/DicomFormat/DicomIntegerPixelAccessor.h b/Core/DicomFormat/DicomIntegerPixelAccessor.h
index bc60e4e..33ca3f4 100644
--- a/Core/DicomFormat/DicomIntegerPixelAccessor.h
+++ b/Core/DicomFormat/DicomIntegerPixelAccessor.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/DicomFormat/DicomMap.cpp b/Core/DicomFormat/DicomMap.cpp
index cd72d09..c11ee82 100644
--- a/Core/DicomFormat/DicomMap.cpp
+++ b/Core/DicomFormat/DicomMap.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/DicomFormat/DicomMap.h b/Core/DicomFormat/DicomMap.h
index 160363f..80732ef 100644
--- a/Core/DicomFormat/DicomMap.h
+++ b/Core/DicomFormat/DicomMap.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/DicomFormat/DicomTag.cpp b/Core/DicomFormat/DicomTag.cpp
index 12ae7a4..83cc9fe 100644
--- a/Core/DicomFormat/DicomTag.cpp
+++ b/Core/DicomFormat/DicomTag.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/DicomFormat/DicomTag.h b/Core/DicomFormat/DicomTag.h
index bf971ca..6b9ba90 100644
--- a/Core/DicomFormat/DicomTag.h
+++ b/Core/DicomFormat/DicomTag.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/DicomFormat/DicomValue.cpp b/Core/DicomFormat/DicomValue.cpp
index 2a4c2f2..9c8958d 100644
--- a/Core/DicomFormat/DicomValue.cpp
+++ b/Core/DicomFormat/DicomValue.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/DicomFormat/DicomValue.h b/Core/DicomFormat/DicomValue.h
index c4844b7..405cdda 100644
--- a/Core/DicomFormat/DicomValue.h
+++ b/Core/DicomFormat/DicomValue.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Endianness.h b/Core/Endianness.h
index a68fd83..14cbca1 100644
--- a/Core/Endianness.h
+++ b/Core/Endianness.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/EnumerationDictionary.h b/Core/EnumerationDictionary.h
index 9479401..e0a0960 100644
--- a/Core/EnumerationDictionary.h
+++ b/Core/EnumerationDictionary.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Enumerations.cpp b/Core/Enumerations.cpp
index 19057b4..8309e1a 100644
--- a/Core/Enumerations.cpp
+++ b/Core/Enumerations.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -635,10 +636,10 @@ namespace Orthanc
         return "RGB";
 
       case PhotometricInterpretation_Monochrome1:
-        return "Monochrome1";
+        return "MONOCHROME1";
 
       case PhotometricInterpretation_Monochrome2:
-        return "Monochrome2";
+        return "MONOCHROME2";
 
       case PhotometricInterpretation_ARGB:
         return "ARGB";
@@ -650,25 +651,25 @@ namespace Orthanc
         return "HSV";
 
       case PhotometricInterpretation_Palette:
-        return "Palette color";
+        return "PALETTE COLOR";
 
       case PhotometricInterpretation_YBRFull:
-        return "YBR full";
+        return "YBR_FULL";
 
       case PhotometricInterpretation_YBRFull422:
-        return "YBR full 422";
+        return "YBR_FULL_422";
 
       case PhotometricInterpretation_YBRPartial420:
-        return "YBR partial 420"; 
+        return "YBR_PARTIAL_420"; 
 
       case PhotometricInterpretation_YBRPartial422:
-        return "YBR partial 422"; 
+        return "YBR_PARTIAL_422"; 
 
       case PhotometricInterpretation_YBR_ICT:
-        return "YBR ICT"; 
+        return "YBR_ICT"; 
 
       case PhotometricInterpretation_YBR_RCT:
-        return "YBR RCT"; 
+        return "YBR_RCT"; 
 
       case PhotometricInterpretation_Unknown:
         return "Unknown";
@@ -1052,6 +1053,80 @@ namespace Orthanc
   }
 
 
+  PhotometricInterpretation StringToPhotometricInterpretation(const char* value)
+  {
+    // http://dicom.nema.org/medical/dicom/2017a/output/chtml/part03/sect_C.7.6.3.html#sect_C.7.6.3.1.2
+    std::string s(value);
+
+    if (s == "MONOCHROME1")
+    {
+      return PhotometricInterpretation_Monochrome1;
+    }
+    
+    if (s == "MONOCHROME2")
+    {
+      return PhotometricInterpretation_Monochrome2;
+    }
+
+    if (s == "PALETTE COLOR")
+    {
+      return PhotometricInterpretation_Palette;
+    }
+    
+    if (s == "RGB")
+    {
+      return PhotometricInterpretation_RGB;
+    }
+    
+    if (s == "HSV")
+    {
+      return PhotometricInterpretation_HSV;
+    }
+    
+    if (s == "ARGB")
+    {
+      return PhotometricInterpretation_ARGB;
+    }    
+
+    if (s == "CMYK")
+    {
+      return PhotometricInterpretation_CMYK;
+    }    
+
+    if (s == "YBR_FULL")
+    {
+      return PhotometricInterpretation_YBRFull;
+    }
+    
+    if (s == "YBR_FULL_422")
+    {
+      return PhotometricInterpretation_YBRFull422;
+    }
+    
+    if (s == "YBR_PARTIAL_422")
+    {
+      return PhotometricInterpretation_YBRPartial422;
+    }
+    
+    if (s == "YBR_PARTIAL_420")
+    {
+      return PhotometricInterpretation_YBRPartial420;
+    }
+    
+    if (s == "YBR_ICT")
+    {
+      return PhotometricInterpretation_YBR_ICT;
+    }
+    
+    if (s == "YBR_RCT")
+    {
+      return PhotometricInterpretation_YBR_RCT;
+    }
+
+    throw OrthancException(ErrorCode_ParameterOutOfRange);
+  }
+  
+
   unsigned int GetBytesPerPixel(PixelFormat format)
   {
     switch (format)
diff --git a/Core/Enumerations.h b/Core/Enumerations.h
index 9b18661..aae6627 100644
--- a/Core/Enumerations.h
+++ b/Core/Enumerations.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -523,6 +524,8 @@ namespace Orthanc
   ValueRepresentation StringToValueRepresentation(const std::string& vr,
                                                   bool throwIfUnsupported);
 
+  PhotometricInterpretation StringToPhotometricInterpretation(const char* value);
+  
   unsigned int GetBytesPerPixel(PixelFormat format);
 
   bool GetDicomEncoding(Encoding& encoding,
diff --git a/Core/FileStorage/FileInfo.h b/Core/FileStorage/FileInfo.h
index 81dc7ef..63c88c1 100644
--- a/Core/FileStorage/FileInfo.h
+++ b/Core/FileStorage/FileInfo.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/FileStorage/FilesystemStorage.cpp b/Core/FileStorage/FilesystemStorage.cpp
index 668ab20..30550e0 100644
--- a/Core/FileStorage/FilesystemStorage.cpp
+++ b/Core/FileStorage/FilesystemStorage.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/FileStorage/FilesystemStorage.h b/Core/FileStorage/FilesystemStorage.h
index a7f52cf..793b6b5 100644
--- a/Core/FileStorage/FilesystemStorage.h
+++ b/Core/FileStorage/FilesystemStorage.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/FileStorage/IStorageArea.h b/Core/FileStorage/IStorageArea.h
index 7e3eafc..21e5ed0 100644
--- a/Core/FileStorage/IStorageArea.h
+++ b/Core/FileStorage/IStorageArea.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/FileStorage/StorageAccessor.cpp b/Core/FileStorage/StorageAccessor.cpp
index d3342dd..89830fc 100644
--- a/Core/FileStorage/StorageAccessor.cpp
+++ b/Core/FileStorage/StorageAccessor.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/FileStorage/StorageAccessor.h b/Core/FileStorage/StorageAccessor.h
index 990418a..6268d32 100644
--- a/Core/FileStorage/StorageAccessor.h
+++ b/Core/FileStorage/StorageAccessor.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpClient.cpp b/Core/HttpClient.cpp
index 70392ff..b246279 100644
--- a/Core/HttpClient.cpp
+++ b/Core/HttpClient.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -822,10 +823,12 @@ namespace Orthanc
 
   void HttpClient::FinalizeOpenSsl()
   {
- #if ORTHANC_ENABLE_SSL == 1
+#if ORTHANC_ENABLE_SSL == 1
     // Finalize OpenSSL
     // https://wiki.openssl.org/index.php/Library_Initialization#Cleanup
+#ifdef FIPS_mode_set
     FIPS_mode_set(0);
+#endif
     ENGINE_cleanup();
     CONF_modules_unload(1);
     EVP_cleanup();
diff --git a/Core/HttpClient.h b/Core/HttpClient.h
index 1b80f33..65435d0 100644
--- a/Core/HttpClient.h
+++ b/Core/HttpClient.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/BufferHttpSender.cpp b/Core/HttpServer/BufferHttpSender.cpp
index a61389d..f0835de 100644
--- a/Core/HttpServer/BufferHttpSender.cpp
+++ b/Core/HttpServer/BufferHttpSender.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/BufferHttpSender.h b/Core/HttpServer/BufferHttpSender.h
index 646a5e5..c1e08c6 100644
--- a/Core/HttpServer/BufferHttpSender.h
+++ b/Core/HttpServer/BufferHttpSender.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/EmbeddedResourceHttpHandler.cpp b/Core/HttpServer/EmbeddedResourceHttpHandler.cpp
index 175fee5..99d5cad 100644
--- a/Core/HttpServer/EmbeddedResourceHttpHandler.cpp
+++ b/Core/HttpServer/EmbeddedResourceHttpHandler.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/EmbeddedResourceHttpHandler.h b/Core/HttpServer/EmbeddedResourceHttpHandler.h
index d262eb5..184f5b3 100644
--- a/Core/HttpServer/EmbeddedResourceHttpHandler.h
+++ b/Core/HttpServer/EmbeddedResourceHttpHandler.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/FilesystemHttpHandler.cpp b/Core/HttpServer/FilesystemHttpHandler.cpp
index 33909f3..f4e8e1b 100644
--- a/Core/HttpServer/FilesystemHttpHandler.cpp
+++ b/Core/HttpServer/FilesystemHttpHandler.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/FilesystemHttpHandler.h b/Core/HttpServer/FilesystemHttpHandler.h
index 2ca059b..3fc0b1d 100644
--- a/Core/HttpServer/FilesystemHttpHandler.h
+++ b/Core/HttpServer/FilesystemHttpHandler.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/FilesystemHttpSender.cpp b/Core/HttpServer/FilesystemHttpSender.cpp
index cdef503..280c614 100644
--- a/Core/HttpServer/FilesystemHttpSender.cpp
+++ b/Core/HttpServer/FilesystemHttpSender.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -69,7 +70,7 @@ namespace Orthanc
       throw OrthancException(ErrorCode_CorruptedFile);
     }
 
-    chunkSize_ = file_.gcount();
+    chunkSize_ = static_cast<size_t>(file_.gcount());
 
     return chunkSize_ > 0;
   }
diff --git a/Core/HttpServer/FilesystemHttpSender.h b/Core/HttpServer/FilesystemHttpSender.h
index 8e09595..538a07a 100644
--- a/Core/HttpServer/FilesystemHttpSender.h
+++ b/Core/HttpServer/FilesystemHttpSender.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/HttpContentNegociation.cpp b/Core/HttpServer/HttpContentNegociation.cpp
index ac8731c..876f8d6 100644
--- a/Core/HttpServer/HttpContentNegociation.cpp
+++ b/Core/HttpServer/HttpContentNegociation.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/HttpContentNegociation.h b/Core/HttpServer/HttpContentNegociation.h
index 2c36821..98d2719 100644
--- a/Core/HttpServer/HttpContentNegociation.h
+++ b/Core/HttpServer/HttpContentNegociation.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/HttpFileSender.cpp b/Core/HttpServer/HttpFileSender.cpp
index 2f520cf..5cb34ce 100644
--- a/Core/HttpServer/HttpFileSender.cpp
+++ b/Core/HttpServer/HttpFileSender.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/HttpFileSender.h b/Core/HttpServer/HttpFileSender.h
index e653b68..72cf980 100644
--- a/Core/HttpServer/HttpFileSender.h
+++ b/Core/HttpServer/HttpFileSender.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/HttpOutput.cpp b/Core/HttpServer/HttpOutput.cpp
index 3e0862e..38a2bf8 100644
--- a/Core/HttpServer/HttpOutput.cpp
+++ b/Core/HttpServer/HttpOutput.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/HttpOutput.h b/Core/HttpServer/HttpOutput.h
index ff08bf1..7296a80 100644
--- a/Core/HttpServer/HttpOutput.h
+++ b/Core/HttpServer/HttpOutput.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/HttpStreamTranscoder.cpp b/Core/HttpServer/HttpStreamTranscoder.cpp
index 8c865a4..bda7510 100644
--- a/Core/HttpServer/HttpStreamTranscoder.cpp
+++ b/Core/HttpServer/HttpStreamTranscoder.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/HttpStreamTranscoder.h b/Core/HttpServer/HttpStreamTranscoder.h
index 0647eda..402c487 100644
--- a/Core/HttpServer/HttpStreamTranscoder.h
+++ b/Core/HttpServer/HttpStreamTranscoder.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/HttpToolbox.cpp b/Core/HttpServer/HttpToolbox.cpp
index be69f52..b198afc 100644
--- a/Core/HttpServer/HttpToolbox.cpp
+++ b/Core/HttpServer/HttpToolbox.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/HttpToolbox.h b/Core/HttpServer/HttpToolbox.h
index 7f4141c..b7b8b86 100644
--- a/Core/HttpServer/HttpToolbox.h
+++ b/Core/HttpServer/HttpToolbox.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/IHttpHandler.h b/Core/HttpServer/IHttpHandler.h
index 0bc7f55..ba486c2 100644
--- a/Core/HttpServer/IHttpHandler.h
+++ b/Core/HttpServer/IHttpHandler.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/IHttpOutputStream.h b/Core/HttpServer/IHttpOutputStream.h
index 822aa7a..40c2e8b 100644
--- a/Core/HttpServer/IHttpOutputStream.h
+++ b/Core/HttpServer/IHttpOutputStream.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/IHttpStreamAnswer.h b/Core/HttpServer/IHttpStreamAnswer.h
index 0e5a54c..83455d7 100644
--- a/Core/HttpServer/IHttpStreamAnswer.h
+++ b/Core/HttpServer/IHttpStreamAnswer.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/IIncomingHttpRequestFilter.h b/Core/HttpServer/IIncomingHttpRequestFilter.h
index eff47af..da6025c 100644
--- a/Core/HttpServer/IIncomingHttpRequestFilter.h
+++ b/Core/HttpServer/IIncomingHttpRequestFilter.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -47,6 +48,7 @@ namespace Orthanc
                            const char* uri,
                            const char* ip,
                            const char* username,
-                           const IHttpHandler::Arguments& httpHeaders) const = 0;
+                           const IHttpHandler::Arguments& httpHeaders,
+                           const IHttpHandler::GetArguments& getArguments) const = 0;
   };
 }
diff --git a/Core/HttpServer/MongooseServer.cpp b/Core/HttpServer/MongooseServer.cpp
index 01b7a55..d89af62 100644
--- a/Core/HttpServer/MongooseServer.cpp
+++ b/Core/HttpServer/MongooseServer.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -651,7 +652,8 @@ namespace Orthanc
     const IIncomingHttpRequestFilter *filter = server.GetIncomingHttpRequestFilter();
     if (filter != NULL)
     {
-      if (!filter->IsAllowed(method, request->uri, remoteIp, username.c_str(), headers))
+      if (!filter->IsAllowed(method, request->uri, remoteIp,
+                             username.c_str(), headers, argumentsGET))
       {
         //output.SendUnauthorized(ORTHANC_REALM);
         output.SendStatus(HttpStatus_403_Forbidden);
diff --git a/Core/HttpServer/MongooseServer.h b/Core/HttpServer/MongooseServer.h
index 2e0e5ad..a482ca1 100644
--- a/Core/HttpServer/MongooseServer.h
+++ b/Core/HttpServer/MongooseServer.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/StringHttpOutput.cpp b/Core/HttpServer/StringHttpOutput.cpp
index 8e6699a..f9ab737 100644
--- a/Core/HttpServer/StringHttpOutput.cpp
+++ b/Core/HttpServer/StringHttpOutput.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/HttpServer/StringHttpOutput.h b/Core/HttpServer/StringHttpOutput.h
index fab996f..8b5c8f3 100644
--- a/Core/HttpServer/StringHttpOutput.h
+++ b/Core/HttpServer/StringHttpOutput.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/ICommand.h b/Core/ICommand.h
index a0805b9..221893e 100644
--- a/Core/ICommand.h
+++ b/Core/ICommand.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/IDynamicObject.h b/Core/IDynamicObject.h
index 8c36617..648acf4 100644
--- a/Core/IDynamicObject.h
+++ b/Core/IDynamicObject.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Images/Font.cpp b/Core/Images/Font.cpp
index 873d690..e063a5a 100644
--- a/Core/Images/Font.cpp
+++ b/Core/Images/Font.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Images/Font.h b/Core/Images/Font.h
index 825d2d8..3a91271 100644
--- a/Core/Images/Font.h
+++ b/Core/Images/Font.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Images/FontRegistry.cpp b/Core/Images/FontRegistry.cpp
index 3035b88..20b8013 100644
--- a/Core/Images/FontRegistry.cpp
+++ b/Core/Images/FontRegistry.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Images/FontRegistry.h b/Core/Images/FontRegistry.h
index ddaca49..e3519b0 100644
--- a/Core/Images/FontRegistry.h
+++ b/Core/Images/FontRegistry.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Images/IImageWriter.cpp b/Core/Images/IImageWriter.cpp
index b215080..479ee39 100644
--- a/Core/Images/IImageWriter.cpp
+++ b/Core/Images/IImageWriter.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Images/IImageWriter.h b/Core/Images/IImageWriter.h
index ca27010..d467c7f 100644
--- a/Core/Images/IImageWriter.h
+++ b/Core/Images/IImageWriter.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Images/Image.cpp b/Core/Images/Image.cpp
index 4212f6d..e60ab07 100644
--- a/Core/Images/Image.cpp
+++ b/Core/Images/Image.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Images/Image.h b/Core/Images/Image.h
index eba83c7..8d4cdac 100644
--- a/Core/Images/Image.h
+++ b/Core/Images/Image.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Images/ImageAccessor.cpp b/Core/Images/ImageAccessor.cpp
index eff8623..2c61674 100644
--- a/Core/Images/ImageAccessor.cpp
+++ b/Core/Images/ImageAccessor.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Images/ImageAccessor.h b/Core/Images/ImageAccessor.h
index 77e79c2..6033ce4 100644
--- a/Core/Images/ImageAccessor.h
+++ b/Core/Images/ImageAccessor.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Images/ImageBuffer.cpp b/Core/Images/ImageBuffer.cpp
index 71364dc..cfb3459 100644
--- a/Core/Images/ImageBuffer.cpp
+++ b/Core/Images/ImageBuffer.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Images/ImageBuffer.h b/Core/Images/ImageBuffer.h
index 21b1b15..1c2dbd3 100644
--- a/Core/Images/ImageBuffer.h
+++ b/Core/Images/ImageBuffer.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Images/ImageProcessing.cpp b/Core/Images/ImageProcessing.cpp
index 23c9fee..eea0a85 100644
--- a/Core/Images/ImageProcessing.cpp
+++ b/Core/Images/ImageProcessing.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -457,6 +458,26 @@ namespace Orthanc
       return;
     }
 
+    if (target.GetFormat() == PixelFormat_RGB24 &&
+        source.GetFormat() == PixelFormat_BGRA32)
+    {
+      for (unsigned int y = 0; y < source.GetHeight(); y++)
+      {
+        const uint8_t* p = reinterpret_cast<const uint8_t*>(source.GetConstRow(y));
+        uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
+        for (unsigned int x = 0; x < source.GetWidth(); x++)
+        {
+          q[0] = p[2];
+          q[1] = p[1];
+          q[2] = p[0];
+          p += 4;
+          q += 3;
+        }
+      }
+
+      return;
+    }
+
     if (target.GetFormat() == PixelFormat_RGBA32 &&
         source.GetFormat() == PixelFormat_RGB24)
     {
@@ -751,4 +772,29 @@ namespace Orthanc
         throw OrthancException(ErrorCode_NotImplemented);
     }
   }
+
+
+  void ImageProcessing::Invert(ImageAccessor& image)
+  {
+    switch (image.GetFormat())
+    {
+      case PixelFormat_Grayscale8:
+      {
+        for (unsigned int y = 0; y < image.GetHeight(); y++)
+        {
+          uint8_t* p = reinterpret_cast<uint8_t*>(image.GetRow(y));
+
+          for (unsigned int x = 0; x < image.GetWidth(); x++, p++)
+          {
+            *p = 255 - (*p);
+          }
+        }
+        
+        return;
+      }
+
+      default:
+        throw OrthancException(ErrorCode_NotImplemented);
+    }   
+  }
 }
diff --git a/Core/Images/ImageProcessing.h b/Core/Images/ImageProcessing.h
index 45176b5..8ee4297 100644
--- a/Core/Images/ImageProcessing.h
+++ b/Core/Images/ImageProcessing.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -72,5 +73,7 @@ namespace Orthanc
     static void ShiftScale(ImageAccessor& image,
                            float offset,
                            float scaling);
+
+    static void Invert(ImageAccessor& image);
   };
 }
diff --git a/Core/Images/JpegErrorManager.cpp b/Core/Images/JpegErrorManager.cpp
index 42c3842..00daea0 100644
--- a/Core/Images/JpegErrorManager.cpp
+++ b/Core/Images/JpegErrorManager.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Images/JpegErrorManager.h b/Core/Images/JpegErrorManager.h
index 610cd73..f149510 100644
--- a/Core/Images/JpegErrorManager.h
+++ b/Core/Images/JpegErrorManager.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Images/JpegReader.cpp b/Core/Images/JpegReader.cpp
index 9d6ea08..7d5c7e8 100644
--- a/Core/Images/JpegReader.cpp
+++ b/Core/Images/JpegReader.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Images/JpegReader.h b/Core/Images/JpegReader.h
index 978058c..105a9b8 100644
--- a/Core/Images/JpegReader.h
+++ b/Core/Images/JpegReader.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Images/JpegWriter.cpp b/Core/Images/JpegWriter.cpp
index 6ce0d63..1c62ac2 100644
--- a/Core/Images/JpegWriter.cpp
+++ b/Core/Images/JpegWriter.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Images/JpegWriter.h b/Core/Images/JpegWriter.h
index ffb6098..94341c4 100644
--- a/Core/Images/JpegWriter.h
+++ b/Core/Images/JpegWriter.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Images/PngReader.cpp b/Core/Images/PngReader.cpp
index 8315ca7..0227875 100644
--- a/Core/Images/PngReader.cpp
+++ b/Core/Images/PngReader.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Images/PngReader.h b/Core/Images/PngReader.h
index fd18d26..f07013d 100644
--- a/Core/Images/PngReader.h
+++ b/Core/Images/PngReader.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Images/PngWriter.cpp b/Core/Images/PngWriter.cpp
index 5603bcf..bf04e9a 100644
--- a/Core/Images/PngWriter.cpp
+++ b/Core/Images/PngWriter.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Images/PngWriter.h b/Core/Images/PngWriter.h
index 7d8b87f..691a579 100644
--- a/Core/Images/PngWriter.h
+++ b/Core/Images/PngWriter.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Logging.cpp b/Core/Logging.cpp
index cffdb5b..c1635a4 100644
--- a/Core/Logging.cpp
+++ b/Core/Logging.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -73,7 +74,79 @@ namespace Orthanc
   }
 }
 
-#else
+
+#elif ORTHANC_ENABLE_LOGGING_PLUGIN == 1
+
+/*********************************************************
+ * Logger compatible with the Orthanc plugin SDK
+ *********************************************************/
+
+#include <boost/lexical_cast.hpp>
+
+namespace Orthanc
+{
+  namespace Logging
+  {
+    static OrthancPluginContext* context_ = NULL;
+
+    void Initialize(OrthancPluginContext* context)
+    {
+      context_ = context;
+    }
+
+    InternalLogger::InternalLogger(const char* level,
+                                   const char* file  /* ignored */,
+                                   int line  /* ignored */) :
+      level_(level)
+    {
+    }
+
+    InternalLogger::~InternalLogger()
+    {
+      if (context_ != NULL)
+      {
+        if (level_ == "ERROR")
+        {
+          OrthancPluginLogError(context_, message_.c_str());
+        }
+        else if (level_ == "WARNING")
+        {
+          OrthancPluginLogWarning(context_, message_.c_str());
+        }
+        else if (level_ == "INFO")
+        {
+          OrthancPluginLogInfo(context_, message_.c_str());
+        }
+        else
+        {
+          std::string s = "Unknown log level (" + level_ + ") for message: " + message_;
+          OrthancPluginLogError(context_, s.c_str());
+        }
+      }
+    }
+
+    InternalLogger& InternalLogger::operator<< (const std::string& message)
+    {
+      message_ += message;
+      return *this;
+    }
+
+    InternalLogger& InternalLogger::operator<< (const char* message)
+    {
+      message_ += std::string(message);
+      return *this;
+    }
+
+    InternalLogger& InternalLogger::operator<< (int message)
+    {
+      message_ += boost::lexical_cast<std::string>(message);
+      return *this;
+    }
+  }
+}
+
+
+#else  /* ORTHANC_ENABLE_LOGGING_PLUGIN == 0 && ORTHANC_ENABLE_LOGGING == 1 */
 
 /*********************************************************
  * Internal logger of Orthanc, that mimics some
diff --git a/Core/Logging.h b/Core/Logging.h
index abec83f..8c419e2 100644
--- a/Core/Logging.h
+++ b/Core/Logging.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -38,11 +39,27 @@
 #  error The macro ORTHANC_ENABLE_LOGGING must be defined
 #endif
 
+#if !defined(ORTHANC_ENABLE_LOGGING_PLUGIN)
+#  if ORTHANC_ENABLE_LOGGING == 1
+#    error The macro ORTHANC_ENABLE_LOGGING_PLUGIN must be defined
+#  else
+#    define ORTHANC_ENABLE_LOGGING_PLUGIN 0
+#  endif
+#endif
+
+#if ORTHANC_ENABLE_LOGGING_PLUGIN == 1
+#  include <orthanc/OrthancCPlugin.h>
+#endif
+
 namespace Orthanc
 {
   namespace Logging
   {
+#if ORTHANC_ENABLE_LOGGING_PLUGIN == 1
+    void Initialize(OrthancPluginContext* context);
+#else
     void Initialize();
+#endif
 
     void Finalize();
 
@@ -86,7 +103,41 @@ namespace Orthanc
 #  define LOG(level)   ::Orthanc::Logging::NullStream()
 #  define VLOG(level)  ::Orthanc::Logging::NullStream()
 
-#else  /* ORTHANC_ENABLE_LOGGING == 1 */
+
+#elif ORTHANC_ENABLE_LOGGING_PLUGIN == 1
+
+#  include <boost/noncopyable.hpp>
+#  define LOG(level)  ::Orthanc::Logging::InternalLogger(#level,  __FILE__, __LINE__)
+#  define VLOG(level) ::Orthanc::Logging::InternalLogger("TRACE", __FILE__, __LINE__)
+
+namespace Orthanc
+{
+  namespace Logging
+  {
+    class InternalLogger : public boost::noncopyable
+    {
+    private:
+      std::string level_;
+      std::string message_;
+
+    public:
+      InternalLogger(const char* level,
+                     const char* file,
+                     int line);
+
+      ~InternalLogger();
+      
+      InternalLogger& operator<< (const std::string& message);
+
+      InternalLogger& operator<< (const char* message);
+
+      InternalLogger& operator<< (int message);
+    };
+  }
+}
+
+
+#else  /* ORTHANC_ENABLE_LOGGING_PLUGIN == 0 && ORTHANC_ENABLE_LOGGING == 1 */
 
 #  include <boost/thread/mutex.hpp>
 #  define LOG(level)  ::Orthanc::Logging::InternalLogger(#level,  __FILE__, __LINE__)
diff --git a/Core/Lua/LuaContext.cpp b/Core/Lua/LuaContext.cpp
index e6a7d63..d8e80b7 100644
--- a/Core/Lua/LuaContext.cpp
+++ b/Core/Lua/LuaContext.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -61,7 +62,6 @@ namespace Orthanc
     return true;
   }
   
-
   LuaContext& LuaContext::GetLuaContext(lua_State *state)
   {
     const void* value = GetGlobalVariable(state, "_LuaContext");
@@ -209,14 +209,36 @@ namespace Orthanc
     return true;
   }
 
+  void LuaContext::SetHttpHeaders(lua_State *state, int top)
+  {
+    this->httpClient_.ClearHeaders(); // always reset headers in case they have been set in a previous request
+
+    if (lua_gettop(state) >= top)
+    {
+      Json::Value headers;
+      this->GetJson(headers, top, true);
+
+      Json::Value::Members members = headers.getMemberNames();
+
+      for (Json::Value::Members::const_iterator 
+           it = members.begin(); it != members.end(); ++it)
+      {
+        this->httpClient_.AddHeader(*it, headers[*it].asString());
+      }
+    }
+
+  }
   
+
+
   int LuaContext::CallHttpGet(lua_State *state)
   {
     LuaContext& that = GetLuaContext(state);
 
     // Check the types of the arguments
     int nArgs = lua_gettop(state);
-    if (nArgs != 1 || !lua_isstring(state, 1))  // URL
+    if ((nArgs < 1 || nArgs > 2) ||         // check args count
+       !lua_isstring(state, 1))             // URL is a string
     {
       LOG(ERROR) << "Lua: Bad parameters to HttpGet()";
       lua_pushnil(state);
@@ -227,6 +249,8 @@ namespace Orthanc
     const char* url = lua_tostring(state, 1);
     that.httpClient_.SetMethod(HttpMethod_Get);
     that.httpClient_.SetUrl(url);
+    that.httpClient_.GetBody().clear();
+    that.SetHttpHeaders(state, 2);
 
     // Do the HTTP GET request
     if (!that.AnswerHttpQuery(state))
@@ -246,9 +270,9 @@ namespace Orthanc
 
     // Check the types of the arguments
     int nArgs = lua_gettop(state);
-    if ((nArgs != 1 && nArgs != 2) ||
-        !lua_isstring(state, 1) ||                // URL
-        (nArgs >= 2 && !lua_isstring(state, 2)))  // Body data
+    if ((nArgs < 1 || nArgs > 3) ||                 // check arg count
+        !lua_isstring(state, 1) ||                  // URL is a string
+        (nArgs >= 2 && (!lua_isstring(state, 2) && !lua_isnil(state, 2))))    // Body data is null or is a string
     {
       LOG(ERROR) << "Lua: Bad parameters to HttpPost() or HttpPut()";
       lua_pushnil(state);
@@ -259,8 +283,9 @@ namespace Orthanc
     const char* url = lua_tostring(state, 1);
     that.httpClient_.SetMethod(method);
     that.httpClient_.SetUrl(url);
+    that.SetHttpHeaders(state, 3);
 
-    if (nArgs >= 2)
+    if (nArgs >= 2 && !lua_isnil(state, 2))
     {
       that.httpClient_.SetBody(lua_tostring(state, 2));
     }
@@ -298,7 +323,7 @@ namespace Orthanc
 
     // Check the types of the arguments
     int nArgs = lua_gettop(state);
-    if (nArgs != 1 || !lua_isstring(state, 1))  // URL
+    if (nArgs < 1 || nArgs > 2 || !lua_isstring(state, 1))  // URL
     {
       LOG(ERROR) << "Lua: Bad parameters to HttpDelete()";
       lua_pushnil(state);
@@ -309,6 +334,8 @@ namespace Orthanc
     const char* url = lua_tostring(state, 1);
     that.httpClient_.SetMethod(HttpMethod_Delete);
     that.httpClient_.SetUrl(url);
+    that.httpClient_.GetBody().clear();
+    that.SetHttpHeaders(state, 2);
 
     // Do the HTTP DELETE request
     std::string s;
diff --git a/Core/Lua/LuaContext.h b/Core/Lua/LuaContext.h
index bd08b1b..ac51591 100644
--- a/Core/Lua/LuaContext.h
+++ b/Core/Lua/LuaContext.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -32,6 +33,14 @@
 
 #pragma once
 
+#if !defined(ORTHANC_ENABLE_LUA)
+#  error The macro ORTHANC_ENABLE_LUA must be defined
+#endif
+
+#if ORTHANC_ENABLE_LUA == 0
+#  error The Lua support is disabled, cannot include this file
+#endif
+
 #include "../HttpClient.h"
 
 extern "C" 
@@ -74,6 +83,8 @@ namespace Orthanc
     void GetJson(Json::Value& result,
                  int top,
                  bool keepStrings);
+
+    void SetHttpHeaders(lua_State* state, int top);
     
   public:
     LuaContext();
diff --git a/Core/Lua/LuaFunctionCall.cpp b/Core/Lua/LuaFunctionCall.cpp
index a52afe6..74e5137 100644
--- a/Core/Lua/LuaFunctionCall.cpp
+++ b/Core/Lua/LuaFunctionCall.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Lua/LuaFunctionCall.h b/Core/Lua/LuaFunctionCall.h
index a4cdc38..93c5977 100644
--- a/Core/Lua/LuaFunctionCall.h
+++ b/Core/Lua/LuaFunctionCall.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/MultiThreading/BagOfTasks.h b/Core/MultiThreading/BagOfTasks.h
index 7b992f6..20fc8e1 100644
--- a/Core/MultiThreading/BagOfTasks.h
+++ b/Core/MultiThreading/BagOfTasks.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/MultiThreading/BagOfTasksProcessor.cpp b/Core/MultiThreading/BagOfTasksProcessor.cpp
index c409f1c..28fdd30 100644
--- a/Core/MultiThreading/BagOfTasksProcessor.cpp
+++ b/Core/MultiThreading/BagOfTasksProcessor.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/MultiThreading/BagOfTasksProcessor.h b/Core/MultiThreading/BagOfTasksProcessor.h
index a0dff6e..dc7c2ca 100644
--- a/Core/MultiThreading/BagOfTasksProcessor.h
+++ b/Core/MultiThreading/BagOfTasksProcessor.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/MultiThreading/ILockable.h b/Core/MultiThreading/ILockable.h
index 9e2e6bf..66b45cc 100644
--- a/Core/MultiThreading/ILockable.h
+++ b/Core/MultiThreading/ILockable.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/MultiThreading/IRunnableBySteps.h b/Core/MultiThreading/IRunnableBySteps.h
index 4d91f17..977f9db 100644
--- a/Core/MultiThreading/IRunnableBySteps.h
+++ b/Core/MultiThreading/IRunnableBySteps.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/MultiThreading/Locker.h b/Core/MultiThreading/Locker.h
index 4f38409..b71893c 100644
--- a/Core/MultiThreading/Locker.h
+++ b/Core/MultiThreading/Locker.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/MultiThreading/Mutex.cpp b/Core/MultiThreading/Mutex.cpp
index 35cc732..f15cc31 100644
--- a/Core/MultiThreading/Mutex.cpp
+++ b/Core/MultiThreading/Mutex.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/MultiThreading/Mutex.h b/Core/MultiThreading/Mutex.h
index bbcbebf..8649c55 100644
--- a/Core/MultiThreading/Mutex.h
+++ b/Core/MultiThreading/Mutex.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/MultiThreading/ReaderWriterLock.cpp b/Core/MultiThreading/ReaderWriterLock.cpp
index 25bc231..d92193c 100644
--- a/Core/MultiThreading/ReaderWriterLock.cpp
+++ b/Core/MultiThreading/ReaderWriterLock.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/MultiThreading/ReaderWriterLock.h b/Core/MultiThreading/ReaderWriterLock.h
index 899b3d3..7bd23dc 100644
--- a/Core/MultiThreading/ReaderWriterLock.h
+++ b/Core/MultiThreading/ReaderWriterLock.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/MultiThreading/RunnableWorkersPool.cpp b/Core/MultiThreading/RunnableWorkersPool.cpp
index f688e91..f48c863 100644
--- a/Core/MultiThreading/RunnableWorkersPool.cpp
+++ b/Core/MultiThreading/RunnableWorkersPool.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -76,6 +77,10 @@ namespace Orthanc
           {
             LOG(ERROR) << "Not enough memory to handle some runnable object";
           }
+          catch (std::exception& e)
+          {
+            LOG(ERROR) << "std::exception while handling some runnable object: " << e.what();
+          }
           catch (...)
           {
             LOG(ERROR) << "Native exception while handling some runnable object";
diff --git a/Core/MultiThreading/RunnableWorkersPool.h b/Core/MultiThreading/RunnableWorkersPool.h
index 9bd2a2b..376d8d5 100644
--- a/Core/MultiThreading/RunnableWorkersPool.h
+++ b/Core/MultiThreading/RunnableWorkersPool.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/MultiThreading/Semaphore.cpp b/Core/MultiThreading/Semaphore.cpp
index 82d5aa5..7d1b0de 100644
--- a/Core/MultiThreading/Semaphore.cpp
+++ b/Core/MultiThreading/Semaphore.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/MultiThreading/Semaphore.h b/Core/MultiThreading/Semaphore.h
index 31e1392..86cf3c3 100644
--- a/Core/MultiThreading/Semaphore.h
+++ b/Core/MultiThreading/Semaphore.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/MultiThreading/SharedMessageQueue.cpp b/Core/MultiThreading/SharedMessageQueue.cpp
index 0c1a727..9920593 100644
--- a/Core/MultiThreading/SharedMessageQueue.cpp
+++ b/Core/MultiThreading/SharedMessageQueue.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/MultiThreading/SharedMessageQueue.h b/Core/MultiThreading/SharedMessageQueue.h
index 211b774..b5bb062 100644
--- a/Core/MultiThreading/SharedMessageQueue.h
+++ b/Core/MultiThreading/SharedMessageQueue.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/OrthancException.h b/Core/OrthancException.h
index d5544dd..ee9b603 100644
--- a/Core/OrthancException.h
+++ b/Core/OrthancException.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Pkcs11.cpp b/Core/Pkcs11.cpp
index 613a464..e008237 100644
--- a/Core/Pkcs11.cpp
+++ b/Core/Pkcs11.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Pkcs11.h b/Core/Pkcs11.h
index f2e1cba..1e94407 100644
--- a/Core/Pkcs11.h
+++ b/Core/Pkcs11.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/PrecompiledHeaders.cpp b/Core/PrecompiledHeaders.cpp
index 01ea20f..a18e764 100644
--- a/Core/PrecompiledHeaders.cpp
+++ b/Core/PrecompiledHeaders.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/PrecompiledHeaders.h b/Core/PrecompiledHeaders.h
index 1422e30..4fc6435 100644
--- a/Core/PrecompiledHeaders.h
+++ b/Core/PrecompiledHeaders.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/RestApi/RestApi.cpp b/Core/RestApi/RestApi.cpp
index f9e6fa7..c3f0257 100644
--- a/Core/RestApi/RestApi.cpp
+++ b/Core/RestApi/RestApi.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/RestApi/RestApi.h b/Core/RestApi/RestApi.h
index 467970a..2fa2f6e 100644
--- a/Core/RestApi/RestApi.h
+++ b/Core/RestApi/RestApi.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/RestApi/RestApiCall.cpp b/Core/RestApi/RestApiCall.cpp
index 822c772..13b7bf6 100644
--- a/Core/RestApi/RestApiCall.cpp
+++ b/Core/RestApi/RestApiCall.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/RestApi/RestApiCall.h b/Core/RestApi/RestApiCall.h
index 454c75c..5144cfc 100644
--- a/Core/RestApi/RestApiCall.h
+++ b/Core/RestApi/RestApiCall.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/RestApi/RestApiDeleteCall.h b/Core/RestApi/RestApiDeleteCall.h
index d1a2439..d409ee8 100644
--- a/Core/RestApi/RestApiDeleteCall.h
+++ b/Core/RestApi/RestApiDeleteCall.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/RestApi/RestApiGetCall.cpp b/Core/RestApi/RestApiGetCall.cpp
index ecd4afa..70e0faa 100644
--- a/Core/RestApi/RestApiGetCall.cpp
+++ b/Core/RestApi/RestApiGetCall.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/RestApi/RestApiGetCall.h b/Core/RestApi/RestApiGetCall.h
index 1d0c05e..e33318c 100644
--- a/Core/RestApi/RestApiGetCall.h
+++ b/Core/RestApi/RestApiGetCall.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/RestApi/RestApiHierarchy.cpp b/Core/RestApi/RestApiHierarchy.cpp
index 3b7274d..bae3f5a 100644
--- a/Core/RestApi/RestApiHierarchy.cpp
+++ b/Core/RestApi/RestApiHierarchy.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/RestApi/RestApiHierarchy.h b/Core/RestApi/RestApiHierarchy.h
index 0510951..ae618a4 100644
--- a/Core/RestApi/RestApiHierarchy.h
+++ b/Core/RestApi/RestApiHierarchy.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/RestApi/RestApiOutput.cpp b/Core/RestApi/RestApiOutput.cpp
index c9901c4..b20711f 100644
--- a/Core/RestApi/RestApiOutput.cpp
+++ b/Core/RestApi/RestApiOutput.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/RestApi/RestApiOutput.h b/Core/RestApi/RestApiOutput.h
index d6bf6b8..5bc7838 100644
--- a/Core/RestApi/RestApiOutput.h
+++ b/Core/RestApi/RestApiOutput.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/RestApi/RestApiPath.cpp b/Core/RestApi/RestApiPath.cpp
index cb2f63f..d7a8b6d 100644
--- a/Core/RestApi/RestApiPath.cpp
+++ b/Core/RestApi/RestApiPath.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/RestApi/RestApiPath.h b/Core/RestApi/RestApiPath.h
index d60bc75..317277c 100644
--- a/Core/RestApi/RestApiPath.h
+++ b/Core/RestApi/RestApiPath.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/RestApi/RestApiPostCall.h b/Core/RestApi/RestApiPostCall.h
index 4a36609..13a3d01 100644
--- a/Core/RestApi/RestApiPostCall.h
+++ b/Core/RestApi/RestApiPostCall.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/RestApi/RestApiPutCall.h b/Core/RestApi/RestApiPutCall.h
index 27bc6f3..41e9043 100644
--- a/Core/RestApi/RestApiPutCall.h
+++ b/Core/RestApi/RestApiPutCall.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/SQLite/Connection.h b/Core/SQLite/Connection.h
index b58c42c..140ae4c 100644
--- a/Core/SQLite/Connection.h
+++ b/Core/SQLite/Connection.h
@@ -39,13 +39,11 @@
 
 #include "Statement.h"
 #include "IScalarFunction.h"
+#include "SQLiteTypes.h"
 
 #include <string>
 #include <map>
 
-struct sqlite3;
-struct sqlite3_stmt;
-
 #define SQLITE_FROM_HERE ::Orthanc::SQLite::StatementId(__FILE__, __LINE__)
 
 namespace Orthanc
diff --git a/Core/SQLite/FunctionContext.cpp b/Core/SQLite/FunctionContext.cpp
index a953f2f..71950ac 100644
--- a/Core/SQLite/FunctionContext.cpp
+++ b/Core/SQLite/FunctionContext.cpp
@@ -49,7 +49,7 @@ namespace Orthanc
   {
     FunctionContext::FunctionContext(struct sqlite3_context* context,
                                      int argc,
-                                     struct ::Mem** argv)
+                                     Internals::SQLiteValue** argv)
     {
       assert(context != NULL);
       assert(argc >= 0);
diff --git a/Core/SQLite/FunctionContext.h b/Core/SQLite/FunctionContext.h
index 243a518..3d0f994 100644
--- a/Core/SQLite/FunctionContext.h
+++ b/Core/SQLite/FunctionContext.h
@@ -36,9 +36,6 @@
 
 #include "Statement.h"
 
-struct sqlite3_context;
-struct Mem;  // This corresponds to the opaque type "sqlite3_value"
- 
 namespace Orthanc
 {
   namespace SQLite
@@ -50,14 +47,14 @@ namespace Orthanc
     private:
       struct sqlite3_context* context_;
       unsigned int argc_;
-      struct ::Mem** argv_;
+      Internals::SQLiteValue** argv_;
 
       void CheckIndex(unsigned int index) const;
 
     public:
       FunctionContext(struct sqlite3_context* context,
                       int argc,
-                      struct ::Mem** argv);
+                      Internals::SQLiteValue** argv);
 
       ColumnType GetColumnType(unsigned int index) const;
  
diff --git a/Core/SQLite/FunctionContext.h b/Core/SQLite/SQLiteTypes.h
similarity index 62%
copy from Core/SQLite/FunctionContext.h
copy to Core/SQLite/SQLiteTypes.h
index 243a518..f6a5117 100644
--- a/Core/SQLite/FunctionContext.h
+++ b/Core/SQLite/SQLiteTypes.h
@@ -34,55 +34,40 @@
 
 #pragma once
 
-#include "Statement.h"
-
+struct sqlite3;
 struct sqlite3_context;
-struct Mem;  // This corresponds to the opaque type "sqlite3_value"
- 
+struct sqlite3_stmt;
+
+#if !defined(ORTHANC_SQLITE_VERSION)
+#error  Please define macro ORTHANC_SQLITE_VERSION
+#endif
+
+
+/**
+ * "sqlite3_value" is defined as:
+ * - "typedef struct Mem sqlite3_value;" up to SQLite <= 3.18.2
+ * - "typedef struct sqlite3_value sqlite3_value;" since SQLite >= 3.19.0.
+ * We create our own copy of this typedef to get around this API incompatibility.
+ * https://github.com/mackyle/sqlite/commit/db1d90df06a78264775a14d22c3361eb5b42be17
+ **/
+      
+#if ORTHANC_SQLITE_VERSION < 3019000
+struct Mem;
+#else
+struct sqlite3_value;
+#endif
+
 namespace Orthanc
 {
   namespace SQLite
   {
-    class FunctionContext : public NonCopyable
+    namespace Internals
     {
-      friend class Connection;
-
-    private:
-      struct sqlite3_context* context_;
-      unsigned int argc_;
-      struct ::Mem** argv_;
-
-      void CheckIndex(unsigned int index) const;
-
-    public:
-      FunctionContext(struct sqlite3_context* context,
-                      int argc,
-                      struct ::Mem** argv);
-
-      ColumnType GetColumnType(unsigned int index) const;
- 
-      unsigned int GetParameterCount() const
-      {
-        return argc_;
-      }
-
-      int GetIntValue(unsigned int index) const;
-
-      int64_t GetInt64Value(unsigned int index) const;
-
-      double GetDoubleValue(unsigned int index) const;
-
-      std::string GetStringValue(unsigned int index) const;
-
-      bool IsNullValue(unsigned int index) const;
-  
-      void SetNullResult();
-
-      void SetIntResult(int value);
-
-      void SetDoubleResult(double value);
-
-      void SetStringResult(const std::string& str);
-    };
+#if ORTHANC_SQLITE_VERSION < 3019000
+      typedef struct ::Mem  SQLiteValue;
+#else
+      typedef struct ::sqlite3_value  SQLiteValue;
+#endif
+    }
   }
 }
diff --git a/Core/SQLite/Statement.h b/Core/SQLite/Statement.h
index f48af30..24b14c3 100644
--- a/Core/SQLite/Statement.h
+++ b/Core/SQLite/Statement.h
@@ -49,8 +49,6 @@
 #include <gtest/gtest_prod.h>
 #endif
 
-struct sqlite3_stmt;
-
 
 namespace Orthanc
 {
diff --git a/Core/SQLite/StatementReference.h b/Core/SQLite/StatementReference.h
index db121dc..9931972 100644
--- a/Core/SQLite/StatementReference.h
+++ b/Core/SQLite/StatementReference.h
@@ -38,13 +38,12 @@
 #pragma once
 
 #include "NonCopyable.h"
+#include "SQLiteTypes.h"
 
 #include <stdint.h>
 #include <cassert>
 #include <stdlib.h>
 
-struct sqlite3;
-struct sqlite3_stmt;
 
 namespace Orthanc
 {
diff --git a/Core/SystemToolbox.cpp b/Core/SystemToolbox.cpp
index e22a006..5fc53ae 100644
--- a/Core/SystemToolbox.cpp
+++ b/Core/SystemToolbox.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -123,7 +124,7 @@ namespace Orthanc
     barrierEvent_ = ServerBarrierEvent_Stop;
     while (!(*stopFlag || finish_))
     {
-      Toolbox::USleep(100 * 1000);
+      SystemToolbox::USleep(100 * 1000);
     }
 
 #if defined(_WIN32)
@@ -152,6 +153,18 @@ namespace Orthanc
   }
 
 
+  void SystemToolbox::USleep(uint64_t microSeconds)
+  {
+#if defined(_WIN32)
+    ::Sleep(static_cast<DWORD>(microSeconds / static_cast<uint64_t>(1000)));
+#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) || defined(__native_client__)
+    usleep(microSeconds);
+#else
+#error Support your platform here
+#endif
+  }
+
+
   static std::streamsize GetStreamSize(std::istream& f)
   {
     // http://www.cplusplus.com/reference/iostream/istream/tellg/
@@ -180,7 +193,7 @@ namespace Orthanc
     }
 
     std::streamsize size = GetStreamSize(f);
-    content.resize(size);
+    content.resize(static_cast<size_t>(size));
     if (size != 0)
     {
       f.read(reinterpret_cast<char*>(&content[0]), size);
@@ -218,7 +231,7 @@ namespace Orthanc
       }
       else if (static_cast<size_t>(size) < headerSize)
       {
-        headerSize = size;  // Truncate to the size of the file
+        headerSize = static_cast<size_t>(size);  // Truncate to the size of the file
         full = false;
       }
     }
diff --git a/Core/SystemToolbox.h b/Core/SystemToolbox.h
index e62b529..0b3fe3f 100644
--- a/Core/SystemToolbox.h
+++ b/Core/SystemToolbox.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -50,6 +51,8 @@ namespace Orthanc
 {
   namespace SystemToolbox
   {
+    void USleep(uint64_t microSeconds);
+
     ServerBarrierEvent ServerBarrier(const bool& stopFlag);
 
     ServerBarrierEvent ServerBarrier();
diff --git a/Core/TemporaryFile.cpp b/Core/TemporaryFile.cpp
index 955489b..63f7134 100644
--- a/Core/TemporaryFile.cpp
+++ b/Core/TemporaryFile.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/TemporaryFile.h b/Core/TemporaryFile.h
index 1dd4f73..0482589 100644
--- a/Core/TemporaryFile.h
+++ b/Core/TemporaryFile.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Core/Toolbox.cpp b/Core/Toolbox.cpp
index cb9bcb2..74b3c57 100644
--- a/Core/Toolbox.cpp
+++ b/Core/Toolbox.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -36,11 +37,12 @@
 #include "OrthancException.h"
 #include "Logging.h"
 
+#include <boost/algorithm/string/case_conv.hpp>
 #include <boost/algorithm/string/replace.hpp>
 #include <boost/lexical_cast.hpp>
 #include <boost/locale.hpp>
 #include <boost/uuid/sha1.hpp>
-
+ 
 #include <string>
 #include <stdint.h>
 #include <string.h>
@@ -90,18 +92,6 @@ extern "C"
 
 namespace Orthanc
 {
-  void Toolbox::USleep(uint64_t microSeconds)
-  {
-#if defined(_WIN32)
-    ::Sleep(static_cast<DWORD>(microSeconds / static_cast<uint64_t>(1000)));
-#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__) || defined(__native_client__)
-    usleep(microSeconds);
-#else
-#error Support your platform here
-#endif
-  }
-
-
   void Toolbox::ToUpperCase(std::string& s)
   {
     std::transform(s.begin(), s.end(), s.begin(), toupper);
@@ -1262,4 +1252,122 @@ namespace Orthanc
 
     return IsUuid(str.substr(0, 36));
   }
+
+
+  static std::auto_ptr<std::locale>  globalLocale_;
+
+  static bool SetGlobalLocale(const char* locale)
+  {
+    globalLocale_.reset(NULL);
+
+    try
+    {
+      if (locale == NULL)
+      {
+        LOG(WARNING) << "Falling back to system-wide default locale";
+        globalLocale_.reset(new std::locale());
+      }
+      else
+      {
+        LOG(INFO) << "Using locale: \"" << locale << "\" for case-insensitive comparison of strings";
+        globalLocale_.reset(new std::locale(locale));
+      }
+    }
+    catch (std::runtime_error&)
+    {
+    }
+
+    return (globalLocale_.get() != NULL);
+  }
+  
+  void Toolbox::InitializeGlobalLocale(const char* locale)
+  {
+    // Make Orthanc use English, United States locale
+    // Linux: use "en_US.UTF-8"
+    // Windows: use ""
+    // Wine: use NULL
+    
+#if defined(__MINGW32__)
+    // Visibly, there is no support of locales in MinGW yet
+    // http://mingw.5.n7.nabble.com/How-to-use-std-locale-global-with-MinGW-correct-td33048.html
+    static const char* DEFAULT_LOCALE = NULL;
+#elif defined(_WIN32)
+    // For Windows: use default locale (using "en_US" does not work)
+    static const char* DEFAULT_LOCALE = "";
+#else
+    // For Linux & cie
+    static const char* DEFAULT_LOCALE = "en_US.UTF-8";
+#endif
+
+    bool ok;
+    
+    if (locale == NULL)
+    {
+      ok = SetGlobalLocale(DEFAULT_LOCALE);
+
+#if defined(__MINGW32__)
+      LOG(WARNING) << "This is a MinGW build, case-insensitive comparison of "
+                   << "strings with accents will not work outside of Wine";
+#endif
+    }
+    else
+    {
+      ok = SetGlobalLocale(locale);
+    }
+
+    if (!ok &&
+        !SetGlobalLocale(NULL))
+    {
+      LOG(ERROR) << "Cannot initialize global locale";
+      throw OrthancException(ErrorCode_InternalError);
+    }
+
+  }
+
+
+  void Toolbox::FinalizeGlobalLocale()
+  {
+    globalLocale_.reset();
+  }
+
+  
+  std::string Toolbox::ToUpperCaseWithAccents(const std::string& source)
+  {
+    if (globalLocale_.get() == NULL)
+    {
+      LOG(ERROR) << "No global locale was set, call Toolbox::InitializeGlobalLocale()";
+      throw OrthancException(ErrorCode_BadSequenceOfCalls);
+    }
+
+    /**
+     * A few notes about locales:
+     *
+     * (1) We don't use "case folding":
+     * http://www.boost.org/doc/libs/1_64_0/libs/locale/doc/html/conversions.html
+     *
+     * Characters are made uppercase one by one. This is because, in
+     * static builds, we are using iconv, which is visibly not
+     * supported correctly (TODO: Understand why). Case folding seems
+     * to be working correctly if using the default backend under
+     * Linux (ICU or POSIX?). If one wishes to use case folding, one
+     * would use:
+     *
+     *   boost::locale::generator gen;
+     *   std::locale::global(gen(DEFAULT_LOCALE));
+     *   return boost::locale::to_upper(source);
+     *
+     * (2) The function "boost::algorithm::to_upper_copy" does not
+     * make use of the "std::locale::global()". We therefore create a
+     * global variable "globalLocale_".
+     * 
+     * (3) The variant of "boost::algorithm::to_upper_copy()" that
+     * uses std::string does not work properly. We need to apply it
+     * one wide strings (std::wstring). This explains the two calls to
+     * "utf_to_utf" in order to convert to/from std::wstring.
+     **/
+
+    std::wstring w = boost::locale::conv::utf_to_utf<wchar_t>(source);
+    w = boost::algorithm::to_upper_copy<std::wstring>(w, *globalLocale_);
+    return boost::locale::conv::utf_to_utf<char>(w);
+  }
 }
diff --git a/Core/Toolbox.h b/Core/Toolbox.h
index d32777a..f0a9623 100644
--- a/Core/Toolbox.h
+++ b/Core/Toolbox.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -78,8 +79,6 @@ namespace Orthanc
 
   namespace Toolbox
   {
-    void USleep(uint64_t microSeconds);
-
     void ToUpperCase(std::string& s);  // Inplace version
 
     void ToLowerCase(std::string& s);  // Inplace version
@@ -207,5 +206,11 @@ namespace Orthanc
     bool IsUuid(const std::string& str);
 
     bool StartsWithUuid(const std::string& str);
+
+    void InitializeGlobalLocale(const char* locale);
+
+    void FinalizeGlobalLocale();
+
+    std::string ToUpperCaseWithAccents(const std::string& source);
   }
 }
diff --git a/Core/WebServiceParameters.cpp b/Core/WebServiceParameters.cpp
index cef2e26..2d44a85 100644
--- a/Core/WebServiceParameters.cpp
+++ b/Core/WebServiceParameters.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -34,7 +35,6 @@
 #include "WebServiceParameters.h"
 
 #include "../Core/Logging.h"
-#include "../Core/Toolbox.h"
 #include "../Core/OrthancException.h"
 
 #if ORTHANC_SANDBOXED == 0
diff --git a/Core/WebServiceParameters.h b/Core/WebServiceParameters.h
index b6b373f..5249f85 100644
--- a/Core/WebServiceParameters.h
+++ b/Core/WebServiceParameters.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/NEWS b/NEWS
index 16a0800..92dc78c 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,66 @@ Pending changes in the mainline
 ===============================
 
 
+Version 1.3.0 (2017-07-19)
+==========================
+
+General
+-------
+
+* Orthanc now anonymizes according to Basic Profile of PS 3.15-2017c Table E.1-1
+* In the "DicomModalities" configuration:
+  - Manufacturer type MedInria is now obsolete
+  - Manufacturer types AgfaImpax and SyngoVia are obsolete too
+    (use GenericNoWildcardInDates instead)
+  - Obsolete manufacturers are still accepted but might disappear in the future
+  - Added new manufacturer: GenericNoUniversalWildcard to replace all '*' by '' in
+    outgoing C-Find requests
+* New security-related options: "DicomAlwaysAllowStore" and "DicomCheckModalityHost"
+
+REST API
+--------
+
+* Argument "Since" in URI "/tools/find" (related to issue 53)
+* Argument "DicomVersion" in URIs "/{...}/{...}/anonymization"
+
+Plugins
+-------
+
+* New function: "OrthancPluginRegisterIncomingHttpRequestFilter2()"
+
+Lua
+---
+
+* Added HTTP headers support for Lua HttpPost/HttpGet/HttpPut/HttpDelete
+
+Orthanc Explorer
+----------------
+
+* Query/retrieve: Added button for "DR" modality
+
+Maintenance
+-----------
+
+* Ability to retrieve raw frames encoded as unsigned 32-bits integers
+* Fix issue 29 (more consistent handling of the "--upgrade" argument)
+* Fix issue 31 (create new modality types for Philips ADW, GE Xeleris, GE AWServer)
+* Fix issue 35 (AET name is not transferred to Orthanc using DCMTK 3.6.0)
+* Fix issue 44 (bad interpretation of photometric interpretation MONOCHROME1)
+* Fix issue 45 (crash when providing a folder to "--config" command-line option)
+* Fix issue 46 (PHI remaining after anonymization)
+* Fix issue 49 (worklists: accentuated characters are removed from C-Find responses)
+* Fix issue 52 (DICOM level security association problems)
+* Fix issue 55 (modification/anonymization of tags that might break the database
+  model now requires the "Force" parameter to be set to "true" in the query)
+* Fix issue 56 (case-insensitive matching over accents)
+* Fix Debian #865606 (orthanc FTBFS with libdcmtk-dev 3.6.1~20170228-2)
+* Fix XSS inside DICOM in Orthanc Explorer (as reported by Victor Pasnkel, Morphus Labs)
+* Upgrade to DCMTK 3.6.2 in static builds (released on 2017-07-17)
+* Upgrade to Boost 1.64.0 in static builds
+* New advanced "Locale" configuration option
+* Removed configuration option "USE_DCMTK_361_PRIVATE_DIC"
+
+
 Version 1.2.0 (2016/12/13)
 ==========================
 
@@ -51,6 +111,9 @@ Maintenance
 * Ignore "Group Length" tags in C-FIND queries
 * Fix handling of worklist SCP with ReferencedStudySequence and ReferencedPatientSequence
 * Fix handling of Move Originator AET and ID in C-MOVE SCP
+* Fix vulnerability ZSL-2016-5379 "Unquoted Service Path Privilege Escalation" in the
+  Windows service
+* Fix vulnerability ZSL-2016-5380 "Remote Memory Corruption Vulnerability" in DCMTK 3.6.0
 
 
 Version 1.1.0 (2016/06/27)
diff --git a/OrthancExplorer/explorer.html b/OrthancExplorer/explorer.html
index fa3d77d..652065e 100644
--- a/OrthancExplorer/explorer.html
+++ b/OrthancExplorer/explorer.html
@@ -349,6 +349,7 @@
 	        <input type="checkbox" name="PT" id="qr-pt" class="custom" /> <label for="qr-pt">PT</label>
 	        <input type="checkbox" name="US" id="qr-us" class="custom" /> <label for="qr-us">US</label>
 	        <input type="checkbox" name="XA" id="qr-xa" class="custom" /> <label for="qr-xa">XA</label>
+	        <input type="checkbox" name="DR" id="qr-dr" class="custom" /> <label for="qr-dr">DR</label>
 	      </fieldset>
             </div>
           </div>
diff --git a/OrthancExplorer/explorer.js b/OrthancExplorer/explorer.js
index 4d70a7b..684d499 100644
--- a/OrthancExplorer/explorer.js
+++ b/OrthancExplorer/explorer.js
@@ -17,19 +17,6 @@ var currentPage = '';
 var currentUuid = '';
 
 
-// http://stackoverflow.com/a/4673436
-String.prototype.format = function() {
-  var args = arguments;
-  return this.replace(/{(\d+)}/g, function(match, number) { 
-    /*return typeof args[number] != 'undefined'
-      ? args[number]
-      : match;*/
-
-    return args[number];
-  });
-};
-
-
 function DeepCopy(obj)
 {
   return jQuery.extend(true, {}, obj);
@@ -209,29 +196,34 @@ function GetResource(uri, callback)
 }
 
 
-function CompleteFormatting(s, link, isReverse)
+function CompleteFormatting(node, link, isReverse, count)
 {
+  if (count != null)
+  {
+    node = node.add($('<span>')
+                    .addClass('ui-li-count')
+                    .text(count));
+  }
+  
   if (link != null)
   {
-    s = 'href="' + link + '">' + s + '</a>';
-    
-    if (isReverse)
-      s = 'data-direction="reverse" '+ s;
+    node = $('<a>').attr('href', link).append(node);
 
-    s = '<a ' + s;
+    if (isReverse)
+      node.attr('data-direction', 'reverse')
   }
 
+  node = $('<li>').append(node);
+
   if (isReverse)
-    return '<li data-icon="back">' + s + '</li>';
-  else
-    return '<li>' + s + '</li>';
+    node.attr('data-icon', 'back');
+
+  return node;
 }
 
 
-function FormatMainDicomTags(tags, tagsToIgnore)
+function FormatMainDicomTags(target, tags, tagsToIgnore)
 {
-  var s = '';
-
   for (var i in tags)
   {
     if (tagsToIgnore.indexOf(i) == -1)
@@ -250,47 +242,38 @@ function FormatMainDicomTags(tags, tagsToIgnore)
         v = SplitLongUid(v);
       }
       
-
-      s += ('<p>{0}: <strong>{1}</strong></p>').format(i, v);
+      target.append($('<p>')
+                    .text(i + ': ')
+                    .append($('<strong>').text(v)));
     }
   }
-
-  return s;
 }
 
 
 function FormatPatient(patient, link, isReverse)
 {
-  var s = ('<h3>{0}</h3>{1}' + 
-           '<span class="ui-li-count">{2}</span>'
-          ).format
-  (patient.MainDicomTags.PatientName,
-   FormatMainDicomTags(patient.MainDicomTags, [ 
-     "PatientName"
-     /*"OtherPatientIDs" */
-   ]),
-   patient.Studies.length
-  );
+  var node = $('<div>').append($('<h3>').text(patient.MainDicomTags.PatientName));
 
-  return CompleteFormatting(s, link, isReverse);
+  FormatMainDicomTags(node, patient.MainDicomTags, [ 
+    "PatientName"
+    // "OtherPatientIDs"
+  ]);
+    
+  return CompleteFormatting(node, link, isReverse, patient.Studies.length);
 }
 
 
 
 function FormatStudy(study, link, isReverse)
 {
-  var s = ('<h3>{0}</h3>{1}' +
-           '<span class="ui-li-count">{2}</span>'
-           ).format
-  (study.MainDicomTags.StudyDescription,
-   FormatMainDicomTags(study.MainDicomTags, [
+  var node = $('<div>').append($('<h3>').text(study.MainDicomTags.StudyDescription));
+
+  FormatMainDicomTags(node, study.MainDicomTags, [ 
      "StudyDescription", 
      "StudyTime" 
-   ]),
-   study.Series.length
-  );
-
-  return CompleteFormatting(s, link, isReverse);
+  ]);
+    
+  return CompleteFormatting(node, link, isReverse, study.Series.length);
 }
 
 
@@ -307,41 +290,39 @@ function FormatSeries(series, link, isReverse)
   {
     c = series.Instances.length + '/' + series.ExpectedNumberOfInstances;
   }
+  
+  var node = $('<div>')
+      .append($('<h3>').text(series.MainDicomTags.SeriesDescription))
+      .append($('<p>').append($('<em>')
+                           .text('Status: ')
+                           .append($('<strong>').text(series.Status))));
 
-  var s = ('<h3>{0}</h3>' +
-           '<p><em>Status: <strong>{1}</strong></em></p>{2}' +
-           '<span class="ui-li-count">{3}</span>').format
-  (series.MainDicomTags.SeriesDescription,
-   series.Status,
-   FormatMainDicomTags(series.MainDicomTags, [
+  FormatMainDicomTags(node, series.MainDicomTags, [ 
      "SeriesDescription", 
      "SeriesTime", 
      "Manufacturer",
      "ImagesInAcquisition",
      "SeriesDate",
      "ImageOrientationPatient"
-   ]),
-   c
-  );
-
-  return CompleteFormatting(s, link, isReverse);
+  ]);
+    
+  return CompleteFormatting(node, link, isReverse, c);
 }
 
 
 function FormatInstance(instance, link, isReverse)
 {
-  var s = ('<h3>Instance {0}</h3>{1}').format
-  (instance.IndexInSeries,
-   FormatMainDicomTags(instance.MainDicomTags, [
-     "AcquisitionNumber", 
-     "InstanceNumber", 
-     "InstanceCreationDate", 
-     "InstanceCreationTime",
-     "ImagePositionPatient"
-   ])
-  );
-
-  return CompleteFormatting(s, link, isReverse);
+  var node = $('<div>').append($('<h3>').text('Instance: ' + instance.IndexInSeries));
+
+  FormatMainDicomTags(node, instance.MainDicomTags, [
+    "AcquisitionNumber", 
+    "InstanceNumber", 
+    "InstanceCreationDate", 
+    "InstanceCreationTime",
+    "ImagePositionPatient"
+  ]);
+    
+  return CompleteFormatting(node, link, isReverse);
 }
 
 
@@ -353,7 +334,11 @@ $('[data-role="page"]').live('pagebeforeshow', function() {
     cache: false,
     success: function(s) {
       if (s.Name != "") {
-        $('.orthanc-name').html('<a class="ui-link" href="explorer.html">' + s.Name + '</a> » ');
+        $('.orthanc-name').html($('<a>')
+                                .addClass('ui-link')
+                                .attr('href', 'explorer.html')
+                                .text(s.Name)
+                                .append(' » '));
       }
     }
   });
@@ -417,8 +402,9 @@ function RefreshPatient()
         for (var i = 0; i < studies.length; i++) {
           if (i == 0 || studies[i].MainDicomTags.StudyDate != studies[i - 1].MainDicomTags.StudyDate)
           {
-            target.append('<li data-role="list-divider">{0}</li>'.format
-                          (FormatDicomDate(studies[i].MainDicomTags.StudyDate)));
+            target.append($('<li>')
+                          .attr('data-role', 'list-divider')
+                          .text(FormatDicomDate(studies[i].MainDicomTags.StudyDate)));
           }
 
           target.append(FormatStudy(studies[i], '#study?uuid=' + studies[i].ID));
@@ -477,9 +463,11 @@ function RefreshStudy()
           for (var i = 0; i < series.length; i++) {
             if (i == 0 || series[i].MainDicomTags.SeriesDate != series[i - 1].MainDicomTags.SeriesDate)
             {
-              target.append('<li data-role="list-divider">{0}</li>'.format
-                            (FormatDicomDate(series[i].MainDicomTags.SeriesDate)));
+              target.append($('<li>')
+                            .attr('data-role', 'list-divider')
+                            .text(FormatDicomDate(series[i].MainDicomTags.SeriesDate)));
             }
+            
             target.append(FormatSeries(series[i], '#series?uuid=' + series[i].ID));
           }
           target.listview('refresh');
@@ -537,6 +525,24 @@ function RefreshSeries()
 }
 
 
+function EscapeHtml(value)
+{
+  var ENTITY_MAP = {
+    '&': '&',
+    '<': '<',
+    '>': '>',
+    '"': '"',
+    "'": ''',
+    '/': '&#x2F;',
+    '`': '&#x60;',
+    '=': '&#x3D;'
+  };
+
+  return String(value).replace(/[&<>"'`=\/]/g, function (s) {
+    return ENTITY_MAP[s];
+  });
+}
+
 
 function ConvertForTree(dicom)
 {
@@ -544,12 +550,14 @@ function ConvertForTree(dicom)
 
   for (var i in dicom) {
     if (dicom[i] != null) {
-      var label = i + '<span class="tag-name"> (<i>' + dicom[i]["Name"] + '</i>)</span>: ';
+      var label = (i + '<span class="tag-name"> (<i>' +
+                   EscapeHtml(dicom[i]["Name"]) +
+                   '</i>)</span>: ');
 
       if (dicom[i]["Type"] == 'String')
       {
         result.push({
-          label: label + '<strong>' + dicom[i]["Value"] + '</strong>',
+          label: label + '<strong>' + EscapeHtml(dicom[i]["Value"]) + '</strong>',
           children: []
         });
       }
@@ -797,7 +805,7 @@ $('#series-preview').live('click', function(e) {
         var images = [];
         for (var i = 0; i < instances.length; i++) {
           images.push([ '../instances/' + instances[i].ID + '/preview',
-                        '{0}/{1}'.format(i + 1, instances.length) ])
+                        (i + 1).toString() + '/' + instances.length.toString() ])
         }
 
         jQuery.slimbox(images, 0, {
diff --git a/OrthancExplorer/query-retrieve.js b/OrthancExplorer/query-retrieve.js
index 1e4d4ae..d611e2c 100644
--- a/OrthancExplorer/query-retrieve.js
+++ b/OrthancExplorer/query-retrieve.js
@@ -149,21 +149,22 @@ $('#query-retrieve-2').live('pagebeforeshow', function() {
             async: false,
             success: function(study) {
               var series = '#query-retrieve-3?server=' + pageData.server + '&uuid=' + study['StudyInstanceUID'];
-              var info = $('<a>').attr('href', series).html(
-                ('<h3>{0} - {1}</h3>' + 
-                 '<p>Accession number: <b>{2}</b></p>' +
-                 '<p>Birth date: <b>{3}</b></p>' +
-                 '<p>Patient sex: <b>{4}</b></p>' +
-                 '<p>Study description: <b>{5}</b></p>' +
-                 '<p>Study date: <b>{6}</b></p>').format(
-                   study['PatientID'],
-                   study['PatientName'],
-                   study['AccessionNumber'],
-                   FormatDicomDate(study['PatientBirthDate']),
-                   study['PatientSex'],
-                   study['StudyDescription'],
-                   FormatDicomDate(study['StudyDate'])));
 
+              var content = ($('<div>')
+                             .append($('<h3>').text(study['PatientID'] + ' - ' + study['PatientName']))
+                             .append($('<p>').text('Accession number: ')
+                                     .append($('<b>').text(study['AccessionNumber'])))
+                             .append($('<p>').text('Birth date: ')
+                                     .append($('<b>').text(study['PatientBirthDate'])))
+                             .append($('<p>').text('Patient sex: ')
+                                     .append($('<b>').text(study['PatientSex'])))
+                             .append($('<p>').text('Study description: ')
+                                     .append($('<b>').text(study['StudyDescription'])))
+                             .append($('<p>').text('Study date: ')
+                                     .append($('<b>').text(FormatDicomDate(study['StudyDate'])))));
+
+              var info = $('<a>').attr('href', series).html(content);
+              
               var answerId = answers[i];
               var retrieve = $('<a>').text('Retrieve all study').click(function() {
                 ChangePage('query-retrieve-4', {
@@ -228,15 +229,14 @@ $('#query-retrieve-3').live('pagebeforeshow', function() {
                 dataType: 'json',
                 async: false,
                 success: function(series) {
-                  var info = $('<a>').html(
-                    ('<h3>{0}</h3>'  + 
-                     '<p>Modality: <b>{1}</b></p>' +
-                     '<p>Protocol name: <b>{2}</b></p>'
-                    ).format(
-                      series['SeriesDescription'],
-                      series['Modality'],
-                      series['ProtocolName']
-                    ));
+                  var content = ($('<div>')
+                                 .append($('<h3>').text(series['SeriesDescription']))
+                                 .append($('<p>').text('Modality: ')
+                                         .append($('<b>').text(series['Modality'])))
+                                 .append($('<p>').text('ProtocolName: ')
+                                         .append($('<b>').text(series['ProtocolName']))));
+
+                  var info = $('<a>').html(content);
 
                   var answerId = answers[i];
                   info.click(function() {
diff --git a/OrthancServer/DatabaseWrapper.cpp b/OrthancServer/DatabaseWrapper.cpp
index 032509a..5e345a6 100644
--- a/OrthancServer/DatabaseWrapper.cpp
+++ b/OrthancServer/DatabaseWrapper.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DatabaseWrapper.h b/OrthancServer/DatabaseWrapper.h
index e9aeecb..59aa740 100644
--- a/OrthancServer/DatabaseWrapper.h
+++ b/OrthancServer/DatabaseWrapper.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DatabaseWrapperBase.cpp b/OrthancServer/DatabaseWrapperBase.cpp
index 0667a67..ad00672 100644
--- a/OrthancServer/DatabaseWrapperBase.cpp
+++ b/OrthancServer/DatabaseWrapperBase.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DatabaseWrapperBase.h b/OrthancServer/DatabaseWrapperBase.h
index 014e997..4be50ca 100644
--- a/OrthancServer/DatabaseWrapperBase.h
+++ b/OrthancServer/DatabaseWrapperBase.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DefaultDicomImageDecoder.h b/OrthancServer/DefaultDicomImageDecoder.h
index c82fd5b..2e9effd 100644
--- a/OrthancServer/DefaultDicomImageDecoder.h
+++ b/OrthancServer/DefaultDicomImageDecoder.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DicomDirWriter.cpp b/OrthancServer/DicomDirWriter.cpp
index fbe998f..f7975ee 100644
--- a/OrthancServer/DicomDirWriter.cpp
+++ b/OrthancServer/DicomDirWriter.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DicomDirWriter.h b/OrthancServer/DicomDirWriter.h
index 05e4f31..0e09353 100644
--- a/OrthancServer/DicomDirWriter.h
+++ b/OrthancServer/DicomDirWriter.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DicomInstanceToStore.cpp b/OrthancServer/DicomInstanceToStore.cpp
index 3851187..68133e3 100644
--- a/OrthancServer/DicomInstanceToStore.cpp
+++ b/OrthancServer/DicomInstanceToStore.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DicomInstanceToStore.h b/OrthancServer/DicomInstanceToStore.h
index 7723922..1118fa0 100644
--- a/OrthancServer/DicomInstanceToStore.h
+++ b/OrthancServer/DicomInstanceToStore.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DicomModification.cpp b/OrthancServer/DicomModification.cpp
index 35a0afd..dc15d97 100644
--- a/OrthancServer/DicomModification.cpp
+++ b/OrthancServer/DicomModification.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -40,19 +41,28 @@
 #include <memory>   // For std::auto_ptr
 
 
-static const std::string ORTHANC_DEIDENTIFICATION_METHOD = "Orthanc " ORTHANC_VERSION " - PS 3.15-2008 Table E.1-1";
+static const std::string ORTHANC_DEIDENTIFICATION_METHOD_2008 =
+  "Orthanc " ORTHANC_VERSION " - PS 3.15-2008 Table E.1-1";
+
+static const std::string ORTHANC_DEIDENTIFICATION_METHOD_2017c =
+  "Orthanc " ORTHANC_VERSION " - PS 3.15-2017c Table E.1-1 Basic Profile";
 
 namespace Orthanc
 {
-  void DicomModification::RemoveInternal(const DicomTag& tag)
+  bool DicomModification::CancelReplacement(const DicomTag& tag)
   {
     Replacements::iterator it = replacements_.find(tag);
-
+    
     if (it != replacements_.end())
     {
       delete it->second;
       replacements_.erase(it);
-    }    
+      return true;
+    }
+    else
+    {
+      return false;
+    }
   }
 
 
@@ -91,7 +101,8 @@ namespace Orthanc
     Replacements::iterator it = replacements_.find(DICOM_TAG_DEIDENTIFICATION_METHOD);
 
     if (it != replacements_.end() &&
-        it->second->asString() == ORTHANC_DEIDENTIFICATION_METHOD)
+        (it->second->asString() == ORTHANC_DEIDENTIFICATION_METHOD_2008 ||
+         it->second->asString() == ORTHANC_DEIDENTIFICATION_METHOD_2017c))
     {
       delete it->second;
       replacements_.erase(it);
@@ -160,23 +171,32 @@ namespace Orthanc
 
   void DicomModification::Keep(const DicomTag& tag)
   {
+    bool wasRemoved = IsRemoved(tag);
+    bool wasCleared = IsCleared(tag);
+    
     removals_.erase(tag);
-    RemoveInternal(tag);
+    clearings_.erase(tag);
 
-    if (tag.IsPrivate())
-    {
-      privateTagsToKeep_.insert(tag);
-    }
+    bool wasReplaced = CancelReplacement(tag);
 
     if (tag == DICOM_TAG_STUDY_INSTANCE_UID)
     {
       keepStudyInstanceUid_ = true;
     }
-
-    if (tag == DICOM_TAG_SERIES_INSTANCE_UID)
+    else if (tag == DICOM_TAG_SERIES_INSTANCE_UID)
     {
       keepSeriesInstanceUid_ = true;
     }
+    else if (tag.IsPrivate())
+    {
+      privateTagsToKeep_.insert(tag);
+    }
+    else if (!wasRemoved &&
+             !wasReplaced &&
+             !wasCleared)
+    {
+      LOG(WARNING) << "Marking this tag as to be kept has no effect: " << tag.Format();
+    }
 
     MarkNotOrthancAnonymization();
   }
@@ -184,7 +204,18 @@ namespace Orthanc
   void DicomModification::Remove(const DicomTag& tag)
   {
     removals_.insert(tag);
-    RemoveInternal(tag);
+    clearings_.erase(tag);
+    CancelReplacement(tag);
+    privateTagsToKeep_.erase(tag);
+
+    MarkNotOrthancAnonymization();
+  }
+
+  void DicomModification::Clear(const DicomTag& tag)
+  {
+    removals_.erase(tag);
+    clearings_.insert(tag);
+    CancelReplacement(tag);
     privateTagsToKeep_.erase(tag);
 
     MarkNotOrthancAnonymization();
@@ -195,10 +226,16 @@ namespace Orthanc
     return removals_.find(tag) != removals_.end();
   }
 
+  bool DicomModification::IsCleared(const DicomTag& tag) const
+  {
+    return clearings_.find(tag) != clearings_.end();
+  }
+
   void DicomModification::Replace(const DicomTag& tag,
                                   const Json::Value& value,
                                   bool safeForAnonymization)
   {
+    clearings_.erase(tag);
     removals_.erase(tag);
     privateTagsToKeep_.erase(tag);
     ReplaceInternal(tag, value);
@@ -266,16 +303,12 @@ namespace Orthanc
     }
   }
 
-  void DicomModification::SetupAnonymization()
-  {
-    removals_.clear();
-    ClearReplacements();
-    removePrivateTags_ = true;
-    level_ = ResourceType_Patient;
-    uidMap_.clear();
-    privateTagsToKeep_.clear();
 
+  void DicomModification::SetupAnonymization2008()
+  {
     // This is Table E.1-1 from PS 3.15-2008 - DICOM Part 15: Security and System Management Profiles
+    // https://raw.githubusercontent.com/jodogne/dicom-specification/master/2008/08_15pu.pdf
+    
     removals_.insert(DicomTag(0x0008, 0x0014));  // Instance Creator UID
     //removals_.insert(DicomTag(0x0008, 0x0018));  // SOP Instance UID => set in Apply()
     removals_.insert(DicomTag(0x0008, 0x0050));  // Accession Number
@@ -332,7 +365,589 @@ namespace Orthanc
     removals_.insert(DicomTag(0x0010, 0x2000));  // Medical Alerts
 
     // Set the DeidentificationMethod tag
-    ReplaceInternal(DICOM_TAG_DEIDENTIFICATION_METHOD, ORTHANC_DEIDENTIFICATION_METHOD);
+    ReplaceInternal(DICOM_TAG_DEIDENTIFICATION_METHOD, ORTHANC_DEIDENTIFICATION_METHOD_2008);
+  }
+  
+
+#if 0
+  /**
+   * This is a manual implementation by Alain Mazy. Only kept for reference.
+   * https://bitbucket.org/sjodogne/orthanc/commits/c6defdc4c611fca2ab528ba2c6937a742e0329a8?at=issue-46-anonymization
+   **/
+  
+  void DicomModification::SetupAnonymization2011()
+  {
+    // This is Table E.1-1 from PS 3.15-2011 - DICOM Part 15: Security and System Management Profiles
+    // https://raw.githubusercontent.com/jodogne/dicom-specification/master/2011/11_15pu.pdf
+    
+    removals_.insert(DicomTag(0x0000, 0x1000));  // Affected SOP Instance UID
+    removals_.insert(DicomTag(0x0000, 0x1001));  // Requested SOP Instance UID
+    removals_.insert(DicomTag(0x0002, 0x0003));  // Media Storage SOP Instance UID => TODO: replace with a non-zero length UID that is internally consistent within a set of Instances
+    removals_.insert(DicomTag(0x0004, 0x1511));  // Referenced SOP Instance UID in File
+    removals_.insert(DicomTag(0x0008, 0x0010));  // Irradiation Event UID
+    removals_.insert(DicomTag(0x0008, 0x0014));  // Instance Creator UID
+    //removals_.insert(DicomTag(0x0008, 0x0018));  // SOP Instance UID => set in Apply()
+    clearings_.insert(DicomTag(0x0008, 0x0020)); // Study Date
+    clearings_.insert(DicomTag(0x0008, 0x0021)); // Series Date
+    clearings_.insert(DicomTag(0x0008, 0x0030)); // Study Time
+    clearings_.insert(DicomTag(0x0008, 0x0031)); // Series Time
+    removals_.insert(DicomTag(0x0008, 0x0022));  // Acquisition Date
+    removals_.insert(DicomTag(0x0008, 0x0023));  // Content Date
+    removals_.insert(DicomTag(0x0008, 0x0024));  // Overlay Date
+    removals_.insert(DicomTag(0x0008, 0x0025));  // Curve Date
+    removals_.insert(DicomTag(0x0008, 0x002a));  // Acquisition DateTime
+    removals_.insert(DicomTag(0x0008, 0x0032));  // Acquisition Time
+    removals_.insert(DicomTag(0x0008, 0x0033));  // Content Time
+    removals_.insert(DicomTag(0x0008, 0x0034));  // Overlay Time
+    removals_.insert(DicomTag(0x0008, 0x0035));  // Curve Time
+    removals_.insert(DicomTag(0x0008, 0x0050));  // Accession Number
+    removals_.insert(DicomTag(0x0008, 0x0058));  // Failed SOP Instance UID List
+    removals_.insert(DicomTag(0x0008, 0x0080));  // Institution Name
+    removals_.insert(DicomTag(0x0008, 0x0081));  // Institution Address
+    removals_.insert(DicomTag(0x0008, 0x0082));  // Institution Code Sequence
+    removals_.insert(DicomTag(0x0008, 0x0090));  // Referring Physician's Name
+    removals_.insert(DicomTag(0x0008, 0x0092));  // Referring Physician's Address 
+    removals_.insert(DicomTag(0x0008, 0x0094));  // Referring Physician's Telephone Numbers 
+    removals_.insert(DicomTag(0x0008, 0x0096));  // Referring Physician's Identification Sequence
+    removals_.insert(DicomTag(0x0008, 0x010d));  // Context Group Extension Creator UID
+    removals_.insert(DicomTag(0x0008, 0x0201));  // Timezone Offset From UTC
+    removals_.insert(DicomTag(0x0008, 0x0300));  // Current Patient Location
+    removals_.insert(DicomTag(0x0008, 0x1010));  // Station Name
+    removals_.insert(DicomTag(0x0008, 0x1030));  // Study Description 
+    removals_.insert(DicomTag(0x0008, 0x103e));  // Series Description 
+    removals_.insert(DicomTag(0x0008, 0x1040));  // Institutional Department Name 
+    removals_.insert(DicomTag(0x0008, 0x1048));  // Physician(s) of Record 
+    removals_.insert(DicomTag(0x0008, 0x1049));  // Physician(s) of Record Identification Sequence
+    removals_.insert(DicomTag(0x0008, 0x1050));  // Performing Physicians' Name
+    removals_.insert(DicomTag(0x0008, 0x1052));  // Performing Physicians Identification Sequence
+    removals_.insert(DicomTag(0x0008, 0x1060));  // Name of Physician(s) Reading Study
+    removals_.insert(DicomTag(0x0008, 0x1062));  // Physician Reading Study Identification Sequence
+    removals_.insert(DicomTag(0x0008, 0x1070));  // Operators' Name
+    removals_.insert(DicomTag(0x0008, 0x1072));  // Operators' Identification Sequence
+    removals_.insert(DicomTag(0x0008, 0x1080));  // Admitting Diagnoses Description
+    removals_.insert(DicomTag(0x0008, 0x1084));  // Admitting Diagnoses Code Sequence
+    removals_.insert(DicomTag(0x0008, 0x1110));  // Referenced Study Sequence
+    removals_.insert(DicomTag(0x0008, 0x1111));  // Referenced Performed Procedure Step Sequence
+    removals_.insert(DicomTag(0x0008, 0x1120));  // Referenced Patient Sequence
+    removals_.insert(DicomTag(0x0008, 0x1140));  // Referenced Image Sequence
+    removals_.insert(DicomTag(0x0008, 0x1155));  // Referenced SOP Instance UID
+    removals_.insert(DicomTag(0x0008, 0x1195));  // Transaction UID
+    removals_.insert(DicomTag(0x0008, 0x2111));  // Derivation Description
+    removals_.insert(DicomTag(0x0008, 0x2112));  // Source Image Sequence
+    removals_.insert(DicomTag(0x0008, 0x4000));  // Identifying Comments
+    removals_.insert(DicomTag(0x0008, 0x9123));  // Creator Version UID
+    //removals_.insert(DicomTag(0x0010, 0x0010));  // Patient's Name => cf. below (*)
+    //removals_.insert(DicomTag(0x0010, 0x0020));  // Patient ID => cf. below (*)
+    removals_.insert(DicomTag(0x0010, 0x0030));  // Patient's Birth Date 
+    removals_.insert(DicomTag(0x0010, 0x0032));  // Patient's Birth Time 
+    clearings_.insert(DicomTag(0x0010, 0x0040)); // Patient's Sex
+    removals_.insert(DicomTag(0x0010, 0x0050));  // Patient's Insurance Plan Code Sequence
+    removals_.insert(DicomTag(0x0010, 0x0101));  // Patient's Primary Language Code Sequence
+    removals_.insert(DicomTag(0x0010, 0x0102));  // Patient's Primary Language Modifier Code Sequence
+    removals_.insert(DicomTag(0x0010, 0x1000));  // Other Patient Ids
+    removals_.insert(DicomTag(0x0010, 0x1001));  // Other Patient Names 
+    removals_.insert(DicomTag(0x0010, 0x1002));  // Other Patient IDs Sequence
+    removals_.insert(DicomTag(0x0010, 0x1005));  // Patient's Birth Name
+    removals_.insert(DicomTag(0x0010, 0x1010));  // Patient's Age
+    removals_.insert(DicomTag(0x0010, 0x1020));  // Patient's Size 
+    removals_.insert(DicomTag(0x0010, 0x1030));  // Patient's Weight 
+    removals_.insert(DicomTag(0x0010, 0x1040));  // Patient's Address
+    removals_.insert(DicomTag(0x0010, 0x1050));  // Insurance Plan Identification
+    removals_.insert(DicomTag(0x0010, 0x1060));  // Patient's Mother's Birth Name
+    removals_.insert(DicomTag(0x0010, 0x1080));  // Military Rank
+    removals_.insert(DicomTag(0x0010, 0x1081));  // Branch of Service
+    removals_.insert(DicomTag(0x0010, 0x1090));  // Medical Record Locator
+    removals_.insert(DicomTag(0x0010, 0x2000));  // Medical Alerts
+    removals_.insert(DicomTag(0x0010, 0x2110));  // Allergies
+    removals_.insert(DicomTag(0x0010, 0x2150));  // Country of Residence
+    removals_.insert(DicomTag(0x0010, 0x2152));  // Region of Residence
+    removals_.insert(DicomTag(0x0010, 0x2154));  // PatientTelephoneNumbers
+    removals_.insert(DicomTag(0x0010, 0x2160));  // Ethnic Group
+    removals_.insert(DicomTag(0x0010, 0x2180));  // Occupation 
+    removals_.insert(DicomTag(0x0010, 0x21a0));  // Smoking Status
+    removals_.insert(DicomTag(0x0010, 0x21b0));  // Additional Patient's History
+    removals_.insert(DicomTag(0x0010, 0x21c0));  // Pregnancy Status
+    removals_.insert(DicomTag(0x0010, 0x21d0));  // Last Menstrual Date
+    removals_.insert(DicomTag(0x0010, 0x21f0));  // Patient's Religious Preference
+    removals_.insert(DicomTag(0x0010, 0x2203));  // Patient's Sex Neutered
+    removals_.insert(DicomTag(0x0010, 0x2297));  // Responsible Person
+    removals_.insert(DicomTag(0x0010, 0x2299));  // Responsible Organization
+    removals_.insert(DicomTag(0x0010, 0x4000));  // Patient Comments
+    removals_.insert(DicomTag(0x0018, 0x0010));  // Contrast Bolus Agent
+    removals_.insert(DicomTag(0x0018, 0x1000));  // Device Serial Number
+    removals_.insert(DicomTag(0x0018, 0x1002));  // Device UID
+    removals_.insert(DicomTag(0x0018, 0x1004));  // Plate ID
+    removals_.insert(DicomTag(0x0018, 0x1005));  // Generator ID
+    removals_.insert(DicomTag(0x0018, 0x1007));  // Cassette ID
+    removals_.insert(DicomTag(0x0018, 0x1008));  // Gantry ID
+    removals_.insert(DicomTag(0x0018, 0x1030));  // Protocol Name
+    removals_.insert(DicomTag(0x0018, 0x1400));  // Acquisition Device Processing Description
+    removals_.insert(DicomTag(0x0018, 0x4000));  // Acquisition Comments
+    removals_.insert(DicomTag(0x0018, 0x700a));  // Detector ID
+    removals_.insert(DicomTag(0x0018, 0xa003));  // Contribution Description
+    removals_.insert(DicomTag(0x0018, 0x9424));  // Acquisition Protocol Description
+    //removals_.insert(DicomTag(0x0020, 0x000d));  // Study Instance UID => set in Apply()
+    //removals_.insert(DicomTag(0x0020, 0x000e));  // Series Instance UID => set in Apply()
+    removals_.insert(DicomTag(0x0020, 0x0010));  // Study ID
+    removals_.insert(DicomTag(0x0020, 0x0052));  // Frame of Reference UID 
+    removals_.insert(DicomTag(0x0020, 0x0200));  // Synchronization Frame of Reference UID 
+    removals_.insert(DicomTag(0x0020, 0x3401));  // Modifying Device ID
+    removals_.insert(DicomTag(0x0020, 0x3404));  // Modifying Device Manufacturer
+    removals_.insert(DicomTag(0x0020, 0x3406));  // Modified Image Description
+    removals_.insert(DicomTag(0x0020, 0x4000));  // Image Comments
+    removals_.insert(DicomTag(0x0020, 0x9158));  // Frame Comments
+    removals_.insert(DicomTag(0x0020, 0x9161));  // Concatenation UID
+    removals_.insert(DicomTag(0x0020, 0x9164));  // Dimension Organization UID
+    //removals_.insert(DicomTag(0x0028, 0x1199));  // Palette Color Lookup Table UID => TODO: replace with a non-zero length UID that is internally consistent within a set of Instances
+    //removals_.insert(DicomTag(0x0028, 0x1214));  // Large Palette Color Lookup Table UID => TODO: replace with a non-zero length UID that is internally consistent within a set of Instances
+    removals_.insert(DicomTag(0x0028, 0x4000));  // Image Presentation Comments
+    removals_.insert(DicomTag(0x0032, 0x0012));  // Study ID Issuer
+    removals_.insert(DicomTag(0x0032, 0x1020));  // Scheduled Study Location
+    removals_.insert(DicomTag(0x0032, 0x1021));  // Scheduled Study Location AE Title
+    removals_.insert(DicomTag(0x0032, 0x1030));  // Reason for Study
+    removals_.insert(DicomTag(0x0032, 0x1032));  // Requesting Physician
+    removals_.insert(DicomTag(0x0032, 0x1033));  // Requesting Service
+    removals_.insert(DicomTag(0x0032, 0x1060));  // Requesting Procedure Description
+    removals_.insert(DicomTag(0x0032, 0x1070));  // Requested Contrast Agent
+    removals_.insert(DicomTag(0x0032, 0x4000));  // Study Comments
+    removals_.insert(DicomTag(0x0038, 0x0010));  // Admission ID
+    removals_.insert(DicomTag(0x0038, 0x0011));  // Issuer of Admission ID
+    removals_.insert(DicomTag(0x0038, 0x001e));  // Scheduled Patient Institution Residence
+    removals_.insert(DicomTag(0x0038, 0x0020));  // Admitting Date
+    removals_.insert(DicomTag(0x0038, 0x0021));  // Admitting Time
+    removals_.insert(DicomTag(0x0038, 0x0040));  // Discharge Diagnosis Description
+    removals_.insert(DicomTag(0x0038, 0x0050));  // Special Needs
+    removals_.insert(DicomTag(0x0038, 0x0060));  // Service Episode ID
+    removals_.insert(DicomTag(0x0038, 0x0061));  // Issuer of Service Episode ID
+    removals_.insert(DicomTag(0x0038, 0x0062));  // Service Episode Description
+    removals_.insert(DicomTag(0x0038, 0x0400));  // Patient's Institution Residence
+    removals_.insert(DicomTag(0x0038, 0x0500));  // Patient State
+    removals_.insert(DicomTag(0x0038, 0x4000));  // Visit Comments
+    removals_.insert(DicomTag(0x0038, 0x1234));  // Referenced Patient Alias Sequence
+    removals_.insert(DicomTag(0x0040, 0x0001));  // Scheduled Station AE Title
+    removals_.insert(DicomTag(0x0040, 0x0002));  // Scheduled Procedure Step Start Date
+    removals_.insert(DicomTag(0x0040, 0x0003));  // Scheduled Procedure Step Start Time
+    removals_.insert(DicomTag(0x0040, 0x0004));  // Scheduled Procedure Step End Date
+    removals_.insert(DicomTag(0x0040, 0x0005));  // Scheduled Procedure Step End Time
+    removals_.insert(DicomTag(0x0040, 0x0006));  // Scheduled Performing Physician Name
+    removals_.insert(DicomTag(0x0040, 0x0007));  // Scheduled Procedure Step Description
+    removals_.insert(DicomTag(0x0040, 0x000b));  // Scheduled Performing Physician Identification Sequence
+    removals_.insert(DicomTag(0x0040, 0x0010));  // Scheduled Station Name
+    removals_.insert(DicomTag(0x0040, 0x0011));  // Scheduled Procedure Step Location
+    removals_.insert(DicomTag(0x0040, 0x0012));  // Pre-Medication
+    removals_.insert(DicomTag(0x0040, 0x0241));  // Performed Station AE Title
+    removals_.insert(DicomTag(0x0040, 0x0242));  // Performed Station Name
+    removals_.insert(DicomTag(0x0040, 0x0243));  // Performed Location
+    removals_.insert(DicomTag(0x0040, 0x0244));  // Performed Procedure Step Start Date
+    removals_.insert(DicomTag(0x0040, 0x0245));  // Performed Procedure Step Start Time
+    removals_.insert(DicomTag(0x0040, 0x0248));  // Performed Station Name Code Sequence
+    removals_.insert(DicomTag(0x0040, 0x0253));  // Performed Procedure Step ID
+    removals_.insert(DicomTag(0x0040, 0x0254));  // Performed Procedure Step Description
+    removals_.insert(DicomTag(0x0040, 0x0275));  // Request Attributes Sequence
+    removals_.insert(DicomTag(0x0040, 0x0280));  // Comments on Performed Procedure Step
+    removals_.insert(DicomTag(0x0040, 0x0555));  // Acquisition Context Sequence
+    removals_.insert(DicomTag(0x0040, 0x1001));  // Requested Procedure ID
+    removals_.insert(DicomTag(0x0040, 0x1010));  // Names of Intended Recipient of Results
+    removals_.insert(DicomTag(0x0040, 0x1011));  // Intended Recipient of Results Identification Sequence
+    removals_.insert(DicomTag(0x0040, 0x1004));  // Patient Transport Arrangements
+    removals_.insert(DicomTag(0x0040, 0x1005));  // Requested Procedure Location
+    removals_.insert(DicomTag(0x0040, 0x1101));  // Person Identification Code Sequence
+    removals_.insert(DicomTag(0x0040, 0x1102));  // Person Address
+    removals_.insert(DicomTag(0x0040, 0x1103));  // Person Telephone Numbers
+    removals_.insert(DicomTag(0x0040, 0x1400));  // Requested Procedure Comments
+    removals_.insert(DicomTag(0x0040, 0x2001));  // Reason for Imaging Service Request
+    removals_.insert(DicomTag(0x0040, 0x2008));  // Order Entered By
+    removals_.insert(DicomTag(0x0040, 0x2009));  // Order Enterer Location
+    removals_.insert(DicomTag(0x0040, 0x2010));  // Order Callback Phone Number
+    removals_.insert(DicomTag(0x0040, 0x2016));  // Placer Order Number of Imaging Service Request
+    removals_.insert(DicomTag(0x0040, 0x2017));  // Filler Order Number of Imaging Service Request
+    removals_.insert(DicomTag(0x0040, 0x2400));  // Imaging Service Request Comments
+    removals_.insert(DicomTag(0x0040, 0x4023));  // Referenced General Purpose Scheduled Procedure Step Transaction UID
+    removals_.insert(DicomTag(0x0040, 0x4025));  // Scheduled Station Name Code Sequence
+    removals_.insert(DicomTag(0x0040, 0x4027));  // Scheduled Station Geographic Location Code Sequence
+    removals_.insert(DicomTag(0x0040, 0x4030));  // Performed Station Geographic Location Code Sequence
+    removals_.insert(DicomTag(0x0040, 0x4034));  // Scheduled Human Performers Sequence
+    removals_.insert(DicomTag(0x0040, 0x4035));  // Actual Human Performers Sequence
+    removals_.insert(DicomTag(0x0040, 0x4036));  // Human Performers Organization
+    removals_.insert(DicomTag(0x0040, 0x4037));  // Human Performers Name
+    removals_.insert(DicomTag(0x0040, 0xa027));  // Verifying Organization
+    removals_.insert(DicomTag(0x0040, 0xa073));  // Verifying Observer Sequence
+    removals_.insert(DicomTag(0x0040, 0xa075));  // Verifying Observer Name
+    removals_.insert(DicomTag(0x0040, 0xa078));  // Author Observer Sequence
+    removals_.insert(DicomTag(0x0040, 0xa07a));  // Participant Sequence
+    removals_.insert(DicomTag(0x0040, 0xa07c));  // Custodial Organization Sequence
+    removals_.insert(DicomTag(0x0040, 0xa088));  // Verifying Observer Identification Code Sequence
+    removals_.insert(DicomTag(0x0040, 0xa123));  // Person Name
+    removals_.insert(DicomTag(0x0040, 0xa124));  // UID
+    removals_.insert(DicomTag(0x0040, 0xa730));  // Content Sequence 
+    removals_.insert(DicomTag(0x0040, 0x3001));  // Confidentiality Constraint on Patient Data Description
+    removals_.insert(DicomTag(0x0040, 0xdb0c));  // Template Extension Organization UID
+    removals_.insert(DicomTag(0x0040, 0xdb0d));  // Template Extension Creator UID
+    removals_.insert(DicomTag(0x0070, 0x0001));  // Graphic Annotation Sequence
+    removals_.insert(DicomTag(0x0070, 0x0084));  // Content Creator's Name
+    removals_.insert(DicomTag(0x0070, 0x0086));  // Content Creator's Identification Code Sequence
+    removals_.insert(DicomTag(0x0070, 0x031a));  // Fiducial UID
+    removals_.insert(DicomTag(0x0088, 0x0140));  // Storage Media File-set UID
+    removals_.insert(DicomTag(0x0088, 0x0200));  // Icon Image Sequence
+    removals_.insert(DicomTag(0x0088, 0x0904));  // Topic Title
+    removals_.insert(DicomTag(0x0088, 0x0906));  // Topic Subject
+    removals_.insert(DicomTag(0x0088, 0x0910));  // Topic Author
+    removals_.insert(DicomTag(0x0088, 0x0912));  // Topic Key Words
+    removals_.insert(DicomTag(0x0400, 0x0100));  // Digital Signature UID
+    removals_.insert(DicomTag(0x0400, 0x0402));  // Referenced Digital Signature Sequence
+    removals_.insert(DicomTag(0x0400, 0x0403));  // Referenced SOP Instance MAC Sequence
+    removals_.insert(DicomTag(0x0400, 0x0404));  // MAC
+    removals_.insert(DicomTag(0x0400, 0x0550));  // Modified Attributes Sequence
+    removals_.insert(DicomTag(0x0400, 0x0561));  // Original Attributes Sequence
+    removals_.insert(DicomTag(0x2030, 0x0020));  // Text String
+    removals_.insert(DicomTag(0x3006, 0x0024));  // Referenced Frame of Reference UID
+    removals_.insert(DicomTag(0x3006, 0x00c2));  // Related Frame of Reference UID 
+    removals_.insert(DicomTag(0x300a, 0x0013));  // Dose Reference UID
+    removals_.insert(DicomTag(0x300e, 0x0008));  // Reviewer Name
+    removals_.insert(DicomTag(0x4000, 0x0010));  // Arbitrary
+    removals_.insert(DicomTag(0x4000, 0x4000));  // Text Comments
+    removals_.insert(DicomTag(0x4008, 0x0042));  // Results ID Issuer
+    removals_.insert(DicomTag(0x4008, 0x0102));  // Interpretation Recorder
+    removals_.insert(DicomTag(0x4008, 0x010a));  // Interpretation Transcriber
+    removals_.insert(DicomTag(0x4008, 0x010b));  // Interpretation Text
+    removals_.insert(DicomTag(0x4008, 0x010c));  // Interpretation Author
+    removals_.insert(DicomTag(0x4008, 0x0111));  // Interpretation Approver Sequence
+    removals_.insert(DicomTag(0x4008, 0x0114));  // Physician Approving Interpretation
+    removals_.insert(DicomTag(0x4008, 0x0115));  // Interpretation Diagnosis Description
+    removals_.insert(DicomTag(0x4008, 0x0118));  // Results Distribution List Sequence
+    removals_.insert(DicomTag(0x4008, 0x0119));  // Distribution Name
+    removals_.insert(DicomTag(0x4008, 0x011a));  // Distribution Address
+    removals_.insert(DicomTag(0x4008, 0x0202));  // Interpretation ID Issuer
+    removals_.insert(DicomTag(0x4008, 0x0300));  // Impressions
+    removals_.insert(DicomTag(0x4008, 0x4000));  // Results Comments
+    removals_.insert(DicomTag(0xfffa, 0xfffa));  // Digital Signature Sequence
+    removals_.insert(DicomTag(0xfffc, 0xfffc));  // Data Set Trailing Padding
+    //removals_.insert(DicomTag(0x60xx, 0x4000));  // Overlay Comments => TODO
+    //removals_.insert(DicomTag(0x60xx, 0x3000));  // Overlay Data => TODO
+
+    // Set the DeidentificationMethod tag
+    ReplaceInternal(DICOM_TAG_DEIDENTIFICATION_METHOD, ORTHANC_DEIDENTIFICATION_METHOD_2011);
+  }
+#endif
+  
+  
+
+  void DicomModification::SetupAnonymization2017c()
+  {
+    /**
+     * This is Table E.1-1 from PS 3.15-2017c (DICOM Part 15: Security
+     * and System Management Profiles), "basic profile" column. It was
+     * generated automatically with the
+     * "../Resources/GenerateAnonymizationProfile.py" script.
+     * https://raw.githubusercontent.com/jodogne/dicom-specification/master/2017c/part15.pdf
+     **/
+    
+    // TODO: (50xx,xxxx) with rule X                                 // Curve Data
+    // TODO: (60xx,3000) with rule X                                 // Overlay Data
+    // TODO: (60xx,4000) with rule X                                 // Overlay Comments
+    // Tag (0x0008, 0x0018) is set in Apply()                        // SOP Instance UID
+    // Tag (0x0010, 0x0010) is set below (*)                         // Patient's Name
+    // Tag (0x0010, 0x0020) is set below (*)                         // Patient ID
+    // Tag (0x0020, 0x000d) is set in Apply()                        // Study Instance UID
+    // Tag (0x0020, 0x000e) is set in Apply()                        // Series Instance UID
+    clearings_.insert(DicomTag(0x0008, 0x0020));                     // Study Date
+    clearings_.insert(DicomTag(0x0008, 0x0023));  /* Z/D */          // Content Date
+    clearings_.insert(DicomTag(0x0008, 0x0030));                     // Study Time
+    clearings_.insert(DicomTag(0x0008, 0x0033));  /* Z/D */          // Content Time
+    clearings_.insert(DicomTag(0x0008, 0x0050));                     // Accession Number
+    clearings_.insert(DicomTag(0x0008, 0x0090));                     // Referring Physician's Name
+    clearings_.insert(DicomTag(0x0008, 0x009c));                     // Consulting Physician's Name
+    clearings_.insert(DicomTag(0x0010, 0x0030));                     // Patient's Birth Date
+    clearings_.insert(DicomTag(0x0010, 0x0040));                     // Patient's Sex
+    clearings_.insert(DicomTag(0x0018, 0x0010));  /* Z/D */          // Contrast Bolus Agent
+    clearings_.insert(DicomTag(0x0020, 0x0010));                     // Study ID
+    clearings_.insert(DicomTag(0x0040, 0x1101));  /* D */            // Person Identification Code Sequence
+    clearings_.insert(DicomTag(0x0040, 0x2016));                     // Placer Order Number / Imaging Service Request
+    clearings_.insert(DicomTag(0x0040, 0x2017));                     // Filler Order Number / Imaging Service Request
+    clearings_.insert(DicomTag(0x0040, 0xa073));  /* D */            // Verifying Observer Sequence
+    clearings_.insert(DicomTag(0x0040, 0xa075));  /* D */            // Verifying Observer Name
+    clearings_.insert(DicomTag(0x0040, 0xa088));                     // Verifying Observer Identification Code Sequence
+    clearings_.insert(DicomTag(0x0040, 0xa123));  /* D */            // Person Name
+    clearings_.insert(DicomTag(0x0070, 0x0001));  /* D */            // Graphic Annotation Sequence
+    clearings_.insert(DicomTag(0x0070, 0x0084));                     // Content Creator's Name
+    removals_.insert(DicomTag(0x0000, 0x1000));                      // Affected SOP Instance UID
+    removals_.insert(DicomTag(0x0000, 0x1001));   /* TODO UID */     // Requested SOP Instance UID
+    removals_.insert(DicomTag(0x0002, 0x0003));   /* TODO UID */     // Media Storage SOP Instance UID
+    removals_.insert(DicomTag(0x0004, 0x1511));   /* TODO UID */     // Referenced SOP Instance UID in File
+    removals_.insert(DicomTag(0x0008, 0x0014));   /* TODO UID */     // Instance Creator UID
+    removals_.insert(DicomTag(0x0008, 0x0015));                      // Instance Coercion DateTime
+    removals_.insert(DicomTag(0x0008, 0x0021));   /* X/D */          // Series Date
+    removals_.insert(DicomTag(0x0008, 0x0022));   /* X/Z */          // Acquisition Date
+    removals_.insert(DicomTag(0x0008, 0x0024));                      // Overlay Date
+    removals_.insert(DicomTag(0x0008, 0x0025));                      // Curve Date
+    removals_.insert(DicomTag(0x0008, 0x002a));   /* X/D */          // Acquisition DateTime
+    removals_.insert(DicomTag(0x0008, 0x0031));   /* X/D */          // Series Time
+    removals_.insert(DicomTag(0x0008, 0x0032));   /* X/Z */          // Acquisition Time
+    removals_.insert(DicomTag(0x0008, 0x0034));                      // Overlay Time
+    removals_.insert(DicomTag(0x0008, 0x0035));                      // Curve Time
+    removals_.insert(DicomTag(0x0008, 0x0058));   /* TODO UID */     // Failed SOP Instance UID List
+    removals_.insert(DicomTag(0x0008, 0x0080));   /* X/Z/D */        // Institution Name
+    removals_.insert(DicomTag(0x0008, 0x0081));                      // Institution Address
+    removals_.insert(DicomTag(0x0008, 0x0082));   /* X/Z/D */        // Institution Code Sequence
+    removals_.insert(DicomTag(0x0008, 0x0092));                      // Referring Physician's Address
+    removals_.insert(DicomTag(0x0008, 0x0094));                      // Referring Physician's Telephone Numbers
+    removals_.insert(DicomTag(0x0008, 0x0096));                      // Referring Physician Identification Sequence
+    removals_.insert(DicomTag(0x0008, 0x009d));                      // Consulting Physician Identification Sequence
+    removals_.insert(DicomTag(0x0008, 0x0201));                      // Timezone Offset From UTC
+    removals_.insert(DicomTag(0x0008, 0x1010));   /* X/Z/D */        // Station Name
+    removals_.insert(DicomTag(0x0008, 0x1030));                      // Study Description
+    removals_.insert(DicomTag(0x0008, 0x103e));                      // Series Description
+    removals_.insert(DicomTag(0x0008, 0x1040));                      // Institutional Department Name
+    removals_.insert(DicomTag(0x0008, 0x1048));                      // Physician(s) of Record
+    removals_.insert(DicomTag(0x0008, 0x1049));                      // Physician(s) of Record Identification Sequence
+    removals_.insert(DicomTag(0x0008, 0x1050));                      // Performing Physicians' Name
+    removals_.insert(DicomTag(0x0008, 0x1052));                      // Performing Physician Identification Sequence
+    removals_.insert(DicomTag(0x0008, 0x1060));                      // Name of Physician(s) Reading Study
+    removals_.insert(DicomTag(0x0008, 0x1062));                      // Physician(s) Reading Study Identification Sequence
+    removals_.insert(DicomTag(0x0008, 0x1070));   /* X/Z/D */        // Operators' Name
+    removals_.insert(DicomTag(0x0008, 0x1072));   /* X/D */          // Operators' Identification Sequence
+    removals_.insert(DicomTag(0x0008, 0x1080));                      // Admitting Diagnoses Description
+    removals_.insert(DicomTag(0x0008, 0x1084));                      // Admitting Diagnoses Code Sequence
+    removals_.insert(DicomTag(0x0008, 0x1110));   /* X/Z */          // Referenced Study Sequence
+    removals_.insert(DicomTag(0x0008, 0x1111));   /* X/Z/D */        // Referenced Performed Procedure Step Sequence
+    removals_.insert(DicomTag(0x0008, 0x1120));                      // Referenced Patient Sequence
+    removals_.insert(DicomTag(0x0008, 0x1140));   /* X/Z/U* */       // Referenced Image Sequence
+    removals_.insert(DicomTag(0x0008, 0x1155));   /* TODO UID */     // Referenced SOP Instance UID
+    removals_.insert(DicomTag(0x0008, 0x1195));   /* TODO UID */     // Transaction UID
+    removals_.insert(DicomTag(0x0008, 0x2111));                      // Derivation Description
+    removals_.insert(DicomTag(0x0008, 0x2112));   /* X/Z/U* */       // Source Image Sequence
+    removals_.insert(DicomTag(0x0008, 0x3010));   /* TODO UID */     // Irradiation Event UID
+    removals_.insert(DicomTag(0x0008, 0x4000));                      // Identifying Comments
+    removals_.insert(DicomTag(0x0010, 0x0021));                      // Issuer of Patient ID
+    removals_.insert(DicomTag(0x0010, 0x0032));                      // Patient's Birth Time
+    removals_.insert(DicomTag(0x0010, 0x0050));                      // Patient's Insurance Plan Code Sequence
+    removals_.insert(DicomTag(0x0010, 0x0101));                      // Patient's Primary Language Code Sequence
+    removals_.insert(DicomTag(0x0010, 0x0102));                      // Patient's Primary Language Modifier Code Sequence
+    removals_.insert(DicomTag(0x0010, 0x1000));                      // Other Patient IDs
+    removals_.insert(DicomTag(0x0010, 0x1001));                      // Other Patient Names
+    removals_.insert(DicomTag(0x0010, 0x1002));                      // Other Patient IDs Sequence
+    removals_.insert(DicomTag(0x0010, 0x1005));                      // Patient's Birth Name
+    removals_.insert(DicomTag(0x0010, 0x1010));                      // Patient's Age
+    removals_.insert(DicomTag(0x0010, 0x1020));                      // Patient's Size
+    removals_.insert(DicomTag(0x0010, 0x1030));                      // Patient's Weight
+    removals_.insert(DicomTag(0x0010, 0x1040));                      // Patient Address
+    removals_.insert(DicomTag(0x0010, 0x1050));                      // Insurance Plan Identification
+    removals_.insert(DicomTag(0x0010, 0x1060));                      // Patient's Mother's Birth Name
+    removals_.insert(DicomTag(0x0010, 0x1080));                      // Military Rank
+    removals_.insert(DicomTag(0x0010, 0x1081));                      // Branch of Service
+    removals_.insert(DicomTag(0x0010, 0x1090));                      // Medical Record Locator
+    removals_.insert(DicomTag(0x0010, 0x1100));                      // Referenced Patient Photo Sequence
+    removals_.insert(DicomTag(0x0010, 0x2000));                      // Medical Alerts
+    removals_.insert(DicomTag(0x0010, 0x2110));                      // Allergies
+    removals_.insert(DicomTag(0x0010, 0x2150));                      // Country of Residence
+    removals_.insert(DicomTag(0x0010, 0x2152));                      // Region of Residence
+    removals_.insert(DicomTag(0x0010, 0x2154));                      // Patient's Telephone Numbers
+    removals_.insert(DicomTag(0x0010, 0x2155));                      // Patient's Telecom Information
+    removals_.insert(DicomTag(0x0010, 0x2160));                      // Ethnic Group
+    removals_.insert(DicomTag(0x0010, 0x2180));                      // Occupation
+    removals_.insert(DicomTag(0x0010, 0x21a0));                      // Smoking Status
+    removals_.insert(DicomTag(0x0010, 0x21b0));                      // Additional Patient's History
+    removals_.insert(DicomTag(0x0010, 0x21c0));                      // Pregnancy Status
+    removals_.insert(DicomTag(0x0010, 0x21d0));                      // Last Menstrual Date
+    removals_.insert(DicomTag(0x0010, 0x21f0));                      // Patient's Religious Preference
+    removals_.insert(DicomTag(0x0010, 0x2203));   /* X/Z */          // Patient Sex Neutered
+    removals_.insert(DicomTag(0x0010, 0x2297));                      // Responsible Person
+    removals_.insert(DicomTag(0x0010, 0x2299));                      // Responsible Organization
+    removals_.insert(DicomTag(0x0010, 0x4000));                      // Patient Comments
+    removals_.insert(DicomTag(0x0018, 0x1000));   /* X/Z/D */        // Device Serial Number
+    removals_.insert(DicomTag(0x0018, 0x1002));   /* TODO UID */     // Device UID
+    removals_.insert(DicomTag(0x0018, 0x1004));                      // Plate ID
+    removals_.insert(DicomTag(0x0018, 0x1005));                      // Generator ID
+    removals_.insert(DicomTag(0x0018, 0x1007));                      // Cassette ID
+    removals_.insert(DicomTag(0x0018, 0x1008));                      // Gantry ID
+    removals_.insert(DicomTag(0x0018, 0x1030));   /* X/D */          // Protocol Name
+    removals_.insert(DicomTag(0x0018, 0x1400));   /* X/D */          // Acquisition Device Processing Description
+    removals_.insert(DicomTag(0x0018, 0x2042));   /* TODO UID */     // Target UID
+    removals_.insert(DicomTag(0x0018, 0x4000));                      // Acquisition Comments
+    removals_.insert(DicomTag(0x0018, 0x700a));   /* X/D */          // Detector ID
+    removals_.insert(DicomTag(0x0018, 0x9424));                      // Acquisition Protocol Description
+    removals_.insert(DicomTag(0x0018, 0x9516));   /* X/D */          // Start Acquisition DateTime
+    removals_.insert(DicomTag(0x0018, 0x9517));   /* X/D */          // End Acquisition DateTime
+    removals_.insert(DicomTag(0x0018, 0xa003));                      // Contribution Description
+    removals_.insert(DicomTag(0x0020, 0x0052));   /* TODO UID */     // Frame of Reference UID
+    removals_.insert(DicomTag(0x0020, 0x0200));   /* TODO UID */     // Synchronization Frame of Reference UID
+    removals_.insert(DicomTag(0x0020, 0x3401));                      // Modifying Device ID
+    removals_.insert(DicomTag(0x0020, 0x3404));                      // Modifying Device Manufacturer
+    removals_.insert(DicomTag(0x0020, 0x3406));                      // Modified Image Description
+    removals_.insert(DicomTag(0x0020, 0x4000));                      // Image Comments
+    removals_.insert(DicomTag(0x0020, 0x9158));                      // Frame Comments
+    removals_.insert(DicomTag(0x0020, 0x9161));   /* TODO UID */     // Concatenation UID
+    removals_.insert(DicomTag(0x0020, 0x9164));   /* TODO UID */     // Dimension Organization UID
+    removals_.insert(DicomTag(0x0028, 0x1199));   /* TODO UID */     // Palette Color Lookup Table UID
+    removals_.insert(DicomTag(0x0028, 0x1214));   /* TODO UID */     // Large Palette Color Lookup Table UID
+    removals_.insert(DicomTag(0x0028, 0x4000));                      // Image Presentation Comments
+    removals_.insert(DicomTag(0x0032, 0x0012));                      // Study ID Issuer
+    removals_.insert(DicomTag(0x0032, 0x1020));                      // Scheduled Study Location
+    removals_.insert(DicomTag(0x0032, 0x1021));                      // Scheduled Study Location AE Title
+    removals_.insert(DicomTag(0x0032, 0x1030));                      // Reason for Study
+    removals_.insert(DicomTag(0x0032, 0x1032));                      // Requesting Physician
+    removals_.insert(DicomTag(0x0032, 0x1033));                      // Requesting Service
+    removals_.insert(DicomTag(0x0032, 0x1060));   /* X/Z */          // Requested Procedure Description
+    removals_.insert(DicomTag(0x0032, 0x1070));                      // Requested Contrast Agent
+    removals_.insert(DicomTag(0x0032, 0x4000));                      // Study Comments
+    removals_.insert(DicomTag(0x0038, 0x0004));                      // Referenced Patient Alias Sequence
+    removals_.insert(DicomTag(0x0038, 0x0010));                      // Admission ID
+    removals_.insert(DicomTag(0x0038, 0x0011));                      // Issuer of Admission ID
+    removals_.insert(DicomTag(0x0038, 0x001e));                      // Scheduled Patient Institution Residence
+    removals_.insert(DicomTag(0x0038, 0x0020));                      // Admitting Date
+    removals_.insert(DicomTag(0x0038, 0x0021));                      // Admitting Time
+    removals_.insert(DicomTag(0x0038, 0x0040));                      // Discharge Diagnosis Description
+    removals_.insert(DicomTag(0x0038, 0x0050));                      // Special Needs
+    removals_.insert(DicomTag(0x0038, 0x0060));                      // Service Episode ID
+    removals_.insert(DicomTag(0x0038, 0x0061));                      // Issuer of Service Episode ID
+    removals_.insert(DicomTag(0x0038, 0x0062));                      // Service Episode Description
+    removals_.insert(DicomTag(0x0038, 0x0300));                      // Current Patient Location
+    removals_.insert(DicomTag(0x0038, 0x0400));                      // Patient's Institution Residence
+    removals_.insert(DicomTag(0x0038, 0x0500));                      // Patient State
+    removals_.insert(DicomTag(0x0038, 0x4000));                      // Visit Comments
+    removals_.insert(DicomTag(0x0040, 0x0001));                      // Scheduled Station AE Title
+    removals_.insert(DicomTag(0x0040, 0x0002));                      // Scheduled Procedure Step Start Date
+    removals_.insert(DicomTag(0x0040, 0x0003));                      // Scheduled Procedure Step Start Time
+    removals_.insert(DicomTag(0x0040, 0x0004));                      // Scheduled Procedure Step End Date
+    removals_.insert(DicomTag(0x0040, 0x0005));                      // Scheduled Procedure Step End Time
+    removals_.insert(DicomTag(0x0040, 0x0006));                      // Scheduled Performing Physician Name
+    removals_.insert(DicomTag(0x0040, 0x0007));                      // Scheduled Procedure Step Description
+    removals_.insert(DicomTag(0x0040, 0x000b));                      // Scheduled Performing Physician Identification Sequence
+    removals_.insert(DicomTag(0x0040, 0x0010));                      // Scheduled Station Name
+    removals_.insert(DicomTag(0x0040, 0x0011));                      // Scheduled Procedure Step Location
+    removals_.insert(DicomTag(0x0040, 0x0012));                      // Pre-Medication
+    removals_.insert(DicomTag(0x0040, 0x0241));                      // Performed Station AE Title
+    removals_.insert(DicomTag(0x0040, 0x0242));                      // Performed Station Name
+    removals_.insert(DicomTag(0x0040, 0x0243));                      // Performed Location
+    removals_.insert(DicomTag(0x0040, 0x0244));                      // Performed Procedure Step Start Date
+    removals_.insert(DicomTag(0x0040, 0x0245));                      // Performed Procedure Step Start Time
+    removals_.insert(DicomTag(0x0040, 0x0250));                      // Performed Procedure Step End Date
+    removals_.insert(DicomTag(0x0040, 0x0251));                      // Performed Procedure Step End Time
+    removals_.insert(DicomTag(0x0040, 0x0253));                      // Performed Procedure Step ID
+    removals_.insert(DicomTag(0x0040, 0x0254));                      // Performed Procedure Step Description
+    removals_.insert(DicomTag(0x0040, 0x0275));                      // Request Attributes Sequence
+    removals_.insert(DicomTag(0x0040, 0x0280));                      // Comments on the Performed Procedure Step
+    removals_.insert(DicomTag(0x0040, 0x0555));                      // Acquisition Context Sequence
+    removals_.insert(DicomTag(0x0040, 0x1001));                      // Requested Procedure ID
+    removals_.insert(DicomTag(0x0040, 0x1004));                      // Patient Transport Arrangements
+    removals_.insert(DicomTag(0x0040, 0x1005));                      // Requested Procedure Location
+    removals_.insert(DicomTag(0x0040, 0x1010));                      // Names of Intended Recipient of Results
+    removals_.insert(DicomTag(0x0040, 0x1011));                      // Intended Recipients of Results Identification Sequence
+    removals_.insert(DicomTag(0x0040, 0x1102));                      // Person Address
+    removals_.insert(DicomTag(0x0040, 0x1103));                      // Person's Telephone Numbers
+    removals_.insert(DicomTag(0x0040, 0x1104));                      // Person's Telecom Information
+    removals_.insert(DicomTag(0x0040, 0x1400));                      // Requested Procedure Comments
+    removals_.insert(DicomTag(0x0040, 0x2001));                      // Reason for the Imaging Service Request
+    removals_.insert(DicomTag(0x0040, 0x2008));                      // Order Entered By
+    removals_.insert(DicomTag(0x0040, 0x2009));                      // Order Enterer Location
+    removals_.insert(DicomTag(0x0040, 0x2010));                      // Order Callback Phone Number
+    removals_.insert(DicomTag(0x0040, 0x2011));                      // Order Callback Telecom Information
+    removals_.insert(DicomTag(0x0040, 0x2400));                      // Imaging Service Request Comments
+    removals_.insert(DicomTag(0x0040, 0x3001));                      // Confidentiality Constraint on Patient Data Description
+    removals_.insert(DicomTag(0x0040, 0x4005));                      // Scheduled Procedure Step Start DateTime
+    removals_.insert(DicomTag(0x0040, 0x4010));                      // Scheduled Procedure Step Modification DateTime
+    removals_.insert(DicomTag(0x0040, 0x4011));                      // Expected Completion DateTime
+    removals_.insert(DicomTag(0x0040, 0x4023));   /* TODO UID */     // Referenced General Purpose Scheduled Procedure Step Transaction UID
+    removals_.insert(DicomTag(0x0040, 0x4025));                      // Scheduled Station Name Code Sequence
+    removals_.insert(DicomTag(0x0040, 0x4027));                      // Scheduled Station Geographic Location Code Sequence
+    removals_.insert(DicomTag(0x0040, 0x4028));                      // Performed Station Name Code Sequence
+    removals_.insert(DicomTag(0x0040, 0x4030));                      // Performed Station Geographic Location Code Sequence
+    removals_.insert(DicomTag(0x0040, 0x4034));                      // Scheduled Human Performers Sequence
+    removals_.insert(DicomTag(0x0040, 0x4035));                      // Actual Human Performers Sequence
+    removals_.insert(DicomTag(0x0040, 0x4036));                      // Human Performers Organization
+    removals_.insert(DicomTag(0x0040, 0x4037));                      // Human Performers Name
+    removals_.insert(DicomTag(0x0040, 0x4050));                      // Performed Procedure Step Start DateTime
+    removals_.insert(DicomTag(0x0040, 0x4051));                      // Performed Procedure Step End DateTime
+    removals_.insert(DicomTag(0x0040, 0x4052));                      // Procedure Step Cancellation DateTime
+    removals_.insert(DicomTag(0x0040, 0xa027));                      // Verifying Organization
+    removals_.insert(DicomTag(0x0040, 0xa078));                      // Author Observer Sequence
+    removals_.insert(DicomTag(0x0040, 0xa07a));                      // Participant Sequence
+    removals_.insert(DicomTag(0x0040, 0xa07c));                      // Custodial Organization Sequence
+    removals_.insert(DicomTag(0x0040, 0xa124));   /* TODO UID */     // UID
+    removals_.insert(DicomTag(0x0040, 0xa171));   /* TODO UID */     // Observation UID
+    removals_.insert(DicomTag(0x0040, 0xa172));   /* TODO UID */     // Referenced Observation UID (Trial)
+    removals_.insert(DicomTag(0x0040, 0xa192));                      // Observation Date (Trial)
+    removals_.insert(DicomTag(0x0040, 0xa193));                      // Observation Time (Trial)
+    removals_.insert(DicomTag(0x0040, 0xa307));                      // Current Observer (Trial)
+    removals_.insert(DicomTag(0x0040, 0xa352));                      // Verbal Source (Trial)
+    removals_.insert(DicomTag(0x0040, 0xa353));                      // Address (Trial)
+    removals_.insert(DicomTag(0x0040, 0xa354));                      // Telephone Number (Trial)
+    removals_.insert(DicomTag(0x0040, 0xa358));                      // Verbal Source Identifier Code Sequence (Trial)
+    removals_.insert(DicomTag(0x0040, 0xa402));   /* TODO UID */     // Observation Subject UID (Trial)
+    removals_.insert(DicomTag(0x0040, 0xa730));                      // Content Sequence
+    removals_.insert(DicomTag(0x0040, 0xdb0c));   /* TODO UID */     // Template Extension Organization UID
+    removals_.insert(DicomTag(0x0040, 0xdb0d));   /* TODO UID */     // Template Extension Creator UID
+    removals_.insert(DicomTag(0x0062, 0x0021));   /* TODO UID */     // Tracking UID
+    removals_.insert(DicomTag(0x0070, 0x0086));                      // Content Creator's Identification Code Sequence
+    removals_.insert(DicomTag(0x0070, 0x031a));   /* TODO UID */     // Fiducial UID
+    removals_.insert(DicomTag(0x0070, 0x1101));   /* TODO UID */     // Presentation Display Collection UID
+    removals_.insert(DicomTag(0x0070, 0x1102));   /* TODO UID */     // Presentation Sequence Collection UID
+    removals_.insert(DicomTag(0x0088, 0x0140));   /* TODO UID */     // Storage Media File-set UID
+    removals_.insert(DicomTag(0x0088, 0x0200));                      // Icon Image Sequence(see Note 12)
+    removals_.insert(DicomTag(0x0088, 0x0904));                      // Topic Title
+    removals_.insert(DicomTag(0x0088, 0x0906));                      // Topic Subject
+    removals_.insert(DicomTag(0x0088, 0x0910));                      // Topic Author
+    removals_.insert(DicomTag(0x0088, 0x0912));                      // Topic Keywords
+    removals_.insert(DicomTag(0x0400, 0x0100));                      // Digital Signature UID
+    removals_.insert(DicomTag(0x0400, 0x0402));                      // Referenced Digital Signature Sequence
+    removals_.insert(DicomTag(0x0400, 0x0403));                      // Referenced SOP Instance MAC Sequence
+    removals_.insert(DicomTag(0x0400, 0x0404));                      // MAC
+    removals_.insert(DicomTag(0x0400, 0x0550));                      // Modified Attributes Sequence
+    removals_.insert(DicomTag(0x0400, 0x0561));                      // Original Attributes Sequence
+    removals_.insert(DicomTag(0x2030, 0x0020));                      // Text String
+    removals_.insert(DicomTag(0x3006, 0x0024));   /* TODO UID */     // Referenced Frame of Reference UID
+    removals_.insert(DicomTag(0x3006, 0x00c2));   /* TODO UID */     // Related Frame of Reference UID
+    removals_.insert(DicomTag(0x3008, 0x0105));                      // Source Serial Number
+    removals_.insert(DicomTag(0x300a, 0x0013));   /* TODO UID */     // Dose Reference UID
+    removals_.insert(DicomTag(0x300c, 0x0113));                      // Reason for Omission Description
+    removals_.insert(DicomTag(0x300e, 0x0008));   /* X/Z */          // Reviewer Name
+    removals_.insert(DicomTag(0x4000, 0x0010));                      // Arbitrary
+    removals_.insert(DicomTag(0x4000, 0x4000));                      // Text Comments
+    removals_.insert(DicomTag(0x4008, 0x0042));                      // Results ID Issuer
+    removals_.insert(DicomTag(0x4008, 0x0102));                      // Interpretation Recorder
+    removals_.insert(DicomTag(0x4008, 0x010a));                      // Interpretation Transcriber
+    removals_.insert(DicomTag(0x4008, 0x010b));                      // Interpretation Text
+    removals_.insert(DicomTag(0x4008, 0x010c));                      // Interpretation Author
+    removals_.insert(DicomTag(0x4008, 0x0111));                      // Interpretation Approver Sequence
+    removals_.insert(DicomTag(0x4008, 0x0114));                      // Physician Approving Interpretation
+    removals_.insert(DicomTag(0x4008, 0x0115));                      // Interpretation Diagnosis Description
+    removals_.insert(DicomTag(0x4008, 0x0118));                      // Results Distribution List Sequence
+    removals_.insert(DicomTag(0x4008, 0x0119));                      // Distribution Name
+    removals_.insert(DicomTag(0x4008, 0x011a));                      // Distribution Address
+    removals_.insert(DicomTag(0x4008, 0x0202));                      // Interpretation ID Issuer
+    removals_.insert(DicomTag(0x4008, 0x0300));                      // Impressions
+    removals_.insert(DicomTag(0x4008, 0x4000));                      // Results Comments
+    removals_.insert(DicomTag(0xfffa, 0xfffa));                      // Digital Signatures Sequence
+    removals_.insert(DicomTag(0xfffc, 0xfffc));                      // Data Set Trailing Padding
+    
+    // Set the DeidentificationMethod tag
+    ReplaceInternal(DICOM_TAG_DEIDENTIFICATION_METHOD, ORTHANC_DEIDENTIFICATION_METHOD_2017c);
+  }
+  
+
+  void DicomModification::SetupAnonymization(DicomVersion version)
+  {
+    removals_.clear();
+    clearings_.clear();
+    ClearReplacements();
+    removePrivateTags_ = true;
+    level_ = ResourceType_Patient;
+    uidMap_.clear();
+    privateTagsToKeep_.clear();
+
+    switch (version)
+    {
+      case DicomVersion_2008:
+        SetupAnonymization2008();
+        break;
+
+      case DicomVersion_2017c:
+        SetupAnonymization2017c();
+        break;
+
+      default:
+        throw OrthancException(ErrorCode_ParameterOutOfRange);
+    }
 
     // Set the PatientIdentityRemoved tag
     ReplaceInternal(DicomTag(0x0012, 0x0062), "YES");
@@ -460,21 +1075,28 @@ namespace Orthanc
       toModify.RemovePrivateTags(privateTagsToKeep_);
     }
 
-    // (2) Remove the tags specified by the user
+    // (2) Clear the tags specified by the user
+    for (SetOfTags::const_iterator it = clearings_.begin(); 
+         it != clearings_.end(); ++it)
+    {
+      toModify.Clear(*it, true /* only clear if the tag exists in the original file */);
+    }
+
+    // (3) Remove the tags specified by the user
     for (SetOfTags::const_iterator it = removals_.begin(); 
          it != removals_.end(); ++it)
     {
       toModify.Remove(*it);
     }
 
-    // (3) Replace the tags
+    // (4) Replace the tags
     for (Replacements::const_iterator it = replacements_.begin(); 
          it != replacements_.end(); ++it)
     {
       toModify.Replace(it->first, *it->second, true /* decode data URI scheme */, DicomReplaceMode_InsertIfAbsent);
     }
 
-    // (4) Update the DICOM identifiers
+    // (5) Update the DICOM identifiers
     if (level_ <= ResourceType_Study &&
         !IsReplaced(DICOM_TAG_STUDY_INSTANCE_UID))
     {
diff --git a/OrthancServer/DicomModification.h b/OrthancServer/DicomModification.h
index e92c177..ce99c4c 100644
--- a/OrthancServer/DicomModification.h
+++ b/OrthancServer/DicomModification.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -51,6 +52,7 @@ namespace Orthanc
     typedef std::map< std::pair<ResourceType, std::string>, std::string>  UidMap;
 
     SetOfTags removals_;
+    SetOfTags clearings_;
     Replacements replacements_;
     bool removePrivateTags_;
     ResourceType level_;
@@ -67,11 +69,15 @@ namespace Orthanc
 
     void ClearReplacements();
 
-    void RemoveInternal(const DicomTag& tag);
+    bool CancelReplacement(const DicomTag& tag);
 
     void ReplaceInternal(const DicomTag& tag,
                          const Json::Value& value);
 
+    void SetupAnonymization2008();
+
+    void SetupAnonymization2017c();
+
   public:
     DicomModification();
 
@@ -81,11 +87,18 @@ namespace Orthanc
 
     void Remove(const DicomTag& tag);
 
+    // Replace the DICOM tag as a NULL/empty value (e.g. for anonymization)
+    void Clear(const DicomTag& tag);
+
     bool IsRemoved(const DicomTag& tag) const;
 
+    bool IsCleared(const DicomTag& tag) const;
+
+    // "safeForAnonymization" tells Orthanc that this replacement does
+    // not break the anonymization process it implements (for internal use only)
     void Replace(const DicomTag& tag,
                  const Json::Value& value,   // Encoded using UTF-8
-                 bool safeForAnonymization = false);
+                 bool safeForAnonymization);
 
     bool IsReplaced(const DicomTag& tag) const;
 
@@ -107,7 +120,7 @@ namespace Orthanc
       return level_;
     }
 
-    void SetupAnonymization();
+    void SetupAnonymization(DicomVersion version);
 
     void Apply(ParsedDicomFile& toModify);
 
diff --git a/OrthancServer/DicomProtocol/DicomFindAnswers.cpp b/OrthancServer/DicomProtocol/DicomFindAnswers.cpp
index be15a63..c32f26a 100644
--- a/OrthancServer/DicomProtocol/DicomFindAnswers.cpp
+++ b/OrthancServer/DicomProtocol/DicomFindAnswers.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DicomProtocol/DicomFindAnswers.h b/OrthancServer/DicomProtocol/DicomFindAnswers.h
index f06bbe9..da07d76 100644
--- a/OrthancServer/DicomProtocol/DicomFindAnswers.h
+++ b/OrthancServer/DicomProtocol/DicomFindAnswers.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DicomProtocol/DicomServer.cpp b/OrthancServer/DicomProtocol/DicomServer.cpp
index b908420..c9337e4 100644
--- a/OrthancServer/DicomProtocol/DicomServer.cpp
+++ b/OrthancServer/DicomProtocol/DicomServer.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DicomProtocol/DicomServer.h b/OrthancServer/DicomProtocol/DicomServer.h
index f4d5f3a..5afadda 100644
--- a/OrthancServer/DicomProtocol/DicomServer.h
+++ b/OrthancServer/DicomProtocol/DicomServer.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DicomProtocol/DicomUserConnection.cpp b/OrthancServer/DicomProtocol/DicomUserConnection.cpp
index c8a7ff5..fccc033 100644
--- a/OrthancServer/DicomProtocol/DicomUserConnection.cpp
+++ b/OrthancServer/DicomProtocol/DicomUserConnection.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -104,7 +105,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  * but this string must be 256 bytes or less.
  * http://msdn.microsoft.com/en-us/library/windows/desktop/ms738527(v=vs.85).aspx
  **/
-#define HOST_NAME_MAX 256
+#  define HOST_NAME_MAX 256
+#  include <winsock.h>
 #endif 
 
 
@@ -483,27 +485,33 @@ namespace Orthanc
   static ParsedDicomFile* ConvertQueryFields(const DicomMap& fields,
                                              ModalityManufacturer manufacturer)
   {
+    // Fix outgoing C-Find requests issue for Syngo.Via and its
+    // solution was reported by Emsy Chan by private mail on
+    // 2015-06-17. According to Robert van Ommen (2015-11-30), the
+    // same fix is required for Agfa Impax. This was generalized for
+    // generic manufacturer since it seems to affect PhilipsADW,
+    // GEWAServer as well:
+    // https://bitbucket.org/sjodogne/orthanc/issues/31/
+
     switch (manufacturer)
     {
-      case ModalityManufacturer_AgfaImpax:
-      case ModalityManufacturer_SyngoVia:
+      case ModalityManufacturer_GenericNoWildcardInDates:
+      case ModalityManufacturer_GenericNoUniversalWildcard:
       {
         std::auto_ptr<DicomMap> fix(fields.Clone());
 
-        // This issue for Syngo.Via and its solution was reported by
-        // Emsy Chan by private mail on 2015-06-17. According to
-        // Robert van Ommen (2015-11-30), the same fix is required for
-        // Agfa Impax.
         std::set<DicomTag> tags;
         fix->GetTags(tags);
 
         for (std::set<DicomTag>::const_iterator it = tags.begin(); it != tags.end(); ++it)
         {
-          if (FromDcmtkBridge::LookupValueRepresentation(*it) == ValueRepresentation_Date)
+          // Replace a "*" wildcard query by an empty query ("") for
+          // "date" or "all" value representations depending on the
+          // type of manufacturer.
+          if (manufacturer == ModalityManufacturer_GenericNoUniversalWildcard ||
+              (manufacturer == ModalityManufacturer_GenericNoWildcardInDates &&
+               FromDcmtkBridge::LookupValueRepresentation(*it) == ValueRepresentation_Date))
           {
-            // Replace a "*" query by an empty query ("") for "date"
-            // value representations. Necessary to search over dates
-            // in Syngo.Via.
             const DicomValue* value = fix->TestAndGetValue(*it);
 
             if (value != NULL && 
diff --git a/OrthancServer/DicomProtocol/DicomUserConnection.h b/OrthancServer/DicomProtocol/DicomUserConnection.h
index 6161578..d3a7b4d 100644
--- a/OrthancServer/DicomProtocol/DicomUserConnection.h
+++ b/OrthancServer/DicomProtocol/DicomUserConnection.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DicomProtocol/IApplicationEntityFilter.h b/OrthancServer/DicomProtocol/IApplicationEntityFilter.h
index 1518fd6..2e46d5d 100644
--- a/OrthancServer/DicomProtocol/IApplicationEntityFilter.h
+++ b/OrthancServer/DicomProtocol/IApplicationEntityFilter.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DicomProtocol/IFindRequestHandler.h b/OrthancServer/DicomProtocol/IFindRequestHandler.h
index eaa0362..91eef22 100644
--- a/OrthancServer/DicomProtocol/IFindRequestHandler.h
+++ b/OrthancServer/DicomProtocol/IFindRequestHandler.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -48,6 +49,7 @@ namespace Orthanc
                         const std::list<DicomTag>& sequencesToReturn,
                         const std::string& remoteIp,
                         const std::string& remoteAet,
-                        const std::string& calledAet) = 0;
+                        const std::string& calledAet,
+                        ModalityManufacturer manufacturer) = 0;
   };
 }
diff --git a/OrthancServer/DicomProtocol/IFindRequestHandlerFactory.h b/OrthancServer/DicomProtocol/IFindRequestHandlerFactory.h
index 4f76263..3214ba1 100644
--- a/OrthancServer/DicomProtocol/IFindRequestHandlerFactory.h
+++ b/OrthancServer/DicomProtocol/IFindRequestHandlerFactory.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DicomProtocol/IMoveRequestHandler.h b/OrthancServer/DicomProtocol/IMoveRequestHandler.h
index 44942e6..0ca5ae1 100644
--- a/OrthancServer/DicomProtocol/IMoveRequestHandler.h
+++ b/OrthancServer/DicomProtocol/IMoveRequestHandler.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DicomProtocol/IMoveRequestHandlerFactory.h b/OrthancServer/DicomProtocol/IMoveRequestHandlerFactory.h
index b826f4e..6db0566 100644
--- a/OrthancServer/DicomProtocol/IMoveRequestHandlerFactory.h
+++ b/OrthancServer/DicomProtocol/IMoveRequestHandlerFactory.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DicomProtocol/IStoreRequestHandler.h b/OrthancServer/DicomProtocol/IStoreRequestHandler.h
index 6be724d..f03c5ab 100644
--- a/OrthancServer/DicomProtocol/IStoreRequestHandler.h
+++ b/OrthancServer/DicomProtocol/IStoreRequestHandler.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DicomProtocol/IStoreRequestHandlerFactory.h b/OrthancServer/DicomProtocol/IStoreRequestHandlerFactory.h
index 7a3754f..c0d45d0 100644
--- a/OrthancServer/DicomProtocol/IStoreRequestHandlerFactory.h
+++ b/OrthancServer/DicomProtocol/IStoreRequestHandlerFactory.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DicomProtocol/IWorklistRequestHandler.h b/OrthancServer/DicomProtocol/IWorklistRequestHandler.h
index 7f57b71..ce6d858 100644
--- a/OrthancServer/DicomProtocol/IWorklistRequestHandler.h
+++ b/OrthancServer/DicomProtocol/IWorklistRequestHandler.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -47,6 +48,7 @@ namespace Orthanc
                         ParsedDicomFile& query,
                         const std::string& remoteIp,
                         const std::string& remoteAet,
-                        const std::string& calledAet) = 0;
+                        const std::string& calledAet,
+                        ModalityManufacturer manufacturer) = 0;
   };
 }
diff --git a/OrthancServer/DicomProtocol/IWorklistRequestHandlerFactory.h b/OrthancServer/DicomProtocol/IWorklistRequestHandlerFactory.h
index 039e8d3..121663b 100644
--- a/OrthancServer/DicomProtocol/IWorklistRequestHandlerFactory.h
+++ b/OrthancServer/DicomProtocol/IWorklistRequestHandlerFactory.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DicomProtocol/RemoteModalityParameters.cpp b/OrthancServer/DicomProtocol/RemoteModalityParameters.cpp
index 8c158cc..a99c643 100644
--- a/OrthancServer/DicomProtocol/RemoteModalityParameters.cpp
+++ b/OrthancServer/DicomProtocol/RemoteModalityParameters.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DicomProtocol/RemoteModalityParameters.h b/OrthancServer/DicomProtocol/RemoteModalityParameters.h
index d0d3700..7b382ee 100644
--- a/OrthancServer/DicomProtocol/RemoteModalityParameters.h
+++ b/OrthancServer/DicomProtocol/RemoteModalityParameters.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DicomProtocol/ReusableDicomUserConnection.cpp b/OrthancServer/DicomProtocol/ReusableDicomUserConnection.cpp
index e2c3892..65f84a6 100644
--- a/OrthancServer/DicomProtocol/ReusableDicomUserConnection.cpp
+++ b/OrthancServer/DicomProtocol/ReusableDicomUserConnection.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/DicomProtocol/ReusableDicomUserConnection.h b/OrthancServer/DicomProtocol/ReusableDicomUserConnection.h
index aee23b1..8f3d666 100644
--- a/OrthancServer/DicomProtocol/ReusableDicomUserConnection.h
+++ b/OrthancServer/DicomProtocol/ReusableDicomUserConnection.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/ExportedResource.cpp b/OrthancServer/ExportedResource.cpp
index 552fa2d..117930b 100644
--- a/OrthancServer/ExportedResource.cpp
+++ b/OrthancServer/ExportedResource.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/ExportedResource.h b/OrthancServer/ExportedResource.h
index ad76921..9778876 100644
--- a/OrthancServer/ExportedResource.h
+++ b/OrthancServer/ExportedResource.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/FromDcmtkBridge.cpp b/OrthancServer/FromDcmtkBridge.cpp
index afd33b8..b81362b 100644
--- a/OrthancServer/FromDcmtkBridge.cpp
+++ b/OrthancServer/FromDcmtkBridge.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -180,6 +181,8 @@ namespace Orthanc
 
   void FromDcmtkBridge::InitializeDictionary(bool loadPrivateDictionary)
   {
+    LOG(INFO) << "Using DCTMK version: " << DCMTK_VERSION_NUMBER;
+    
     {
       DictionaryLocker locker;
 
@@ -206,7 +209,7 @@ namespace Orthanc
         LOG(INFO) << "The dictionary of private tags has not been loaded";
       }
 
-#elif defined(__linux__) || defined(__FreeBSD_kernel__)
+#elif defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
       std::string path = DCMTK_DICTIONARY_DIR;
 
       const char* env = std::getenv(DCM_DICT_ENVIRONMENT_VARIABLE);
@@ -1680,7 +1683,7 @@ namespace Orthanc
           throw OrthancException(ErrorCode_BadParameterType);
         }
 
-        DcmSequenceOfItems* sequence = new DcmSequenceOfItems(key, value.size());
+        DcmSequenceOfItems* sequence = new DcmSequenceOfItems(key);
         element.reset(sequence);
         
         for (Json::Value::ArrayIndex i = 0; i < value.size(); i++)
@@ -1977,6 +1980,7 @@ namespace Orthanc
   }
 
 
+#if ORTHANC_ENABLE_LUA == 1
   void FromDcmtkBridge::ExecuteToDicom(DicomMap& target,
                                        LuaFunctionCall& call)
   {
@@ -2012,4 +2016,5 @@ namespace Orthanc
       target.SetValue(tag, output[members[i]].asString(), false);
     }
   }
+#endif
 }
diff --git a/OrthancServer/FromDcmtkBridge.h b/OrthancServer/FromDcmtkBridge.h
index d7ee001..9a05d5f 100644
--- a/OrthancServer/FromDcmtkBridge.h
+++ b/OrthancServer/FromDcmtkBridge.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -36,7 +37,6 @@
 
 #include "../Core/DicomFormat/DicomElement.h"
 #include "../Core/DicomFormat/DicomMap.h"
-#include "../Core/Lua/LuaFunctionCall.h"
 
 #include <dcmtk/dcmdata/dcdatset.h>
 #include <dcmtk/dcmdata/dcmetinf.h>
@@ -44,10 +44,22 @@
 #include <dcmtk/dcmdata/dcfilefo.h>
 #include <json/json.h>
 
+#if !defined(ORTHANC_BUILD_UNIT_TESTS)
+#  error The macro ORTHANC_BUILD_UNIT_TESTS must be defined
+#endif
+
+#if !defined(ORTHANC_ENABLE_LUA)
+#  error The macro ORTHANC_ENABLE_LUA must be defined
+#endif
+
 #if ORTHANC_BUILD_UNIT_TESTS == 1
 #  include <gtest/gtest_prod.h>
 #endif
 
+#if ORTHANC_ENABLE_LUA == 1
+#  include "../Core/Lua/LuaFunctionCall.h"
+#endif
+
 
 namespace Orthanc
 {
@@ -204,7 +216,9 @@ namespace Orthanc
     static bool LookupTransferSyntax(std::string& result,
                                      DcmFileFormat& dicom);
 
+#if ORTHANC_ENABLE_LUA == 1
     static void ExecuteToDicom(DicomMap& target,
                                LuaFunctionCall& call);
+#endif
   };
 }
diff --git a/OrthancServer/IDatabaseListener.h b/OrthancServer/IDatabaseListener.h
index d29bbd5..00099b3 100644
--- a/OrthancServer/IDatabaseListener.h
+++ b/OrthancServer/IDatabaseListener.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/IDatabaseWrapper.h b/OrthancServer/IDatabaseWrapper.h
index 0892a3d..1c2f5b6 100644
--- a/OrthancServer/IDatabaseWrapper.h
+++ b/OrthancServer/IDatabaseWrapper.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/IDicomImageDecoder.h b/OrthancServer/IDicomImageDecoder.h
index ef891a4..4852467 100644
--- a/OrthancServer/IDicomImageDecoder.h
+++ b/OrthancServer/IDicomImageDecoder.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/IServerListener.h b/OrthancServer/IServerListener.h
index 185037b..12a3dea 100644
--- a/OrthancServer/IServerListener.h
+++ b/OrthancServer/IServerListener.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Internals/CommandDispatcher.cpp b/OrthancServer/Internals/CommandDispatcher.cpp
index a29690b..71ed77e 100644
--- a/OrthancServer/Internals/CommandDispatcher.cpp
+++ b/OrthancServer/Internals/CommandDispatcher.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -805,13 +806,12 @@ namespace Orthanc
 
         // Check whether this request is allowed by the security filter
         if (supported && 
-            request != DicomRequestType_Echo &&  // Always allow incoming ECHO requests
             filter_ != NULL &&
             !filter_->IsAllowedRequest(remoteIp_, remoteAet_, calledAet_, request))
         {
-          LOG(ERROR) << EnumerationToString(request) 
-                     << " requests are disallowed for the AET \"" 
-                     << remoteAet_ << "\"";
+          LOG(WARNING) << "Rejected " << EnumerationToString(request)
+                       << " request from remote DICOM modality with AET \""
+                       << remoteAet_ << "\" and hostname \"" << remoteIp_ << "\"";
           cond = DIMSE_ILLEGALASSOCIATION;
           supported = false;
           finished = true;
@@ -905,7 +905,7 @@ namespace Orthanc
         else
         {
           OFString temp_str;
-          LOG(ERROR) << "DIMSE failure (aborting association): " << cond.text();
+          LOG(INFO) << "DIMSE failure (aborting association): " << cond.text();
           /* some kind of error so abort the association */
           ASC_abortAssociation(assoc_);
         }
diff --git a/OrthancServer/Internals/CommandDispatcher.h b/OrthancServer/Internals/CommandDispatcher.h
index eeb8559..84553eb 100644
--- a/OrthancServer/Internals/CommandDispatcher.h
+++ b/OrthancServer/Internals/CommandDispatcher.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Internals/DicomFrameIndex.cpp b/OrthancServer/Internals/DicomFrameIndex.cpp
index 8e8aaf4..67c9406 100644
--- a/OrthancServer/Internals/DicomFrameIndex.cpp
+++ b/OrthancServer/Internals/DicomFrameIndex.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Internals/DicomFrameIndex.h b/OrthancServer/Internals/DicomFrameIndex.h
index 7a15f69..52a1819 100644
--- a/OrthancServer/Internals/DicomFrameIndex.h
+++ b/OrthancServer/Internals/DicomFrameIndex.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Internals/DicomImageDecoder.cpp b/OrthancServer/Internals/DicomImageDecoder.cpp
index 6165090..a20f0ef 100644
--- a/OrthancServer/Internals/DicomImageDecoder.cpp
+++ b/OrthancServer/Internals/DicomImageDecoder.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -726,7 +727,8 @@ namespace Orthanc
 
 
   void DicomImageDecoder::ApplyExtractionMode(std::auto_ptr<ImageAccessor>& image,
-                                              ImageExtractionMode mode)
+                                              ImageExtractionMode mode,
+                                              bool invert)
   {
     if (image.get() == NULL)
     {
@@ -760,6 +762,11 @@ namespace Orthanc
     if (ok)
     {
       assert(image.get() != NULL);
+
+      if (invert)
+      {
+        Orthanc::ImageProcessing::Invert(*image);
+      }
     }
     else
     {
@@ -770,9 +777,10 @@ namespace Orthanc
 
   void DicomImageDecoder::ExtractPngImage(std::string& result,
                                           std::auto_ptr<ImageAccessor>& image,
-                                          ImageExtractionMode mode)
+                                          ImageExtractionMode mode,
+                                          bool invert)
   {
-    ApplyExtractionMode(image, mode);
+    ApplyExtractionMode(image, mode, invert);
 
     PngWriter writer;
     writer.WriteToMemory(result, *image);
@@ -782,6 +790,7 @@ namespace Orthanc
   void DicomImageDecoder::ExtractJpegImage(std::string& result,
                                            std::auto_ptr<ImageAccessor>& image,
                                            ImageExtractionMode mode,
+                                           bool invert,
                                            uint8_t quality)
   {
     if (mode != ImageExtractionMode_UInt8 &&
@@ -790,7 +799,7 @@ namespace Orthanc
       throw OrthancException(ErrorCode_ParameterOutOfRange);
     }
 
-    ApplyExtractionMode(image, mode);
+    ApplyExtractionMode(image, mode, invert);
 
     JpegWriter writer;
     writer.SetQuality(quality);
diff --git a/OrthancServer/Internals/DicomImageDecoder.h b/OrthancServer/Internals/DicomImageDecoder.h
index 97a9278..5a791d0 100644
--- a/OrthancServer/Internals/DicomImageDecoder.h
+++ b/OrthancServer/Internals/DicomImageDecoder.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -78,7 +79,8 @@ namespace Orthanc
     static bool PreviewDecodedImage(std::auto_ptr<ImageAccessor>& image);
 
     static void ApplyExtractionMode(std::auto_ptr<ImageAccessor>& image,
-                                    ImageExtractionMode mode);
+                                    ImageExtractionMode mode,
+                                    bool invert);
 
   public:
     static bool IsPsmctRle1(DcmDataset& dataset);
@@ -91,11 +93,13 @@ namespace Orthanc
 
     static void ExtractPngImage(std::string& result,
                                 std::auto_ptr<ImageAccessor>& image,
-                                ImageExtractionMode mode);
+                                ImageExtractionMode mode,
+                                bool invert);
 
     static void ExtractJpegImage(std::string& result,
                                  std::auto_ptr<ImageAccessor>& image,
                                  ImageExtractionMode mode,
+                                 bool invert,
                                  uint8_t quality);
   };
 }
diff --git a/OrthancServer/Internals/FindScp.cpp b/OrthancServer/Internals/FindScp.cpp
index b3a52e0..a17e601 100644
--- a/OrthancServer/Internals/FindScp.cpp
+++ b/OrthancServer/Internals/FindScp.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -190,6 +191,20 @@ namespace Orthanc
 
         try
         {
+          RemoteModalityParameters modality;
+
+          /**
+           * Ensure that the remote modality is known to Orthanc for C-FIND requests.
+           **/
+
+          if (!Configuration::LookupDicomModalityUsingAETitle(modality, *data.remoteAet_))
+          {
+            LOG(ERROR) << "Modality with AET \"" << *data.remoteAet_
+                       << "\" is not defined in the \"DicomModalities\" configuration option";
+            throw OrthancException(ErrorCode_UnknownModality);
+          }
+
+          
           if (sopClassUid == UID_FINDModalityWorklistInformationModel)
           {
             data.answers_.SetWorklist(true);
@@ -201,7 +216,7 @@ namespace Orthanc
 
               data.worklistHandler_->Handle(data.answers_, query,
                                             *data.remoteIp_, *data.remoteAet_,
-                                            *data.calledAet_);
+                                            *data.calledAet_, modality.GetManufacturer());
               ok = true;
             }
             else
@@ -241,7 +256,7 @@ namespace Orthanc
 
               data.findHandler_->Handle(data.answers_, input, sequencesToReturn,
                                         *data.remoteIp_, *data.remoteAet_,
-                                        *data.calledAet_);
+                                        *data.calledAet_, modality.GetManufacturer());
               ok = true;
             }
             else
diff --git a/OrthancServer/Internals/FindScp.h b/OrthancServer/Internals/FindScp.h
index 6e368c0..5d63f94 100644
--- a/OrthancServer/Internals/FindScp.h
+++ b/OrthancServer/Internals/FindScp.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Internals/MoveScp.cpp b/OrthancServer/Internals/MoveScp.cpp
index a37b8f5..5578f88 100644
--- a/OrthancServer/Internals/MoveScp.cpp
+++ b/OrthancServer/Internals/MoveScp.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Internals/MoveScp.h b/OrthancServer/Internals/MoveScp.h
index 46516b9..0e4e103 100644
--- a/OrthancServer/Internals/MoveScp.h
+++ b/OrthancServer/Internals/MoveScp.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Internals/StoreScp.cpp b/OrthancServer/Internals/StoreScp.cpp
index 30b9025..692765a 100644
--- a/OrthancServer/Internals/StoreScp.cpp
+++ b/OrthancServer/Internals/StoreScp.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Internals/StoreScp.h b/OrthancServer/Internals/StoreScp.h
index ac9af45..6c28fb4 100644
--- a/OrthancServer/Internals/StoreScp.h
+++ b/OrthancServer/Internals/StoreScp.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/LuaScripting.cpp b/OrthancServer/LuaScripting.cpp
index d80cd0a..0bce73f 100644
--- a/OrthancServer/LuaScripting.cpp
+++ b/OrthancServer/LuaScripting.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/LuaScripting.h b/OrthancServer/LuaScripting.h
index e355290..5378dc4 100644
--- a/OrthancServer/LuaScripting.h
+++ b/OrthancServer/LuaScripting.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/OrthancFindRequestHandler.cpp b/OrthancServer/OrthancFindRequestHandler.cpp
index 2134ff1..f64f5c6 100644
--- a/OrthancServer/OrthancFindRequestHandler.cpp
+++ b/OrthancServer/OrthancFindRequestHandler.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -450,19 +451,16 @@ namespace Orthanc
                                                  const DicomTag& tag,
                                                  ModalityManufacturer manufacturer)
   {
-    switch (manufacturer)
+    // Whatever the manufacturer, remove the GenericGroupLength tags
+    // http://dicom.nema.org/medical/dicom/current/output/chtml/part05/sect_7.2.html
+    // https://bitbucket.org/sjodogne/orthanc/issues/31/
+    if (tag.GetGroup() == 0x0000)
     {
-      case ModalityManufacturer_EFilm2:
-        // Following Denis Nesterov's mail on 2015-11-30
-        if (tag == DicomTag(0x0008, 0x0000) ||  // "GenericGroupLength"
-            tag == DicomTag(0x0010, 0x0000) ||  // "GenericGroupLength"
-            tag == DicomTag(0x0020, 0x0000))    // "GenericGroupLength"
-        {
-          return false;
-        }
-
-        break;
+      return false;
+    }
 
+    switch (manufacturer)
+    {
       case ModalityManufacturer_Vitrea:
         // Following Denis Nesterov's mail on 2015-11-30
         if (tag == DicomTag(0x5653, 0x0010))  // "PrivateCreator = Vital Images SW 3.4"
@@ -515,23 +513,10 @@ namespace Orthanc
                                          const std::list<DicomTag>& sequencesToReturn,
                                          const std::string& remoteIp,
                                          const std::string& remoteAet,
-                                         const std::string& calledAet)
+                                         const std::string& calledAet,
+                                         ModalityManufacturer manufacturer)
   {
     /**
-     * Ensure that the remote modality is known to Orthanc.
-     **/
-
-    RemoteModalityParameters modality;
-
-    if (!Configuration::LookupDicomModalityUsingAETitle(modality, remoteAet))
-    {
-      throw OrthancException(ErrorCode_UnknownModality);
-    }
-
-    bool caseSensitivePN = Configuration::GetGlobalBoolParameter("CaseSensitivePN", false);
-
-
-    /**
      * Possibly apply the user-supplied Lua filter.
      **/
 
@@ -597,6 +582,8 @@ namespace Orthanc
 
     LookupResource finder(level);
 
+    const bool caseSensitivePN = Configuration::GetGlobalBoolParameter("CaseSensitivePN", false);
+
     for (size_t i = 0; i < query.GetSize(); i++)
     {
       const DicomElement& element = query.GetElement(i);
@@ -616,7 +603,7 @@ namespace Orthanc
         continue;
       }
 
-      if (FilterQueryTag(value, level, tag, modality.GetManufacturer()))
+      if (FilterQueryTag(value, level, tag, manufacturer))
       {
         ValueRepresentation vr = FromDcmtkBridge::LookupValueRepresentation(tag);
 
diff --git a/OrthancServer/OrthancFindRequestHandler.h b/OrthancServer/OrthancFindRequestHandler.h
index c0f0c9c..5577489 100644
--- a/OrthancServer/OrthancFindRequestHandler.h
+++ b/OrthancServer/OrthancFindRequestHandler.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -71,7 +72,8 @@ namespace Orthanc
                         const std::list<DicomTag>& sequencesToReturn,
                         const std::string& remoteIp,
                         const std::string& remoteAet,
-                        const std::string& calledAet);
+                        const std::string& calledAet,
+                        ModalityManufacturer manufacturer);
 
     unsigned int GetMaxResults() const
     {
diff --git a/OrthancServer/OrthancHttpHandler.cpp b/OrthancServer/OrthancHttpHandler.cpp
index 28405cf..a5fa98d 100644
--- a/OrthancServer/OrthancHttpHandler.cpp
+++ b/OrthancServer/OrthancHttpHandler.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/OrthancHttpHandler.h b/OrthancServer/OrthancHttpHandler.h
index cc7693c..468dfba 100644
--- a/OrthancServer/OrthancHttpHandler.h
+++ b/OrthancServer/OrthancHttpHandler.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/OrthancInitialization.cpp b/OrthancServer/OrthancInitialization.cpp
index a4e2830..0bc6ca1 100644
--- a/OrthancServer/OrthancInitialization.cpp
+++ b/OrthancServer/OrthancInitialization.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -471,6 +472,16 @@ namespace Orthanc
     ReadGlobalConfiguration(configurationFile);
     ValidateGlobalConfiguration();
 
+    if (configuration_.isMember("Locale"))
+    {
+      std::string locale = GetGlobalStringParameterInternal("Locale", "");
+      Toolbox::InitializeGlobalLocale(configuration_["Locale"].asCString());
+    }
+    else
+    {
+      Toolbox::InitializeGlobalLocale(NULL);
+    }
+
     if (configuration_.isMember("Pkcs11"))
     {
       ConfigurePkcs11(configuration_["Pkcs11"]);
@@ -518,6 +529,7 @@ namespace Orthanc
 #endif
 
     HttpClient::FinalizeOpenSsl();
+    Toolbox::FinalizeGlobalLocale();
   }
 
 
@@ -843,10 +855,30 @@ namespace Orthanc
   }
 
 
-  bool Configuration::IsKnownAETitle(const std::string& aet)
+  bool Configuration::IsKnownAETitle(const std::string& aet,
+                                     const std::string& ip)
   {
     RemoteModalityParameters modality;
-    return LookupDicomModalityUsingAETitle(modality, aet);
+    
+    if (!LookupDicomModalityUsingAETitle(modality, aet))
+    {
+      LOG(WARNING) << "Modality \"" << aet
+                   << "\" is not listed in the \"DicomModalities\" configuration option";
+      return false;
+    }
+    else if (!Configuration::GetGlobalBoolParameter("DicomCheckModalityHost", false) ||
+             ip == modality.GetHost())
+    {
+      return true;
+    }
+    else
+    {
+      LOG(WARNING) << "Forbidding access from AET \"" << aet
+                   << "\" given its hostname (" << ip << ") does not match "
+                   << "the \"DicomModalities\" configuration option ("
+                   << modality.GetHost() << " was expected)";
+      return false;
+    }
   }
 
 
diff --git a/OrthancServer/OrthancInitialization.h b/OrthancServer/OrthancInitialization.h
index 7218335..0fb20ae 100644
--- a/OrthancServer/OrthancInitialization.h
+++ b/OrthancServer/OrthancInitialization.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -105,7 +106,8 @@ namespace Orthanc
     static void GetGlobalListOfStringsParameter(std::list<std::string>& target,
                                                 const std::string& key);
 
-    static bool IsKnownAETitle(const std::string& aet);
+    static bool IsKnownAETitle(const std::string& aet,
+                               const std::string& ip);
 
     static bool IsSameAETitle(const std::string& aet1,
                               const std::string& aet2);
diff --git a/OrthancServer/OrthancMoveRequestHandler.cpp b/OrthancServer/OrthancMoveRequestHandler.cpp
index b48f5a1..5e28bdf 100644
--- a/OrthancServer/OrthancMoveRequestHandler.cpp
+++ b/OrthancServer/OrthancMoveRequestHandler.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/OrthancMoveRequestHandler.h b/OrthancServer/OrthancMoveRequestHandler.h
index 6d54eab..23c866b 100644
--- a/OrthancServer/OrthancMoveRequestHandler.h
+++ b/OrthancServer/OrthancMoveRequestHandler.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp b/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp
index cb7f622..6b8c023 100644
--- a/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp
+++ b/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -51,9 +52,18 @@ namespace Orthanc
     TagOperation_Remove
   };
 
+  static bool IsDatabaseKey(const DicomTag& tag)
+  {
+    return (tag == DICOM_TAG_PATIENT_ID ||
+            tag == DICOM_TAG_STUDY_INSTANCE_UID ||
+            tag == DICOM_TAG_SERIES_INSTANCE_UID ||
+            tag == DICOM_TAG_SOP_INSTANCE_UID);
+  }
+
   static void ParseListOfTags(DicomModification& target,
                               const Json::Value& query,
-                              TagOperation operation)
+                              TagOperation operation,
+                              bool force)
   {
     if (!query.isArray())
     {
@@ -66,6 +76,14 @@ namespace Orthanc
 
       DicomTag tag = FromDcmtkBridge::ParseTag(name);
 
+      if (!force && IsDatabaseKey(tag))
+      {
+        LOG(ERROR) << "Marking tag \"" << name << "\" as to be "
+                   << (operation == TagOperation_Keep ? "kept" : "removed")
+                   << " requires the \"Force\" option to be set to true";
+        throw OrthancException(ErrorCode_BadRequest);
+      }
+
       switch (operation)
       {
         case TagOperation_Keep:
@@ -86,7 +104,8 @@ namespace Orthanc
 
 
   static void ParseReplacements(DicomModification& target,
-                                const Json::Value& replacements)
+                                const Json::Value& replacements,
+                                bool force)
   {
     if (!replacements.isObject())
     {
@@ -100,7 +119,15 @@ namespace Orthanc
       const Json::Value& value = replacements[name];
 
       DicomTag tag = FromDcmtkBridge::ParseTag(name);
-      target.Replace(tag, value);
+
+      if (!force && IsDatabaseKey(tag))
+      {
+        LOG(ERROR) << "Marking tag \"" << name << "\" as to be replaced "
+                   << "requires the \"Force\" option to be set to true";
+        throw OrthancException(ErrorCode_BadRequest);
+      }
+
+      target.Replace(tag, value, false);
 
       VLOG(1) << "Replace: " << name << " " << tag 
               << " == " << value.toStyledString() << std::endl;
@@ -115,25 +142,46 @@ namespace Orthanc
   }
 
 
+  static bool GetBooleanValue(const std::string& member,
+                              const Json::Value& json,
+                              bool defaultValue)
+  {
+    if (!json.isMember(member))
+    {
+      return defaultValue;
+    }
+    else if (json[member].type() == Json::booleanValue)
+    {
+      return json[member].asBool();
+    }
+    else
+    {
+      LOG(ERROR) << "Member \"" << member << "\" should be a Boolean value";
+      throw OrthancException(ErrorCode_BadFileFormat);
+    }
+  }
+
 
   bool OrthancRestApi::ParseModifyRequest(DicomModification& target,
                                           const Json::Value& request)
   {
     if (request.isObject())
     {
-      if (request.isMember("RemovePrivateTags"))
+      bool force = GetBooleanValue("Force", request, false);
+      
+      if (GetBooleanValue("RemovePrivateTags", request, false))
       {
         target.SetRemovePrivateTags(true);
       }
 
       if (request.isMember("Remove"))
       {
-        ParseListOfTags(target, request["Remove"], TagOperation_Remove);
+        ParseListOfTags(target, request["Remove"], TagOperation_Remove, force);
       }
 
       if (request.isMember("Replace"))
       {
-        ParseReplacements(target, request["Replace"]);
+        ParseReplacements(target, request["Replace"], force);
       }
 
       // The "Keep" operation only makes sense for the tags
@@ -143,7 +191,7 @@ namespace Orthanc
       // you're doing!
       if (request.isMember("Keep"))
       {
-        ParseListOfTags(target, request["Keep"], TagOperation_Keep);
+        ParseListOfTags(target, request["Keep"], TagOperation_Keep, force);
       }
 
       return true;
@@ -177,46 +225,62 @@ namespace Orthanc
   {
     // curl http://localhost:8042/instances/6e67da51-d119d6ae-c5667437-87b9a8a5-0f07c49f/anonymize -X POST -d '{"Replace":{"PatientName":"hello","0010-0020":"world"},"Keep":["StudyDescription", "SeriesDescription"],"KeepPrivateTags": null,"Remove":["Modality"]}' > Anonymized.dcm
 
-    target.SetupAnonymization();
-    std::string patientName = target.GetReplacementAsString(DICOM_TAG_PATIENT_NAME);
-
     Json::Value request;
-    if (call.ParseJsonRequest(request) && request.isObject())
+    if (!call.ParseJsonRequest(request) ||
+        !request.isObject())
     {
-      if (request.isMember("KeepPrivateTags"))
-      {
-        target.SetRemovePrivateTags(false);
-      }
+      return false;
+    }
 
-      if (request.isMember("Remove"))
+    bool force = GetBooleanValue("Force", request, false);
+      
+    // As of Orthanc 1.3.0, the default anonymization is done
+    // according to PS 3.15-2017c Table E.1-1 (basic profile)
+    DicomVersion version = DicomVersion_2017c;
+    if (request.isMember("DicomVersion"))
+    {
+      if (request["DicomVersion"].type() != Json::stringValue)
       {
-        ParseListOfTags(target, request["Remove"], TagOperation_Remove);
+        throw OrthancException(ErrorCode_BadFileFormat);
       }
-
-      if (request.isMember("Replace"))
+      else
       {
-        ParseReplacements(target, request["Replace"]);
+        version = StringToDicomVersion(request["DicomVersion"].asString());
       }
+    }
+        
+    target.SetupAnonymization(version);
+    std::string patientName = target.GetReplacementAsString(DICOM_TAG_PATIENT_NAME);
 
-      if (request.isMember("Keep"))
-      {
-        ParseListOfTags(target, request["Keep"], TagOperation_Keep);
-      }
+    if (GetBooleanValue("KeepPrivateTags", request, false))
+    {
+      target.SetRemovePrivateTags(false);
+    }
 
-      if (target.IsReplaced(DICOM_TAG_PATIENT_NAME) &&
-          target.GetReplacement(DICOM_TAG_PATIENT_NAME) == patientName)
-      {
-        // Overwrite the random Patient's Name by one that is more
-        // user-friendly (provided none was specified by the user)
-        target.Replace(DICOM_TAG_PATIENT_NAME, GeneratePatientName(OrthancRestApi::GetContext(call)), true);
-      }
+    if (request.isMember("Remove"))
+    {
+      ParseListOfTags(target, request["Remove"], TagOperation_Remove, force);
+    }
 
-      return true;
+    if (request.isMember("Replace"))
+    {
+      ParseReplacements(target, request["Replace"], force);
     }
-    else
+
+    if (request.isMember("Keep"))
     {
-      return false;
+      ParseListOfTags(target, request["Keep"], TagOperation_Keep, force);
     }
+
+    if (target.IsReplaced(DICOM_TAG_PATIENT_NAME) &&
+        target.GetReplacement(DICOM_TAG_PATIENT_NAME) == patientName)
+    {
+      // Overwrite the random Patient's Name by one that is more
+      // user-friendly (provided none was specified by the user)
+      target.Replace(DICOM_TAG_PATIENT_NAME, GeneratePatientName(OrthancRestApi::GetContext(call)), true);
+    }
+
+    return true;
   }
 
 
@@ -861,9 +925,9 @@ namespace Orthanc
     Register("/patients/{id}/modify", ModifyResource<ChangeType_ModifiedPatient, ResourceType_Patient>);
 
     Register("/instances/{id}/anonymize", AnonymizeInstance);
-    Register("/series/{id}/anonymize", AnonymizeResource<ChangeType_ModifiedSeries, ResourceType_Series>);
-    Register("/studies/{id}/anonymize", AnonymizeResource<ChangeType_ModifiedStudy, ResourceType_Study>);
-    Register("/patients/{id}/anonymize", AnonymizeResource<ChangeType_ModifiedPatient, ResourceType_Patient>);
+    Register("/series/{id}/anonymize", AnonymizeResource<ChangeType_AnonymizedSeries, ResourceType_Series>);
+    Register("/studies/{id}/anonymize", AnonymizeResource<ChangeType_AnonymizedStudy, ResourceType_Study>);
+    Register("/patients/{id}/anonymize", AnonymizeResource<ChangeType_AnonymizedPatient, ResourceType_Patient>);
 
     Register("/tools/create-dicom", CreateDicom);
   }
diff --git a/OrthancServer/OrthancRestApi/OrthancRestApi.cpp b/OrthancServer/OrthancRestApi/OrthancRestApi.cpp
index 0b4164a..c050a18 100644
--- a/OrthancServer/OrthancRestApi/OrthancRestApi.cpp
+++ b/OrthancServer/OrthancRestApi/OrthancRestApi.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/OrthancRestApi/OrthancRestApi.h b/OrthancServer/OrthancRestApi/OrthancRestApi.h
index 3acd3f9..8089e76 100644
--- a/OrthancServer/OrthancRestApi/OrthancRestApi.h
+++ b/OrthancServer/OrthancRestApi/OrthancRestApi.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/OrthancRestApi/OrthancRestArchive.cpp b/OrthancServer/OrthancRestApi/OrthancRestArchive.cpp
index 34ac44f..2b01f94 100644
--- a/OrthancServer/OrthancRestApi/OrthancRestArchive.cpp
+++ b/OrthancServer/OrthancRestApi/OrthancRestArchive.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/OrthancRestApi/OrthancRestChanges.cpp b/OrthancServer/OrthancRestApi/OrthancRestChanges.cpp
index 64db6ce..3d1948f 100644
--- a/OrthancServer/OrthancRestApi/OrthancRestChanges.cpp
+++ b/OrthancServer/OrthancRestApi/OrthancRestChanges.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/OrthancRestApi/OrthancRestModalities.cpp b/OrthancServer/OrthancRestApi/OrthancRestModalities.cpp
index 3f0ece0..ad14b9b 100644
--- a/OrthancServer/OrthancRestApi/OrthancRestModalities.cpp
+++ b/OrthancServer/OrthancRestApi/OrthancRestModalities.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/OrthancRestApi/OrthancRestResources.cpp b/OrthancServer/OrthancRestApi/OrthancRestResources.cpp
index 33c217f..2a49bf7 100644
--- a/OrthancServer/OrthancRestApi/OrthancRestResources.cpp
+++ b/OrthancServer/OrthancRestApi/OrthancRestResources.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -266,14 +267,17 @@ namespace Orthanc
     private:
       std::auto_ptr<ImageAccessor>&  image_;
       ImageExtractionMode            mode_;
+      bool                           invert_;
       std::string                    format_;
       std::string                    answer_;
 
     public:
       ImageToEncode(std::auto_ptr<ImageAccessor>& image,
-                    ImageExtractionMode mode) : 
+                    ImageExtractionMode mode,
+                    bool invert) :
         image_(image),
-        mode_(mode)
+        mode_(mode),
+        invert_(invert)
       {
       }
 
@@ -285,13 +289,13 @@ namespace Orthanc
       void EncodeUsingPng()
       {
         format_ = "image/png";
-        DicomImageDecoder::ExtractPngImage(answer_, image_, mode_);
+        DicomImageDecoder::ExtractPngImage(answer_, image_, mode_, invert_);
       }
 
       void EncodeUsingJpeg(uint8_t quality)
       {
         format_ = "image/jpeg";
-        DicomImageDecoder::ExtractJpegImage(answer_, image_, mode_, quality);
+        DicomImageDecoder::ExtractJpegImage(answer_, image_, mode_, invert_, quality);
       }
     };
 
@@ -372,6 +376,7 @@ namespace Orthanc
       return;
     }
 
+    bool invert = false;
     std::auto_ptr<ImageAccessor> decoded;
 
     try
@@ -392,6 +397,21 @@ namespace Orthanc
          * to decode the image. This allows us to take advantage of
          * the cache below.
          **/
+
+        if (mode == ImageExtractionMode_Preview &&
+            decoded.get() != NULL)
+        {
+          // TODO Optimize this lookup for photometric interpretation:
+          // It should be implemented by the plugin to avoid parsing
+          // twice the DICOM file
+          ParsedDicomFile parsed(dicomContent);
+          
+          PhotometricInterpretation photometric;
+          if (parsed.LookupPhotometricInterpretation(photometric))
+          {
+            invert = (photometric == PhotometricInterpretation_Monochrome1);
+          }
+        }
       }
 #endif
 
@@ -399,8 +419,15 @@ namespace Orthanc
       {
         // Use Orthanc's built-in decoder, using the cache to speed-up
         // things on multi-frame images
-        ServerContext::DicomCacheLocker locker(OrthancRestApi::GetContext(call), publicId);
+        ServerContext::DicomCacheLocker locker(context, publicId);        
         decoded.reset(DicomImageDecoder::Decode(locker.GetDicom(), frame));
+
+        PhotometricInterpretation photometric;
+        if (mode == ImageExtractionMode_Preview &&
+            locker.GetDicom().LookupPhotometricInterpretation(photometric))
+        {
+          invert = (photometric == PhotometricInterpretation_Monochrome1);
+        }
       }
     }
     catch (OrthancException& e)
@@ -422,7 +449,7 @@ namespace Orthanc
       }
     }
 
-    ImageToEncode image(decoded, mode);
+    ImageToEncode image(decoded, mode, invert);
 
     HttpContentNegociation negociation;
     EncodePng png(image);          negociation.Register("image/png", png);
@@ -1127,7 +1154,8 @@ namespace Orthanc
         request["Level"].type() == Json::stringValue &&
         request["Query"].type() == Json::objectValue &&
         (!request.isMember("CaseSensitive") || request["CaseSensitive"].type() == Json::booleanValue) &&
-        (!request.isMember("Limit") || request["Limit"].type() == Json::intValue))
+        (!request.isMember("Limit") || request["Limit"].type() == Json::intValue) &&
+        (!request.isMember("Since") || request["Since"].type() == Json::intValue))
     {
       bool expand = false;
       if (request.isMember("Expand"))
@@ -1153,6 +1181,18 @@ namespace Orthanc
         limit = static_cast<size_t>(tmp);
       }
 
+      size_t since = 0;
+      if (request.isMember("Since"))
+      {
+        int tmp = request["Since"].asInt();
+        if (tmp < 0)
+        {
+          throw OrthancException(ErrorCode_ParameterOutOfRange);
+        }
+
+        since = static_cast<size_t>(tmp);
+      }
+
       std::string level = request["Level"].asString();
 
       LookupResource query(StringToResourceType(level.c_str()));
@@ -1171,8 +1211,9 @@ namespace Orthanc
       }
       
       std::list<std::string> resources;
-      context.Apply(resources, query, limit);
-      AnswerListOfResources(call.GetOutput(), context.GetIndex(), resources, query.GetLevel(), expand);
+      context.Apply(resources, query, since, limit);
+      AnswerListOfResources(call.GetOutput(), context.GetIndex(),
+                            resources, query.GetLevel(), expand);
     }
     else
     {
diff --git a/OrthancServer/OrthancRestApi/OrthancRestSystem.cpp b/OrthancServer/OrthancRestApi/OrthancRestSystem.cpp
index f86cd73..69de4d1 100644
--- a/OrthancServer/OrthancRestApi/OrthancRestSystem.cpp
+++ b/OrthancServer/OrthancRestApi/OrthancRestSystem.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/ParsedDicomFile.cpp b/OrthancServer/ParsedDicomFile.cpp
index bc5ecf0..158d12d 100644
--- a/OrthancServer/ParsedDicomFile.cpp
+++ b/OrthancServer/ParsedDicomFile.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -507,6 +508,28 @@ namespace Orthanc
   }
 
 
+  void ParsedDicomFile::Clear(const DicomTag& tag,
+                              bool onlyIfExists)
+  {
+    InvalidateCache();
+
+    DcmItem* dicom = pimpl_->file_->getDataset();
+    DcmTagKey key(tag.GetGroup(), tag.GetElement());
+
+    if (onlyIfExists &&
+        !dicom->tagExists(key))
+    {
+      // The tag is non-existing, do not clear it
+    }
+    else
+    {
+      if (!dicom->insertEmptyElement(key, OFTrue /* replace old value */).good())
+      {
+        throw OrthancException(ErrorCode_InternalError);
+      }
+    }
+  }
+
 
   void ParsedDicomFile::RemovePrivateTagsInternal(const std::set<DicomTag>* toKeep)
   {
@@ -1408,4 +1431,25 @@ namespace Orthanc
   {
     return FromDcmtkBridge::LookupTransferSyntax(result, *pimpl_->file_);
   }
+
+
+  bool ParsedDicomFile::LookupPhotometricInterpretation(PhotometricInterpretation& result) const
+  {
+    DcmTagKey k(DICOM_TAG_PHOTOMETRIC_INTERPRETATION.GetGroup(),
+                DICOM_TAG_PHOTOMETRIC_INTERPRETATION.GetElement());
+
+    DcmDataset& dataset = *pimpl_->file_->getDataset();
+
+    const char *c = NULL;
+    if (dataset.findAndGetString(k, c).good() &&
+        c != NULL)
+    {
+      result = StringToPhotometricInterpretation(c);
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
 }
diff --git a/OrthancServer/ParsedDicomFile.h b/OrthancServer/ParsedDicomFile.h
index b5f7930..2c8bdf8 100644
--- a/OrthancServer/ParsedDicomFile.h
+++ b/OrthancServer/ParsedDicomFile.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -95,6 +96,10 @@ namespace Orthanc
 
     void Remove(const DicomTag& tag);
 
+    // Replace the DICOM tag as a NULL/empty value (e.g. for anonymization)
+    void Clear(const DicomTag& tag,
+               bool onlyIfExists);
+
     void Replace(const DicomTag& tag,
                  const std::string& utf8Value,
                  bool decodeDataUriScheme,
@@ -182,5 +187,7 @@ namespace Orthanc
     void ExtractDicomAsJson(Json::Value& target) const;
 
     bool LookupTransferSyntax(std::string& result);
+
+    bool LookupPhotometricInterpretation(PhotometricInterpretation& result) const;
   };
 }
diff --git a/OrthancServer/PrecompiledHeadersServer.cpp b/OrthancServer/PrecompiledHeadersServer.cpp
index 0835253..4712cfc 100644
--- a/OrthancServer/PrecompiledHeadersServer.cpp
+++ b/OrthancServer/PrecompiledHeadersServer.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/PrecompiledHeadersServer.h b/OrthancServer/PrecompiledHeadersServer.h
index 49e8719..84f7329 100644
--- a/OrthancServer/PrecompiledHeadersServer.h
+++ b/OrthancServer/PrecompiledHeadersServer.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/QueryRetrieveHandler.cpp b/OrthancServer/QueryRetrieveHandler.cpp
index 595d165..ef036b9 100644
--- a/OrthancServer/QueryRetrieveHandler.cpp
+++ b/OrthancServer/QueryRetrieveHandler.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/QueryRetrieveHandler.h b/OrthancServer/QueryRetrieveHandler.h
index 0e86005..bfc8ea8 100644
--- a/OrthancServer/QueryRetrieveHandler.h
+++ b/OrthancServer/QueryRetrieveHandler.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Scheduler/CallSystemCommand.cpp b/OrthancServer/Scheduler/CallSystemCommand.cpp
index 751dc9b..9e56a5d 100644
--- a/OrthancServer/Scheduler/CallSystemCommand.cpp
+++ b/OrthancServer/Scheduler/CallSystemCommand.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Scheduler/CallSystemCommand.h b/OrthancServer/Scheduler/CallSystemCommand.h
index f5502b8..bdb1391 100644
--- a/OrthancServer/Scheduler/CallSystemCommand.h
+++ b/OrthancServer/Scheduler/CallSystemCommand.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Scheduler/DeleteInstanceCommand.cpp b/OrthancServer/Scheduler/DeleteInstanceCommand.cpp
index 7e88a52..bff04a3 100644
--- a/OrthancServer/Scheduler/DeleteInstanceCommand.cpp
+++ b/OrthancServer/Scheduler/DeleteInstanceCommand.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Scheduler/DeleteInstanceCommand.h b/OrthancServer/Scheduler/DeleteInstanceCommand.h
index 39362f7..35665d1 100644
--- a/OrthancServer/Scheduler/DeleteInstanceCommand.h
+++ b/OrthancServer/Scheduler/DeleteInstanceCommand.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Scheduler/IServerCommand.h b/OrthancServer/Scheduler/IServerCommand.h
index df33cd6..582b3f3 100644
--- a/OrthancServer/Scheduler/IServerCommand.h
+++ b/OrthancServer/Scheduler/IServerCommand.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Scheduler/ModifyInstanceCommand.cpp b/OrthancServer/Scheduler/ModifyInstanceCommand.cpp
index 5592680..536d3e3 100644
--- a/OrthancServer/Scheduler/ModifyInstanceCommand.cpp
+++ b/OrthancServer/Scheduler/ModifyInstanceCommand.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Scheduler/ModifyInstanceCommand.h b/OrthancServer/Scheduler/ModifyInstanceCommand.h
index a94f014..1553667 100644
--- a/OrthancServer/Scheduler/ModifyInstanceCommand.h
+++ b/OrthancServer/Scheduler/ModifyInstanceCommand.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Scheduler/ServerCommandInstance.cpp b/OrthancServer/Scheduler/ServerCommandInstance.cpp
index 17f2042..03af0a1 100644
--- a/OrthancServer/Scheduler/ServerCommandInstance.cpp
+++ b/OrthancServer/Scheduler/ServerCommandInstance.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Scheduler/ServerCommandInstance.h b/OrthancServer/Scheduler/ServerCommandInstance.h
index ed20938..0a43d81 100644
--- a/OrthancServer/Scheduler/ServerCommandInstance.h
+++ b/OrthancServer/Scheduler/ServerCommandInstance.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Scheduler/ServerJob.cpp b/OrthancServer/Scheduler/ServerJob.cpp
index a43ee1e..5fa54a5 100644
--- a/OrthancServer/Scheduler/ServerJob.cpp
+++ b/OrthancServer/Scheduler/ServerJob.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Scheduler/ServerJob.h b/OrthancServer/Scheduler/ServerJob.h
index a798923..34f060b 100644
--- a/OrthancServer/Scheduler/ServerJob.h
+++ b/OrthancServer/Scheduler/ServerJob.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Scheduler/ServerScheduler.cpp b/OrthancServer/Scheduler/ServerScheduler.cpp
index dfe4b2c..9e8d275 100644
--- a/OrthancServer/Scheduler/ServerScheduler.cpp
+++ b/OrthancServer/Scheduler/ServerScheduler.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Scheduler/ServerScheduler.h b/OrthancServer/Scheduler/ServerScheduler.h
index 0da65ff..ee2de38 100644
--- a/OrthancServer/Scheduler/ServerScheduler.h
+++ b/OrthancServer/Scheduler/ServerScheduler.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Scheduler/StorePeerCommand.cpp b/OrthancServer/Scheduler/StorePeerCommand.cpp
index 8acbbb3..7e4b747 100644
--- a/OrthancServer/Scheduler/StorePeerCommand.cpp
+++ b/OrthancServer/Scheduler/StorePeerCommand.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Scheduler/StorePeerCommand.h b/OrthancServer/Scheduler/StorePeerCommand.h
index 7f2c80b..82c6015 100644
--- a/OrthancServer/Scheduler/StorePeerCommand.h
+++ b/OrthancServer/Scheduler/StorePeerCommand.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Scheduler/StoreScuCommand.cpp b/OrthancServer/Scheduler/StoreScuCommand.cpp
index c698b2d..6745ba7 100644
--- a/OrthancServer/Scheduler/StoreScuCommand.cpp
+++ b/OrthancServer/Scheduler/StoreScuCommand.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Scheduler/StoreScuCommand.h b/OrthancServer/Scheduler/StoreScuCommand.h
index b1ead73..9d172d8 100644
--- a/OrthancServer/Scheduler/StoreScuCommand.h
+++ b/OrthancServer/Scheduler/StoreScuCommand.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Search/HierarchicalMatcher.cpp b/OrthancServer/Search/HierarchicalMatcher.cpp
index 9e71a03..caf5131 100644
--- a/OrthancServer/Search/HierarchicalMatcher.cpp
+++ b/OrthancServer/Search/HierarchicalMatcher.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -37,16 +38,16 @@
 #include "../../Core/OrthancException.h"
 #include "../FromDcmtkBridge.h"
 #include "../ToDcmtkBridge.h"
+#include "../OrthancInitialization.h"
 
 #include <dcmtk/dcmdata/dcfilefo.h>
 
 namespace Orthanc
 {
-  HierarchicalMatcher::HierarchicalMatcher(ParsedDicomFile& query,
-                                           bool caseSensitivePN)
+  HierarchicalMatcher::HierarchicalMatcher(ParsedDicomFile& query)
   {
     Setup(*query.GetDcmtkObject().getDataset(), 
-          caseSensitivePN,
+          Configuration::GetGlobalBoolParameter("CaseSensitivePN", false),
           query.GetEncoding());
   }
 
@@ -332,7 +333,7 @@ namespace Orthanc
                                                       dicom.GetEncoding()));
 
     std::auto_ptr<ParsedDicomFile> result(new ParsedDicomFile(*dataset));
-    result->SetEncoding(Encoding_Utf8);
+    result->SetEncoding(dicom.GetEncoding());
 
     return result.release();
   }
diff --git a/OrthancServer/Search/HierarchicalMatcher.h b/OrthancServer/Search/HierarchicalMatcher.h
index e646c31..d01859c 100644
--- a/OrthancServer/Search/HierarchicalMatcher.h
+++ b/OrthancServer/Search/HierarchicalMatcher.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -67,8 +68,7 @@ namespace Orthanc
                                 Encoding encoding) const;
 
   public:
-    HierarchicalMatcher(ParsedDicomFile& query,
-                        bool caseSensitivePN);
+    HierarchicalMatcher(ParsedDicomFile& query);
 
     ~HierarchicalMatcher();
 
diff --git a/OrthancServer/Search/IFindConstraint.cpp b/OrthancServer/Search/IFindConstraint.cpp
index ffec897..6f522ed 100644
--- a/OrthancServer/Search/IFindConstraint.cpp
+++ b/OrthancServer/Search/IFindConstraint.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Search/IFindConstraint.h b/OrthancServer/Search/IFindConstraint.h
index d182685..bad9b7a 100644
--- a/OrthancServer/Search/IFindConstraint.h
+++ b/OrthancServer/Search/IFindConstraint.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Search/ListConstraint.cpp b/OrthancServer/Search/ListConstraint.cpp
index 46f9b9a..fbdd9c8 100644
--- a/OrthancServer/Search/ListConstraint.cpp
+++ b/OrthancServer/Search/ListConstraint.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -44,9 +45,7 @@ namespace Orthanc
     }
     else
     {
-      std::string s = value;
-      Toolbox::ToUpperCase(s);
-      allowedValues_.insert(s);      
+      allowedValues_.insert(Toolbox::ToUpperCaseWithAccents(value));
     }
   }
 
@@ -66,14 +65,18 @@ namespace Orthanc
 
   bool ListConstraint::Match(const std::string& value) const
   {
-    std::string v = value;
-
-    if (!isCaseSensitive_)
+    std::string s;
+    
+    if (isCaseSensitive_)
+    {
+      s = value;
+    }
+    else
     {
-      Toolbox::ToUpperCase(v);
+      s = Toolbox::ToUpperCaseWithAccents(value);
     }
 
-    return allowedValues_.find(v) != allowedValues_.end();
+    return allowedValues_.find(s) != allowedValues_.end();
   }
 
 
diff --git a/OrthancServer/Search/ListConstraint.h b/OrthancServer/Search/ListConstraint.h
index cbdc556..5e37ddb 100644
--- a/OrthancServer/Search/ListConstraint.h
+++ b/OrthancServer/Search/ListConstraint.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Search/LookupIdentifierQuery.cpp b/OrthancServer/Search/LookupIdentifierQuery.cpp
index 7b4c3f5..abe40c3 100644
--- a/OrthancServer/Search/LookupIdentifierQuery.cpp
+++ b/OrthancServer/Search/LookupIdentifierQuery.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Search/LookupIdentifierQuery.h b/OrthancServer/Search/LookupIdentifierQuery.h
index 0ad2708..ed8b51f 100644
--- a/OrthancServer/Search/LookupIdentifierQuery.h
+++ b/OrthancServer/Search/LookupIdentifierQuery.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Search/LookupResource.cpp b/OrthancServer/Search/LookupResource.cpp
index b073d92..35d7b67 100644
--- a/OrthancServer/Search/LookupResource.cpp
+++ b/OrthancServer/Search/LookupResource.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Search/LookupResource.h b/OrthancServer/Search/LookupResource.h
index 71390b8..20d27fe 100644
--- a/OrthancServer/Search/LookupResource.h
+++ b/OrthancServer/Search/LookupResource.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Search/RangeConstraint.cpp b/OrthancServer/Search/RangeConstraint.cpp
index b90021d..d05bef2 100644
--- a/OrthancServer/Search/RangeConstraint.cpp
+++ b/OrthancServer/Search/RangeConstraint.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -40,14 +41,17 @@ namespace Orthanc
   RangeConstraint::RangeConstraint(const std::string& lower,
                                    const std::string& upper,
                                    bool isCaseSensitive) : 
-    lower_(lower),
-    upper_(upper),
     isCaseSensitive_(isCaseSensitive)
   {
-    if (!isCaseSensitive_)
+    if (isCaseSensitive_)
     {
-      Toolbox::ToUpperCase(lower_);
-      Toolbox::ToUpperCase(upper_);
+      lower_ = lower;
+      upper_ = upper;
+    }
+    else
+    {
+      lower_ = Toolbox::ToUpperCaseWithAccents(lower);
+      upper_ = Toolbox::ToUpperCaseWithAccents(upper);
     }
   }
 
@@ -69,11 +73,15 @@ namespace Orthanc
 
   bool RangeConstraint::Match(const std::string& value) const
   {
-    std::string v = value;
+    std::string v;
 
-    if (!isCaseSensitive_)
+    if (isCaseSensitive_)
+    {
+      v = value;
+    }
+    else
     {
-      Toolbox::ToUpperCase(v);
+      v = Toolbox::ToUpperCaseWithAccents(value);
     }
 
     if (lower_.size() == 0 && 
diff --git a/OrthancServer/Search/RangeConstraint.h b/OrthancServer/Search/RangeConstraint.h
index 02e0240..6266b94 100644
--- a/OrthancServer/Search/RangeConstraint.h
+++ b/OrthancServer/Search/RangeConstraint.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Search/SetOfResources.cpp b/OrthancServer/Search/SetOfResources.cpp
index 995bb20..88e816c 100644
--- a/OrthancServer/Search/SetOfResources.cpp
+++ b/OrthancServer/Search/SetOfResources.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Search/SetOfResources.h b/OrthancServer/Search/SetOfResources.h
index f4a833f..7069105 100644
--- a/OrthancServer/Search/SetOfResources.h
+++ b/OrthancServer/Search/SetOfResources.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Search/ValueConstraint.cpp b/OrthancServer/Search/ValueConstraint.cpp
index ecb3d62..3981f3c 100644
--- a/OrthancServer/Search/ValueConstraint.cpp
+++ b/OrthancServer/Search/ValueConstraint.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -41,12 +42,15 @@ namespace Orthanc
 {
   ValueConstraint::ValueConstraint(const std::string& value,
                                    bool isCaseSensitive) : 
-    value_(value),
     isCaseSensitive_(isCaseSensitive)
   {
-    if (!isCaseSensitive)
+    if (isCaseSensitive)
     {
-      Toolbox::ToUpperCase(value_);
+      value_ = value;
+    }
+    else
+    {
+      value_ = Toolbox::ToUpperCaseWithAccents(value);
     }
   }
 
@@ -65,9 +69,7 @@ namespace Orthanc
     }
     else
     {
-      std::string v;
-      Toolbox::ToUpperCase(v, value);
-      return value_ == v;
+      return value_ == Toolbox::ToUpperCaseWithAccents(value);
     }
   }
 }
diff --git a/OrthancServer/Search/ValueConstraint.h b/OrthancServer/Search/ValueConstraint.h
index 6cee8e1..528b4f0 100644
--- a/OrthancServer/Search/ValueConstraint.h
+++ b/OrthancServer/Search/ValueConstraint.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/Search/WildcardConstraint.cpp b/OrthancServer/Search/WildcardConstraint.cpp
index f3a4654..050658e 100644
--- a/OrthancServer/Search/WildcardConstraint.cpp
+++ b/OrthancServer/Search/WildcardConstraint.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -41,6 +42,24 @@ namespace Orthanc
   {
     boost::regex  pattern_;
     std::string   wildcard_;
+    bool          isCaseSensitive_;
+
+    PImpl(const std::string& wildcard,
+          bool isCaseSensitive)
+    {
+      isCaseSensitive_ = isCaseSensitive;
+    
+      if (isCaseSensitive)
+      {
+        wildcard_ = wildcard;
+      }
+      else
+      {
+        wildcard_ = Toolbox::ToUpperCaseWithAccents(wildcard);
+      }
+
+      pattern_ = boost::regex(Toolbox::WildcardToRegularExpression(wildcard_));
+    }
   };
 
 
@@ -52,27 +71,22 @@ namespace Orthanc
 
   WildcardConstraint::WildcardConstraint(const std::string& wildcard,
                                          bool isCaseSensitive) :
-    pimpl_(new PImpl)
+    pimpl_(new PImpl(wildcard, isCaseSensitive))
   {
-    pimpl_->wildcard_ = wildcard;
-
-    std::string re = Toolbox::WildcardToRegularExpression(wildcard);
+  }
 
-    if (isCaseSensitive)
+  bool WildcardConstraint::Match(const std::string& value) const
+  {
+    if (pimpl_->isCaseSensitive_)
     {
-      pimpl_->pattern_ = boost::regex(re);
+      return boost::regex_match(value, pimpl_->pattern_);
     }
     else
     {
-      pimpl_->pattern_ = boost::regex(re, boost::regex::icase /* case insensitive search */);
+      return boost::regex_match(Toolbox::ToUpperCaseWithAccents(value), pimpl_->pattern_);
     }
   }
 
-  bool WildcardConstraint::Match(const std::string& value) const
-  {
-    return boost::regex_match(value, pimpl_->pattern_);
-  }
-
   void WildcardConstraint::Setup(LookupIdentifierQuery& lookup,
                                  const DicomTag& tag) const
   {
diff --git a/OrthancServer/Search/WildcardConstraint.h b/OrthancServer/Search/WildcardConstraint.h
index b3eda69..a5b44c3 100644
--- a/OrthancServer/Search/WildcardConstraint.h
+++ b/OrthancServer/Search/WildcardConstraint.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/ServerContext.cpp b/OrthancServer/ServerContext.cpp
index 87aedc8..b63c1ed 100644
--- a/OrthancServer/ServerContext.cpp
+++ b/OrthancServer/ServerContext.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -600,9 +601,10 @@ namespace Orthanc
   }
 
 
-  bool ServerContext::Apply(std::list<std::string>& result,
+  void ServerContext::Apply(std::list<std::string>& result,
                             const ::Orthanc::LookupResource& lookup,
-                            size_t maxResults)
+                            size_t since,
+                            size_t limit)
   {
     result.clear();
 
@@ -611,6 +613,7 @@ namespace Orthanc
 
     assert(resources.size() == instances.size());
 
+    size_t skipped = 0;
     for (size_t i = 0; i < instances.size(); i++)
     {
       Json::Value dicom;
@@ -618,10 +621,14 @@ namespace Orthanc
       
       if (lookup.IsMatch(dicom))
       {
-        if (maxResults != 0 &&
-            result.size() >= maxResults)
+        if (skipped < since)
         {
-          return false;  // too many results
+          skipped++;
+        }
+        else if (limit != 0 &&
+                 result.size() >= limit)
+        {
+          return;  // too many results
         }
         else
         {
@@ -629,8 +636,6 @@ namespace Orthanc
         }
       }
     }
-
-    return true;  // finished
   }
 
 }
diff --git a/OrthancServer/ServerContext.h b/OrthancServer/ServerContext.h
index 2d97d65..72348db 100644
--- a/OrthancServer/ServerContext.h
+++ b/OrthancServer/ServerContext.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -257,9 +258,10 @@ namespace Orthanc
 
     void Stop();
 
-    bool Apply(std::list<std::string>& result,
+    void Apply(std::list<std::string>& result,
                const ::Orthanc::LookupResource& lookup,
-               size_t maxResults);
+               size_t since,
+               size_t limit);
 
 
     /**
diff --git a/OrthancServer/ServerEnumerations.cpp b/OrthancServer/ServerEnumerations.cpp
index a69ef0c..b8e9746 100644
--- a/OrthancServer/ServerEnumerations.cpp
+++ b/OrthancServer/ServerEnumerations.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -324,27 +325,21 @@ namespace Orthanc
       case ModalityManufacturer_Generic:
         return "Generic";
 
+      case ModalityManufacturer_GenericNoWildcardInDates:
+        return "GenericNoWildcardInDates";
+
+      case ModalityManufacturer_GenericNoUniversalWildcard:
+        return "GenericNoUniversalWildcard";
+
       case ModalityManufacturer_StoreScp:
         return "StoreScp";
       
       case ModalityManufacturer_ClearCanvas:
         return "ClearCanvas";
       
-      case ModalityManufacturer_MedInria:
-        return "MedInria";
-
       case ModalityManufacturer_Dcm4Chee:
         return "Dcm4Chee";
       
-      case ModalityManufacturer_SyngoVia:
-        return "SyngoVia";
-      
-      case ModalityManufacturer_AgfaImpax:
-        return "AgfaImpax";
-      
-      case ModalityManufacturer_EFilm2:
-        return "EFilm2";
-      
       case ModalityManufacturer_Vitrea:
         return "Vitrea";
       
@@ -387,10 +382,21 @@ namespace Orthanc
 
   ModalityManufacturer StringToModalityManufacturer(const std::string& manufacturer)
   {
+    ModalityManufacturer result;
+    bool obsolete = false;
+    
     if (manufacturer == "Generic")
     {
       return ModalityManufacturer_Generic;
     }
+    else if (manufacturer == "GenericNoWildcardInDates")
+    {
+      return ModalityManufacturer_GenericNoWildcardInDates;
+    }
+    else if (manufacturer == "GenericNoUniversalWildcard")
+    {
+      return ModalityManufacturer_GenericNoUniversalWildcard;
+    }
     else if (manufacturer == "ClearCanvas")
     {
       return ModalityManufacturer_ClearCanvas;
@@ -399,34 +405,41 @@ namespace Orthanc
     {
       return ModalityManufacturer_StoreScp;
     }
-    else if (manufacturer == "MedInria")
-    {
-      return ModalityManufacturer_MedInria;
-    }
     else if (manufacturer == "Dcm4Chee")
     {
       return ModalityManufacturer_Dcm4Chee;
     }
-    else if (manufacturer == "SyngoVia")
-    {
-      return ModalityManufacturer_SyngoVia;
-    }
-    else if (manufacturer == "AgfaImpax")
-    {
-      return ModalityManufacturer_AgfaImpax;
-    }
     else if (manufacturer == "Vitrea")
     {
       return ModalityManufacturer_Vitrea;
     }
-    else if (manufacturer == "EFilm2")
+    else if (manufacturer == "AgfaImpax" ||
+             manufacturer == "SyngoVia")
     {
-      return ModalityManufacturer_EFilm2;
+      result = ModalityManufacturer_GenericNoWildcardInDates;
+      obsolete = true;
+    }
+    else if (manufacturer == "EFilm2" ||
+             manufacturer == "MedInria")
+    {
+      result = ModalityManufacturer_Generic;
+      obsolete = true;
     }
     else
     {
       throw OrthancException(ErrorCode_ParameterOutOfRange);
     }
+
+    if (obsolete)
+    {
+      LOG(WARNING) << "The \"" << manufacturer << "\" manufacturer is obsolete since "
+                   << "Orthanc 1.3.0. To guarantee compatibility with future Orthanc "
+                   << "releases, you should replace it by \""
+                   << EnumerationToString(result)
+                   << "\" in your configuration file.";
+    }
+
+    return result;
   }
 
 
@@ -461,6 +474,41 @@ namespace Orthanc
   }
 
 
+  const char* EnumerationToString(DicomVersion version)
+  {
+    switch (version)
+    {
+      case DicomVersion_2008:
+        return "2008";
+        break;
+
+      case DicomVersion_2017c:
+        return "2017c";
+        break;
+
+      default: 
+        throw OrthancException(ErrorCode_ParameterOutOfRange);
+    }
+  }
+
+
+  DicomVersion StringToDicomVersion(const std::string& version)
+  {
+    if (version == "2008")
+    {
+      return DicomVersion_2008;
+    }
+    else if (version == "2017c")
+    {
+      return DicomVersion_2017c;
+    }
+    else
+    {
+      throw OrthancException(ErrorCode_ParameterOutOfRange);
+    }
+  }
+
+  
   bool IsUserMetadata(MetadataType metadata)
   {
     return (metadata >= MetadataType_StartUser &&
diff --git a/OrthancServer/ServerEnumerations.h b/OrthancServer/ServerEnumerations.h
index be3f69a..1c6f074 100644
--- a/OrthancServer/ServerEnumerations.h
+++ b/OrthancServer/ServerEnumerations.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -58,13 +59,11 @@ namespace Orthanc
   enum ModalityManufacturer
   {
     ModalityManufacturer_Generic,
+    ModalityManufacturer_GenericNoWildcardInDates,
+    ModalityManufacturer_GenericNoUniversalWildcard,
     ModalityManufacturer_StoreScp,
     ModalityManufacturer_ClearCanvas,
-    ModalityManufacturer_MedInria,
     ModalityManufacturer_Dcm4Chee,
-    ModalityManufacturer_SyngoVia,
-    ModalityManufacturer_AgfaImpax,
-    ModalityManufacturer_EFilm2,
     ModalityManufacturer_Vitrea
   };
 
@@ -134,6 +133,12 @@ namespace Orthanc
     IdentifierConstraintType_Wildcard        /* Case sensitive, "*" or "?" are the only allowed wildcards */
   };
 
+  enum DicomVersion
+  {
+    DicomVersion_2008,
+    DicomVersion_2017c
+  };
+
 
   /**
    * WARNING: Do not change the explicit values in the enumerations
@@ -145,7 +150,8 @@ namespace Orthanc
   {
     GlobalProperty_DatabaseSchemaVersion = 1,   // Unused in the Orthanc core as of Orthanc 0.9.5
     GlobalProperty_FlushSleep = 2,
-    GlobalProperty_AnonymizationSequence = 3
+    GlobalProperty_AnonymizationSequence = 3,
+    GlobalProperty_DatabasePatchLevel = 4       // Reserved for internal use of the database plugins
   };
 
   enum MetadataType
@@ -228,7 +234,11 @@ namespace Orthanc
 
   const char* EnumerationToString(TransferSyntax syntax);
 
+  const char* EnumerationToString(DicomVersion version);
+
   ModalityManufacturer StringToModalityManufacturer(const std::string& manufacturer);
 
+  DicomVersion StringToDicomVersion(const std::string& version);
+
   bool IsUserMetadata(MetadataType type);
 }
diff --git a/OrthancServer/ServerIndex.cpp b/OrthancServer/ServerIndex.cpp
index 29dcfe5..a5ad4e5 100644
--- a/OrthancServer/ServerIndex.cpp
+++ b/OrthancServer/ServerIndex.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/ServerIndex.h b/OrthancServer/ServerIndex.h
index dc2e84b..89db538 100644
--- a/OrthancServer/ServerIndex.h
+++ b/OrthancServer/ServerIndex.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/ServerIndexChange.h b/OrthancServer/ServerIndexChange.h
index 836c5b3..e986f7e 100644
--- a/OrthancServer/ServerIndexChange.h
+++ b/OrthancServer/ServerIndexChange.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/ServerToolbox.cpp b/OrthancServer/ServerToolbox.cpp
index e8589d8..812cbcf 100644
--- a/OrthancServer/ServerToolbox.cpp
+++ b/OrthancServer/ServerToolbox.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/ServerToolbox.h b/OrthancServer/ServerToolbox.h
index 61a02a5..dfdf20e 100644
--- a/OrthancServer/ServerToolbox.h
+++ b/OrthancServer/ServerToolbox.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/SliceOrdering.cpp b/OrthancServer/SliceOrdering.cpp
index 76c03a1..d52b815 100644
--- a/OrthancServer/SliceOrdering.cpp
+++ b/OrthancServer/SliceOrdering.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/SliceOrdering.h b/OrthancServer/SliceOrdering.h
index 13d1693..23b9b4b 100644
--- a/OrthancServer/SliceOrdering.h
+++ b/OrthancServer/SliceOrdering.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/ToDcmtkBridge.cpp b/OrthancServer/ToDcmtkBridge.cpp
index 0fec3f4..e848262 100644
--- a/OrthancServer/ToDcmtkBridge.cpp
+++ b/OrthancServer/ToDcmtkBridge.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/ToDcmtkBridge.h b/OrthancServer/ToDcmtkBridge.h
index 9a78367..551640f 100644
--- a/OrthancServer/ToDcmtkBridge.h
+++ b/OrthancServer/ToDcmtkBridge.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/OrthancServer/main.cpp b/OrthancServer/main.cpp
index 92c4cf7..67ecdc0 100644
--- a/OrthancServer/main.cpp
+++ b/OrthancServer/main.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -151,33 +152,42 @@ class OrthancApplicationEntityFilter : public IApplicationEntityFilter
 {
 private:
   ServerContext& context_;
+  bool           alwaysAllowStore_;
 
 public:
-  OrthancApplicationEntityFilter(ServerContext& context) : context_(context)
+  OrthancApplicationEntityFilter(ServerContext& context) :
+    context_(context)
   {
+    alwaysAllowStore_ = Configuration::GetGlobalBoolParameter("DicomAlwaysAllowStore", true);
   }
 
-  virtual bool IsAllowedConnection(const std::string& /*remoteIp*/,
-                                   const std::string& /*remoteAet*/,
-                                   const std::string& /*calledAet*/)
+  virtual bool IsAllowedConnection(const std::string& remoteIp,
+                                   const std::string& remoteAet,
+                                   const std::string& calledAet)
   {
-    return true;
+    LOG(INFO) << "Incoming connection from AET " << remoteAet
+              << " on IP " << remoteIp << ", calling AET " << calledAet;
+
+    return (alwaysAllowStore_ ||
+            Configuration::IsKnownAETitle(remoteAet, remoteIp));
   }
 
-  virtual bool IsAllowedRequest(const std::string& /*remoteIp*/,
+  virtual bool IsAllowedRequest(const std::string& remoteIp,
                                 const std::string& remoteAet,
-                                const std::string& /*calledAet*/,
+                                const std::string& calledAet,
                                 DicomRequestType type)
   {
-    if (type == DicomRequestType_Store)
+    LOG(INFO) << "Incoming " << Orthanc::EnumerationToString(type) << " request from AET "
+              << remoteAet << " on IP " << remoteIp << ", calling AET " << calledAet;
+    
+    if (type == DicomRequestType_Store &&
+        alwaysAllowStore_)
     {
       // Incoming store requests are always accepted, even from unknown AET
       return true;
     }
-
-    if (!Configuration::IsKnownAETitle(remoteAet))
+    else if (!Configuration::IsKnownAETitle(remoteAet, remoteIp))
     {
-      LOG(ERROR) << "Unknown remote DICOM modality AET: \"" << remoteAet << "\"";
       return false;
     }
     else
@@ -290,10 +300,11 @@ public:
                          const char* uri,
                          const char* ip,
                          const char* username,
-                         const IHttpHandler::Arguments& httpHeaders) const
+                         const IHttpHandler::Arguments& httpHeaders,
+                         const IHttpHandler::GetArguments& getArguments) const
   {
     if (plugins_ != NULL &&
-        !plugins_->IsAllowed(method, uri, ip, username, httpHeaders))
+        !plugins_->IsAllowed(method, uri, ip, username, httpHeaders, getArguments))
     {
       return false;
     }
@@ -469,6 +480,7 @@ static void PrintVersion(const char* path)
   std::cout
     << path << " " << ORTHANC_VERSION << std::endl
     << "Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics Department, University Hospital of Liege (Belgium)" << std::endl
+    << "Copyright (C) 2017 Osimis S.A. (Belgium)" << std::endl
     << "Licensing GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>, with OpenSSL exception." << std::endl
     << "This is free software: you are free to change and redistribute it." << std::endl
     << "There is NO WARRANTY, to the extent permitted by law." << std::endl
@@ -878,30 +890,27 @@ static bool ConfigureHttpHandler(ServerContext& context,
 }
 
 
-static bool UpgradeDatabase(IDatabaseWrapper& database,
-                            IStorageArea& storageArea,
-                            bool allowDatabaseUpgrade)
+static void UpgradeDatabase(IDatabaseWrapper& database,
+                            IStorageArea& storageArea)
 {
   // Upgrade the schema of the database, if needed
   unsigned int currentVersion = database.GetDatabaseVersion();
+
+  LOG(WARNING) << "Starting the upgrade of the database schema";
+  LOG(WARNING) << "Current database version: " << currentVersion;
+  LOG(WARNING) << "Database version expected by Orthanc: " << ORTHANC_DATABASE_VERSION;
+  
   if (currentVersion == ORTHANC_DATABASE_VERSION)
   {
-    return true;
+    LOG(WARNING) << "No upgrade is needed, start Orthanc without the \"--upgrade\" argument";
+    return;
   }
 
   if (currentVersion > ORTHANC_DATABASE_VERSION)
   {
     LOG(ERROR) << "The version of the database schema (" << currentVersion
                << ") is too recent for this version of Orthanc. Please upgrade Orthanc.";
-    return false;
-  }
-
-  if (!allowDatabaseUpgrade)
-  {
-    LOG(ERROR) << "The database schema must be upgraded from version "
-               << currentVersion << " to " << ORTHANC_DATABASE_VERSION 
-               << ": Please run Orthanc with the \"--upgrade\" command-line option";
-    return false;
+    throw OrthancException(ErrorCode_IncompatibleDatabaseVersion);
   }
 
   LOG(WARNING) << "Upgrading the database from schema version "
@@ -923,10 +932,13 @@ static bool UpgradeDatabase(IDatabaseWrapper& database,
   if (ORTHANC_DATABASE_VERSION != currentVersion)
   {
     LOG(ERROR) << "The database schema was not properly upgraded, it is still at version " << currentVersion;
-    throw OrthancException(ErrorCode_InternalError);
+    throw OrthancException(ErrorCode_IncompatibleDatabaseVersion);
+  }
+  else
+  {
+    LOG(WARNING) << "The database schema was successfully upgraded, "
+                 << "you can now start Orthanc without the \"--upgrade\" argument";
   }
-
-  return true;
 }
 
 
@@ -1012,13 +1024,23 @@ static bool ConfigureServerContext(IDatabaseWrapper& database,
 static bool ConfigureDatabase(IDatabaseWrapper& database,
                               IStorageArea& storageArea,
                               OrthancPlugins *plugins,
-                              bool allowDatabaseUpgrade)
+                              bool upgradeDatabase)
 {
   database.Open();
+
+  unsigned int currentVersion = database.GetDatabaseVersion();
   
-  if (!UpgradeDatabase(database, storageArea, allowDatabaseUpgrade))
+  if (upgradeDatabase)
+  {
+    UpgradeDatabase(database, storageArea);
+    return false;  // Stop and don't restart Orthanc (cf. issue 29)
+  }
+  else if (currentVersion != ORTHANC_DATABASE_VERSION)
   {
-    return false;
+    LOG(ERROR) << "The database schema must be changed from version "
+               << currentVersion << " to " << ORTHANC_DATABASE_VERSION 
+               << ": Please run Orthanc with the \"--upgrade\" argument";
+    throw OrthancException(ErrorCode_IncompatibleDatabaseVersion);
   }
 
   bool success = ConfigureServerContext(database, storageArea, plugins);
@@ -1031,7 +1053,7 @@ static bool ConfigureDatabase(IDatabaseWrapper& database,
 
 static bool ConfigurePlugins(int argc, 
                              char* argv[],
-                             bool allowDatabaseUpgrade)
+                             bool upgradeDatabase)
 {
   std::auto_ptr<IDatabaseWrapper>  databasePtr;
   std::auto_ptr<IStorageArea>  storage;
@@ -1066,14 +1088,14 @@ static bool ConfigurePlugins(int argc,
   assert(database != NULL);
   assert(storage.get() != NULL);
 
-  return ConfigureDatabase(*database, *storage, &plugins, allowDatabaseUpgrade);
+  return ConfigureDatabase(*database, *storage, &plugins, upgradeDatabase);
 
 #elif ORTHANC_ENABLE_PLUGINS == 0
   // The plugins are disabled
   databasePtr.reset(Configuration::CreateDatabaseWrapper());
   storage.reset(Configuration::CreateStorageArea());
 
-  return ConfigureDatabase(*databasePtr, *storage, NULL, allowDatabaseUpgrade);
+  return ConfigureDatabase(*databasePtr, *storage, NULL, upgradeDatabase);
 
 #else
 #  error The macro ORTHANC_ENABLE_PLUGINS must be set to 0 or 1
@@ -1083,9 +1105,9 @@ static bool ConfigurePlugins(int argc,
 
 static bool StartOrthanc(int argc, 
                          char* argv[],
-                         bool allowDatabaseUpgrade)
+                         bool upgradeDatabase)
 {
-  return ConfigurePlugins(argc, argv, allowDatabaseUpgrade);
+  return ConfigurePlugins(argc, argv, upgradeDatabase);
 }
 
 
@@ -1101,7 +1123,7 @@ int main(int argc, char* argv[])
 {
   Logging::Initialize();
 
-  bool allowDatabaseUpgrade = false;
+  bool upgradeDatabase = false;
   const char* configurationFile = NULL;
 
 
@@ -1190,7 +1212,7 @@ int main(int argc, char* argv[])
     }
     else if (argument == "--upgrade")
     {
-      allowDatabaseUpgrade = true;
+      upgradeDatabase = true;
     }
     else if (boost::starts_with(argument, "--config="))
     {
@@ -1204,8 +1226,17 @@ int main(int argc, char* argv[])
 #endif
 
       std::string target = argument.substr(9);
-      SystemToolbox::WriteFile(configurationSample, target);
-      return 0;
+
+      try
+      {
+        SystemToolbox::WriteFile(configurationSample, target);
+        return 0;
+      }
+      catch (OrthancException&)
+      {
+        LOG(ERROR) << "Cannot write sample configuration as file \"" << target << "\"";
+        return -1;
+      }
     }
     else
     {
@@ -1246,7 +1277,7 @@ int main(int argc, char* argv[])
     {
       OrthancInitialize(configurationFile);
 
-      bool restart = StartOrthanc(argc, argv, allowDatabaseUpgrade);
+      bool restart = StartOrthanc(argc, argv, upgradeDatabase);
       if (restart)
       {
         OrthancFinalize();
diff --git a/Plugins/Engine/IPluginServiceProvider.h b/Plugins/Engine/IPluginServiceProvider.h
index 3656f22..0954c78 100644
--- a/Plugins/Engine/IPluginServiceProvider.h
+++ b/Plugins/Engine/IPluginServiceProvider.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Engine/OrthancPluginDatabase.cpp b/Plugins/Engine/OrthancPluginDatabase.cpp
index 03b3280..d15667b 100644
--- a/Plugins/Engine/OrthancPluginDatabase.cpp
+++ b/Plugins/Engine/OrthancPluginDatabase.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Engine/OrthancPluginDatabase.h b/Plugins/Engine/OrthancPluginDatabase.h
index 5788eeb..9037714 100644
--- a/Plugins/Engine/OrthancPluginDatabase.h
+++ b/Plugins/Engine/OrthancPluginDatabase.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Engine/OrthancPlugins.cpp b/Plugins/Engine/OrthancPlugins.cpp
index 53a5780..da07351 100644
--- a/Plugins/Engine/OrthancPlugins.cpp
+++ b/Plugins/Engine/OrthancPlugins.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -344,6 +345,7 @@ namespace Orthanc
     typedef std::list<OrthancPluginOnStoredInstanceCallback>  OnStoredCallbacks;
     typedef std::list<OrthancPluginOnChangeCallback>  OnChangeCallbacks;
     typedef std::list<OrthancPluginIncomingHttpRequestFilter>  IncomingHttpRequestFilters;
+    typedef std::list<OrthancPluginIncomingHttpRequestFilter2>  IncomingHttpRequestFilters2;
     typedef std::list<OrthancPluginDecodeImageCallback>  DecodeImageCallbacks;
     typedef std::map<Property, std::string>  Properties;
 
@@ -357,6 +359,7 @@ namespace Orthanc
     DecodeImageCallbacks  decodeImageCallbacks_;
     _OrthancPluginMoveCallback moveCallbacks_;
     IncomingHttpRequestFilters  incomingHttpRequestFilters_;
+    IncomingHttpRequestFilters2 incomingHttpRequestFilters2_;
     std::auto_ptr<StorageAreaFactory>  storageArea_;
 
     boost::recursive_mutex restCallbackMutex_;
@@ -409,14 +412,13 @@ namespace Orthanc
                         ParsedDicomFile& query,
                         const std::string& remoteIp,
                         const std::string& remoteAet,
-                        const std::string& calledAet)
+                        const std::string& calledAet,
+                        ModalityManufacturer manufacturer)
     {
-      bool caseSensitivePN = Configuration::GetGlobalBoolParameter("CaseSensitivePN", false);
-
       {
         boost::mutex::scoped_lock lock(that_.pimpl_->worklistCallbackMutex_);
 
-        matcher_.reset(new HierarchicalMatcher(query, caseSensitivePN));
+        matcher_.reset(new HierarchicalMatcher(query));
         currentQuery_ = &query;
 
         if (that_.pimpl_->worklistCallback_)
@@ -501,7 +503,8 @@ namespace Orthanc
                         const std::list<DicomTag>& sequencesToReturn,
                         const std::string& remoteIp,
                         const std::string& remoteAet,
-                        const std::string& calledAet)
+                        const std::string& calledAet,
+                        ModalityManufacturer manufacturer)
     {
       DicomMap tmp;
       tmp.Assign(input);
@@ -1120,6 +1123,16 @@ namespace Orthanc
   }
 
 
+  void OrthancPlugins::RegisterIncomingHttpRequestFilter2(const void* parameters)
+  {
+    const _OrthancPluginIncomingHttpRequestFilter2& p = 
+      *reinterpret_cast<const _OrthancPluginIncomingHttpRequestFilter2*>(parameters);
+
+    LOG(INFO) << "Plugin has registered a callback to filter incoming HTTP requests";
+    pimpl_->incomingHttpRequestFilters2_.push_back(p.callback);
+  }
+
+
   void OrthancPlugins::AnswerBuffer(const void* parameters)
   {
     const _OrthancPluginAnswerBuffer& p = 
@@ -2597,8 +2610,7 @@ namespace Orthanc
         const _OrthancPluginCreateFindMatcher& p =
           *reinterpret_cast<const _OrthancPluginCreateFindMatcher*>(parameters);
         ParsedDicomFile query(p.query, p.size);
-        *(p.target) = reinterpret_cast<OrthancPluginFindMatcher*>
-          (new HierarchicalMatcher(query, Configuration::GetGlobalBoolParameter("CaseSensitivePN", false)));
+        *(p.target) = reinterpret_cast<OrthancPluginFindMatcher*>(new HierarchicalMatcher(query));
         return true;
       }
 
@@ -2688,6 +2700,10 @@ namespace Orthanc
         RegisterIncomingHttpRequestFilter(parameters);
         return true;
 
+      case _OrthancPluginService_RegisterIncomingHttpRequestFilter2:
+        RegisterIncomingHttpRequestFilter2(parameters);
+        return true;
+
       case _OrthancPluginService_RegisterStorageArea:
       {
         LOG(INFO) << "Plugin has registered a custom storage area";
@@ -3098,8 +3114,11 @@ namespace Orthanc
                                  const char* uri,
                                  const char* ip,
                                  const char* username,
-                                 const IHttpHandler::Arguments& httpHeaders) const
+                                 const IHttpHandler::Arguments& httpHeaders,
+                                 const IHttpHandler::GetArguments& getArguments) const
   {
+    OrthancPluginHttpMethod cMethod = Plugins::Convert(method);
+
     std::vector<const char*> httpKeys(httpHeaders.size());
     std::vector<const char*> httpValues(httpHeaders.size());
 
@@ -3111,26 +3130,56 @@ namespace Orthanc
       httpValues[pos] = it->second.c_str();
     }
 
-    OrthancPluginHttpMethod cMethod = Plugins::Convert(method);
-    const char** cHttpKeys = (httpKeys.size() == 0 ? NULL : &httpKeys[0]);
-    const char** cHttpValues = (httpValues.size() == 0 ? NULL : &httpValues[0]);
+    std::vector<const char*> getKeys(getArguments.size());
+    std::vector<const char*> getValues(getArguments.size());
 
-    for (PImpl::IncomingHttpRequestFilters::const_iterator
-           filter = pimpl_->incomingHttpRequestFilters_.begin();
-         filter != pimpl_->incomingHttpRequestFilters_.end(); ++filter)
+    for (size_t i = 0; i < getArguments.size(); i++)
     {
-      int32_t allowed = (*filter) (cMethod, uri, ip, httpKeys.size(), cHttpKeys, cHttpValues);
+      getKeys[i] = getArguments[i].first.c_str();
+      getValues[i] = getArguments[i].second.c_str();
+    }
 
-      if (allowed != 0 &&
-          allowed != 1)
+    // Improved callback with support for GET arguments, since Orthanc 1.3.0
+    for (PImpl::IncomingHttpRequestFilters2::const_iterator
+           filter = pimpl_->incomingHttpRequestFilters2_.begin();
+         filter != pimpl_->incomingHttpRequestFilters2_.end(); ++filter)
+    {
+      int32_t allowed = (*filter) (cMethod, uri, ip,
+                                   httpKeys.size(),
+                                   httpKeys.empty() ? NULL : &httpKeys[0],
+                                   httpValues.empty() ? NULL : &httpValues[0],
+                                   getKeys.size(),
+                                   getKeys.empty() ? NULL : &getKeys[0],
+                                   getValues.empty() ? NULL : &getValues[0]);
+
+      if (allowed == 0)
+      {
+        return false;
+      }
+      else if (allowed != 1)
       {
+        // The callback is only allowed to answer 0 or 1
         throw OrthancException(ErrorCode_Plugin);
       }
+    }
+
+    for (PImpl::IncomingHttpRequestFilters::const_iterator
+           filter = pimpl_->incomingHttpRequestFilters_.begin();
+         filter != pimpl_->incomingHttpRequestFilters_.end(); ++filter)
+    {
+      int32_t allowed = (*filter) (cMethod, uri, ip, httpKeys.size(),
+                                   httpKeys.empty() ? NULL : &httpKeys[0],
+                                   httpValues.empty() ? NULL : &httpValues[0]);
 
       if (allowed == 0)
       {
         return false;
       }
+      else if (allowed != 1)
+      {
+        // The callback is only allowed to answer 0 or 1
+        throw OrthancException(ErrorCode_Plugin);
+      }
     }
 
     return true;
diff --git a/Plugins/Engine/OrthancPlugins.h b/Plugins/Engine/OrthancPlugins.h
index d8cd8a5..a8e8dff 100644
--- a/Plugins/Engine/OrthancPlugins.h
+++ b/Plugins/Engine/OrthancPlugins.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -105,6 +106,8 @@ namespace Orthanc
 
     void RegisterIncomingHttpRequestFilter(const void* parameters);
 
+    void RegisterIncomingHttpRequestFilter2(const void* parameters);
+
     void AnswerBuffer(const void* parameters);
 
     void Redirect(const void* parameters);
@@ -280,7 +283,8 @@ namespace Orthanc
                            const char* uri,
                            const char* ip,
                            const char* username,
-                           const IHttpHandler::Arguments& httpHeaders) const;
+                           const IHttpHandler::Arguments& httpHeaders,
+                           const IHttpHandler::GetArguments& getArguments) const;
 
     bool HasFindHandler();
 
diff --git a/Plugins/Engine/PluginsEnumerations.cpp b/Plugins/Engine/PluginsEnumerations.cpp
index 9814b4e..53f587e 100644
--- a/Plugins/Engine/PluginsEnumerations.cpp
+++ b/Plugins/Engine/PluginsEnumerations.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Engine/PluginsEnumerations.h b/Plugins/Engine/PluginsEnumerations.h
index 1540232..e5e5ce4 100644
--- a/Plugins/Engine/PluginsEnumerations.h
+++ b/Plugins/Engine/PluginsEnumerations.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Engine/PluginsErrorDictionary.cpp b/Plugins/Engine/PluginsErrorDictionary.cpp
index c64c5f8..40fa155 100644
--- a/Plugins/Engine/PluginsErrorDictionary.cpp
+++ b/Plugins/Engine/PluginsErrorDictionary.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Engine/PluginsErrorDictionary.h b/Plugins/Engine/PluginsErrorDictionary.h
index 5e5214d..676347c 100644
--- a/Plugins/Engine/PluginsErrorDictionary.h
+++ b/Plugins/Engine/PluginsErrorDictionary.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Engine/PluginsManager.cpp b/Plugins/Engine/PluginsManager.cpp
index a3becba..776c58a 100644
--- a/Plugins/Engine/PluginsManager.cpp
+++ b/Plugins/Engine/PluginsManager.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Engine/PluginsManager.h b/Plugins/Engine/PluginsManager.h
index f04bff9..9e6bf3a 100644
--- a/Plugins/Engine/PluginsManager.h
+++ b/Plugins/Engine/PluginsManager.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Engine/SharedLibrary.cpp b/Plugins/Engine/SharedLibrary.cpp
index 1adc878..97e231d 100644
--- a/Plugins/Engine/SharedLibrary.cpp
+++ b/Plugins/Engine/SharedLibrary.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Engine/SharedLibrary.h b/Plugins/Engine/SharedLibrary.h
index 330966c..b5fc419 100644
--- a/Plugins/Engine/SharedLibrary.h
+++ b/Plugins/Engine/SharedLibrary.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Include/orthanc/OrthancCDatabasePlugin.h b/Plugins/Include/orthanc/OrthancCDatabasePlugin.h
index 36cc8b7..0c0632f 100644
--- a/Plugins/Include/orthanc/OrthancCDatabasePlugin.h
+++ b/Plugins/Include/orthanc/OrthancCDatabasePlugin.h
@@ -6,6 +6,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Include/orthanc/OrthancCPlugin.h b/Plugins/Include/orthanc/OrthancCPlugin.h
index b9aa629..f278a36 100644
--- a/Plugins/Include/orthanc/OrthancCPlugin.h
+++ b/Plugins/Include/orthanc/OrthancCPlugin.h
@@ -22,7 +22,7 @@
  *    - Possibly register a handler for C-Find SCP against DICOM worklists using OrthancPluginRegisterWorklistCallback().
  *    - Possibly register a handler for C-Move SCP using OrthancPluginRegisterMoveCallback().
  *    - Possibly register a custom decoder for DICOM images using OrthancPluginRegisterDecodeImageCallback().
- *    - Possibly register a callback to filter incoming HTTP requests using OrthancPluginRegisterIncomingHttpRequestFilter().
+ *    - Possibly register a callback to filter incoming HTTP requests using OrthancPluginRegisterIncomingHttpRequestFilter2().
  * -# <tt>void OrthancPluginFinalize()</tt>:
  *    This function is invoked by Orthanc during its shutdown. The plugin
  *    must free all its memory.
@@ -74,6 +74,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -116,7 +117,7 @@
 #endif
 
 #define ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER     1
-#define ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER     2
+#define ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER     3
 #define ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER  0
 
 
@@ -421,6 +422,7 @@ extern "C"
     _OrthancPluginService_RegisterIncomingHttpRequestFilter = 1007,
     _OrthancPluginService_RegisterFindCallback = 1008,
     _OrthancPluginService_RegisterMoveCallback = 1009,
+    _OrthancPluginService_RegisterIncomingHttpRequestFilter2 = 1010,
 
     /* Sending answers to REST calls */
     _OrthancPluginService_AnswerBuffer = 2000,
@@ -1013,6 +1015,7 @@ extern "C"
    * @param headersValues The values of the HTTP headers.
    * @return 0 if forbidden access, 1 if allowed access, -1 if error.
    * @ingroup Callback
+   * @deprecated Please instead use OrthancPluginIncomingHttpRequestFilter2()
    **/
   typedef int32_t (*OrthancPluginIncomingHttpRequestFilter) (
     OrthancPluginHttpMethod  method,
@@ -1025,6 +1028,40 @@ extern "C"
 
 
   /**
+   * @brief Callback to filter incoming HTTP requests received by Orthanc.
+   *
+   * Signature of a callback function that is triggered whenever
+   * Orthanc receives an HTTP/REST request, and that answers whether
+   * this request should be allowed. If the callback returns "0"
+   * ("false"), the server answers with HTTP status code 403
+   * (Forbidden).
+   *
+   * @param method The HTTP method used by the request.
+   * @param uri The URI of interest.
+   * @param ip The IP address of the HTTP client.
+   * @param headersCount The number of HTTP headers.
+   * @param headersKeys The keys of the HTTP headers (always converted to low-case).
+   * @param headersValues The values of the HTTP headers.
+   * @param getArgumentsCount The number of GET arguments (only for the GET HTTP method).
+   * @param getArgumentsKeys The keys of the GET arguments (only for the GET HTTP method).
+   * @param getArgumentsValues The values of the GET arguments (only for the GET HTTP method).
+   * @return 0 if forbidden access, 1 if allowed access, -1 if error.
+   * @ingroup Callback
+   **/
+  typedef int32_t (*OrthancPluginIncomingHttpRequestFilter2) (
+    OrthancPluginHttpMethod  method,
+    const char*              uri,
+    const char*              ip,
+    uint32_t                 headersCount,
+    const char* const*       headersKeys,
+    const char* const*       headersValues,
+    uint32_t                 getArgumentsCount,
+    const char* const*       getArgumentsKeys,
+    const char* const*       getArgumentsValues);
+
+
+
+  /**
    * @brief Callback to handle incoming C-Find SCP requests.
    *
    * Signature of a callback function that is triggered whenever
@@ -4996,6 +5033,7 @@ extern "C"
    * @param callback The callback.
    * @return 0 if success, other value if error.
    * @ingroup Callbacks
+   * @deprecated Please instead use OrthancPluginRegisterIncomingHttpRequestFilter2()
    **/
   ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginRegisterIncomingHttpRequestFilter(
     OrthancPluginContext*                   context,
@@ -5545,6 +5583,32 @@ extern "C"
   }
 
 
+  typedef struct
+  {
+    OrthancPluginIncomingHttpRequestFilter2 callback;
+  } _OrthancPluginIncomingHttpRequestFilter2;
+
+  /**
+   * @brief Register a callback to filter incoming HTTP requests.
+   *
+   * This function registers a custom callback to filter incoming HTTP/REST
+   * requests received by the HTTP server of Orthanc.
+   *
+   * @param context The Orthanc plugin context, as received by OrthancPluginInitialize().
+   * @param callback The callback.
+   * @return 0 if success, other value if error.
+   * @ingroup Callbacks
+   **/
+  ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginRegisterIncomingHttpRequestFilter2(
+    OrthancPluginContext*                   context,
+    OrthancPluginIncomingHttpRequestFilter2 callback)
+  {
+    _OrthancPluginIncomingHttpRequestFilter2 params;
+    params.callback = callback;
+
+    return context->InvokeService(context, _OrthancPluginService_RegisterIncomingHttpRequestFilter2, &params);
+  }
+
 #ifdef  __cplusplus
 }
 #endif
diff --git a/Plugins/Include/orthanc/OrthancCppDatabasePlugin.h b/Plugins/Include/orthanc/OrthancCppDatabasePlugin.h
index dd8b840..b383e8b 100644
--- a/Plugins/Include/orthanc/OrthancCppDatabasePlugin.h
+++ b/Plugins/Include/orthanc/OrthancCppDatabasePlugin.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/AutomatedJpeg2kCompression/Plugin.cpp b/Plugins/Samples/AutomatedJpeg2kCompression/Plugin.cpp
index 44752e6..62bd2ec 100644
--- a/Plugins/Samples/AutomatedJpeg2kCompression/Plugin.cpp
+++ b/Plugins/Samples/AutomatedJpeg2kCompression/Plugin.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/Basic/Plugin.c b/Plugins/Samples/Basic/Plugin.c
index b30e4da..5826197 100644
--- a/Plugins/Samples/Basic/Plugin.c
+++ b/Plugins/Samples/Basic/Plugin.c
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/Common/DicomDatasetReader.cpp b/Plugins/Samples/Common/DicomDatasetReader.cpp
index b354bb1..6cd8dca 100644
--- a/Plugins/Samples/Common/DicomDatasetReader.cpp
+++ b/Plugins/Samples/Common/DicomDatasetReader.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -32,7 +33,7 @@
 
 #include "DicomDatasetReader.h"
 
-#include "OrthancPluginCppWrapper.h"
+#include "OrthancPluginException.h"
 
 #include <boost/lexical_cast.hpp>
 
@@ -68,55 +69,105 @@ namespace OrthancPlugins
   }
 
 
-  DicomDatasetReader::DicomDatasetReader(IDicomDataset* dataset) :  // takes ownership
+  DicomDatasetReader::DicomDatasetReader(const IDicomDataset& dataset) :
     dataset_(dataset)
   {
-    if (dataset == NULL)
+  }
+  
+
+  std::string DicomDatasetReader::GetStringValue(const DicomPath& path,
+                                                 const std::string& defaultValue) const
+  {
+    std::string s;
+    if (dataset_.GetStringValue(s, path))
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_ParameterOutOfRange);
+      return s;
+    }
+    else
+    {
+      return defaultValue;
     }
   }
-  
+
 
   std::string DicomDatasetReader::GetMandatoryStringValue(const DicomPath& path) const
   {
     std::string s;
-    if (dataset_->GetStringValue(s, path))
+    if (dataset_.GetStringValue(s, path))
     {
       return s;
     }
     else
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_InexistentTag);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(InexistentTag);
     }
   }
 
 
-  int DicomDatasetReader::GetIntegerValue(const DicomPath& path)
+  template <typename T>
+  static bool GetValueInternal(T& target,
+                               const IDicomDataset& dataset,
+                               const DicomPath& path)
   {
     try
     {
-      std::string s = StripSpaces(GetMandatoryStringValue(path));
-      return boost::lexical_cast<int>(s);
+      std::string s;
+
+      if (dataset.GetStringValue(s, path))
+      {
+        target = boost::lexical_cast<T>(StripSpaces(s));
+        return true;
+      }
+      else
+      {
+        return false;
+      }
     }
     catch (boost::bad_lexical_cast&)
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);        
+      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);        
     }
   }
 
 
-  unsigned int DicomDatasetReader::GetUnsignedIntegerValue(const DicomPath& path)
+  bool DicomDatasetReader::GetIntegerValue(int& target,
+                                           const DicomPath& path) const
   {
-    int value = GetIntegerValue(path);
+    return GetValueInternal<int>(target, dataset_, path);
+  }
+
 
-    if (value >= 0)
+  bool DicomDatasetReader::GetUnsignedIntegerValue(unsigned int& target,
+                                                   const DicomPath& path) const
+  {
+    int value;
+
+    if (!GetIntegerValue(value, path))
+    {
+      return false;
+    }
+    else if (value >= 0)
     {
-      return static_cast<unsigned int>(value);
+      target = static_cast<unsigned int>(value);
+      return true;
     }
     else
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_ParameterOutOfRange);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange);
     }
   }
+
+
+  bool DicomDatasetReader::GetFloatValue(float& target,
+                                         const DicomPath& path) const
+  {
+    return GetValueInternal<float>(target, dataset_, path);
+  }
+
+
+  bool DicomDatasetReader::GetDoubleValue(double& target,
+                                          const DicomPath& path) const
+  {
+    return GetValueInternal<double>(target, dataset_, path);
+  }
 }
diff --git a/Plugins/Samples/Common/DicomDatasetReader.h b/Plugins/Samples/Common/DicomDatasetReader.h
index 0074071..ea60a2a 100644
--- a/Plugins/Samples/Common/DicomDatasetReader.h
+++ b/Plugins/Samples/Common/DicomDatasetReader.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -35,26 +36,38 @@
 #include "IDicomDataset.h"
 
 #include <memory>
+#include <vector>
 
 namespace OrthancPlugins
 {
   class DicomDatasetReader : public boost::noncopyable
   {
   private:
-    std::auto_ptr<IDicomDataset>  dataset_;
+    const IDicomDataset&  dataset_;
 
   public:
-    DicomDatasetReader(IDicomDataset* dataset);  // takes ownership
+    DicomDatasetReader(const IDicomDataset& dataset);
 
-    IDicomDataset& GetDataset() const
+    const IDicomDataset& GetDataset() const
     {
-      return *dataset_;
+      return dataset_;
     }
 
+    std::string GetStringValue(const DicomPath& path,
+                               const std::string& defaultValue) const;
+
     std::string GetMandatoryStringValue(const DicomPath& path) const;
 
-    int GetIntegerValue(const DicomPath& path);
+    bool GetIntegerValue(int& target,
+                         const DicomPath& path) const;
+
+    bool GetUnsignedIntegerValue(unsigned int& target,
+                                 const DicomPath& path) const;
+
+    bool GetFloatValue(float& target,
+                       const DicomPath& path) const;
 
-    unsigned int GetUnsignedIntegerValue(const DicomPath& path);
+    bool GetDoubleValue(double& target,
+                        const DicomPath& path) const;
   };
 }
diff --git a/Plugins/Samples/Common/DicomPath.cpp b/Plugins/Samples/Common/DicomPath.cpp
index 3437e60..f0e6c2e 100644
--- a/Plugins/Samples/Common/DicomPath.cpp
+++ b/Plugins/Samples/Common/DicomPath.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -32,7 +33,7 @@
 
 #include "DicomPath.h"
 
-#include "OrthancPluginCppWrapper.h"
+#include "OrthancPluginException.h"
 
 namespace OrthancPlugins
 {
@@ -40,7 +41,7 @@ namespace OrthancPlugins
   {
     if (depth >= prefix_.size())
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_ParameterOutOfRange);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange);
     }
     else
     {
diff --git a/Plugins/Samples/Common/DicomPath.h b/Plugins/Samples/Common/DicomPath.h
index f14f051..1ce79ae 100644
--- a/Plugins/Samples/Common/DicomPath.h
+++ b/Plugins/Samples/Common/DicomPath.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/Common/DicomTag.cpp b/Plugins/Samples/Common/DicomTag.cpp
index 040d885..2ca18b8 100644
--- a/Plugins/Samples/Common/DicomTag.cpp
+++ b/Plugins/Samples/Common/DicomTag.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -32,7 +33,7 @@
 
 #include "DicomTag.h"
 
-#include "OrthancPluginCppWrapper.h"
+#include "OrthancPluginException.h"
 
 namespace OrthancPlugins
 {
@@ -104,7 +105,7 @@ namespace OrthancPlugins
     }
     else
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_NotImplemented);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(NotImplemented);
     }
   }
 }
diff --git a/Plugins/Samples/Common/DicomTag.h b/Plugins/Samples/Common/DicomTag.h
index 660d078..51e5901 100644
--- a/Plugins/Samples/Common/DicomTag.h
+++ b/Plugins/Samples/Common/DicomTag.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -77,19 +78,27 @@ namespace OrthancPlugins
 
 
   static const DicomTag DICOM_TAG_BITS_STORED(0x0028, 0x0101);
-  static const DicomTag DICOM_TAG_COLUMN_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX(0x0048, 0x021e);
   static const DicomTag DICOM_TAG_COLUMNS(0x0028, 0x0011);
+  static const DicomTag DICOM_TAG_COLUMN_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX(0x0048, 0x021e);
+  static const DicomTag DICOM_TAG_IMAGE_ORIENTATION_PATIENT(0x0020, 0x0037);
+  static const DicomTag DICOM_TAG_IMAGE_POSITION_PATIENT(0x0020, 0x0032);
   static const DicomTag DICOM_TAG_MODALITY(0x0008, 0x0060);
   static const DicomTag DICOM_TAG_NUMBER_OF_FRAMES(0x0028, 0x0008);
   static const DicomTag DICOM_TAG_PER_FRAME_FUNCTIONAL_GROUPS_SEQUENCE(0x5200, 0x9230);
   static const DicomTag DICOM_TAG_PHOTOMETRIC_INTERPRETATION(0x0028, 0x0004);
   static const DicomTag DICOM_TAG_PIXEL_REPRESENTATION(0x0028, 0x0103);
+  static const DicomTag DICOM_TAG_PIXEL_SPACING(0x0028, 0x0030);
   static const DicomTag DICOM_TAG_PLANE_POSITION_SLIDE_SEQUENCE(0x0048, 0x021a);
-  static const DicomTag DICOM_TAG_ROW_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX(0x0048, 0x021f);
+  static const DicomTag DICOM_TAG_RESCALE_INTERCEPT(0x0028, 0x1052);
+  static const DicomTag DICOM_TAG_RESCALE_SLOPE(0x0028, 0x1053);
   static const DicomTag DICOM_TAG_ROWS(0x0028, 0x0010);
-  static const DicomTag DICOM_TAG_SOP_CLASS_UID(0x0008, 0x0016);
+  static const DicomTag DICOM_TAG_ROW_POSITION_IN_TOTAL_IMAGE_PIXEL_MATRIX(0x0048, 0x021f);
   static const DicomTag DICOM_TAG_SAMPLES_PER_PIXEL(0x0028, 0x0002);
+  static const DicomTag DICOM_TAG_SLICE_THICKNESS(0x0018, 0x0050);
+  static const DicomTag DICOM_TAG_SOP_CLASS_UID(0x0008, 0x0016);
   static const DicomTag DICOM_TAG_TOTAL_PIXEL_MATRIX_COLUMNS(0x0048, 0x0006);
   static const DicomTag DICOM_TAG_TOTAL_PIXEL_MATRIX_ROWS(0x0048, 0x0007);
   static const DicomTag DICOM_TAG_TRANSFER_SYNTAX_UID(0x0002, 0x0010);
+  static const DicomTag DICOM_TAG_WINDOW_CENTER(0x0028, 0x1050);
+  static const DicomTag DICOM_TAG_WINDOW_WIDTH(0x0028, 0x1051);
 }
diff --git a/Plugins/Samples/Common/FullOrthancDataset.cpp b/Plugins/Samples/Common/FullOrthancDataset.cpp
index 638654b..0f9269b 100644
--- a/Plugins/Samples/Common/FullOrthancDataset.cpp
+++ b/Plugins/Samples/Common/FullOrthancDataset.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -32,7 +33,10 @@
 
 #include "FullOrthancDataset.h"
 
-#include "OrthancPluginCppWrapper.h"
+#include "OrthancPluginException.h"
+
+#include <stdio.h>
+#include <cassert>
 
 namespace OrthancPlugins
 {
@@ -41,7 +45,7 @@ namespace OrthancPlugins
   {
     if (dataset.type() != Json::objectValue)
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
     }
 
     char name[16];
@@ -60,7 +64,7 @@ namespace OrthancPlugins
         value["Name"].type() != Json::stringValue ||
         value["Type"].type() != Json::stringValue)
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
     }
 
     return &value;
@@ -78,7 +82,7 @@ namespace OrthancPlugins
     if (sequence["Type"].asString() != "Sequence" ||
         value.type() != Json::arrayValue)
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
     }
     else
     {
@@ -99,7 +103,7 @@ namespace OrthancPlugins
     if (tag["Type"].asString() != "String" ||
         value.type() != Json::stringValue)
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
     }
     else
     {
@@ -142,7 +146,7 @@ namespace OrthancPlugins
   {
     if (root_.type() != Json::objectValue)
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
     }
   }
 
@@ -162,6 +166,21 @@ namespace OrthancPlugins
   }
 
 
+  FullOrthancDataset::FullOrthancDataset(const void* content,
+                                         size_t size)
+  {
+    IOrthancConnection::ParseJson(root_, content, size);
+    CheckRoot();
+  }
+
+
+  FullOrthancDataset::FullOrthancDataset(const Json::Value& root) :
+    root_(root)
+  {
+    CheckRoot();
+  }
+
+
   bool FullOrthancDataset::GetStringValue(std::string& result,
                                           const DicomPath& path) const
   {
diff --git a/Plugins/Samples/Common/FullOrthancDataset.h b/Plugins/Samples/Common/FullOrthancDataset.h
index 18ab444..e3e20b4 100644
--- a/Plugins/Samples/Common/FullOrthancDataset.h
+++ b/Plugins/Samples/Common/FullOrthancDataset.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -54,6 +55,11 @@ namespace OrthancPlugins
 
     FullOrthancDataset(const std::string& content);
 
+    FullOrthancDataset(const void* content,
+                       size_t size);
+
+    FullOrthancDataset(const Json::Value& root);
+
     virtual bool GetStringValue(std::string& result,
                                 const DicomPath& path) const;
 
diff --git a/Plugins/Samples/Common/IDicomDataset.h b/Plugins/Samples/Common/IDicomDataset.h
index 7fc549e..4d439a1 100644
--- a/Plugins/Samples/Common/IDicomDataset.h
+++ b/Plugins/Samples/Common/IDicomDataset.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/Common/IOrthancConnection.cpp b/Plugins/Samples/Common/IOrthancConnection.cpp
index 5a66912..a29e51e 100644
--- a/Plugins/Samples/Common/IOrthancConnection.cpp
+++ b/Plugins/Samples/Common/IOrthancConnection.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -32,7 +33,7 @@
 
 #include "IOrthancConnection.h"
 
-#include "OrthancPluginCppWrapper.h"
+#include "OrthancPluginException.h"
 
 #include <json/reader.h>
 
@@ -45,7 +46,21 @@ namespace OrthancPlugins
     
     if (!reader.parse(content, result))
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
+    }
+  }
+
+
+  void IOrthancConnection::ParseJson(Json::Value& result,
+                                     const void* content,
+                                     size_t size)
+  {
+    Json::Reader reader;
+    
+    if (!reader.parse(reinterpret_cast<const char*>(content),
+                      reinterpret_cast<const char*>(content) + size, result))
+    {
+      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
     }
   }
 
diff --git a/Plugins/Samples/Common/IOrthancConnection.h b/Plugins/Samples/Common/IOrthancConnection.h
index f64dd5a..61d73e8 100644
--- a/Plugins/Samples/Common/IOrthancConnection.h
+++ b/Plugins/Samples/Common/IOrthancConnection.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -63,6 +64,10 @@ namespace OrthancPlugins
     static void ParseJson(Json::Value& result,
                           const std::string& content);
 
+    static void ParseJson(Json::Value& result,
+                          const void* content,
+                          size_t size);
+
     static void RestApiGet(Json::Value& result,
                            IOrthancConnection& orthanc,
                            const std::string& uri);
diff --git a/Plugins/Samples/Common/OrthancHttpConnection.cpp b/Plugins/Samples/Common/OrthancHttpConnection.cpp
index a1f9846..7b96a90 100644
--- a/Plugins/Samples/Common/OrthancHttpConnection.cpp
+++ b/Plugins/Samples/Common/OrthancHttpConnection.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/Common/OrthancHttpConnection.h b/Plugins/Samples/Common/OrthancHttpConnection.h
index c1e69bd..29d92ea 100644
--- a/Plugins/Samples/Common/OrthancHttpConnection.h
+++ b/Plugins/Samples/Common/OrthancHttpConnection.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/Common/OrthancPluginConnection.cpp b/Plugins/Samples/Common/OrthancPluginConnection.cpp
index fb82353..e6eb3c2 100644
--- a/Plugins/Samples/Common/OrthancPluginConnection.cpp
+++ b/Plugins/Samples/Common/OrthancPluginConnection.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -47,7 +48,7 @@ namespace OrthancPlugins
     }
     else
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_UnknownResource);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(UnknownResource);
     }
   }
 
@@ -64,7 +65,7 @@ namespace OrthancPlugins
     }
     else
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_UnknownResource);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(UnknownResource);
     }
   }
 
@@ -81,7 +82,7 @@ namespace OrthancPlugins
     }
     else
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_UnknownResource);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(UnknownResource);
     }
   }
 
@@ -92,7 +93,7 @@ namespace OrthancPlugins
 
     if (!::OrthancPlugins::RestApiDelete(context_, uri, false))
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_UnknownResource);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(UnknownResource);
     }
   }
 }
diff --git a/Plugins/Samples/Common/OrthancPluginConnection.h b/Plugins/Samples/Common/OrthancPluginConnection.h
index f4b06ff..50761df 100644
--- a/Plugins/Samples/Common/OrthancPluginConnection.h
+++ b/Plugins/Samples/Common/OrthancPluginConnection.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp b/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp
index b26c512..23bd4d4 100644
--- a/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp
+++ b/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -38,40 +39,39 @@
 
 namespace OrthancPlugins
 {
-  const char* GetErrorDescription(OrthancPluginContext* context,
-                                  OrthancPluginErrorCode code)
-  {
-    const char* description = OrthancPluginGetErrorDescription(context, code);
-    if (description)
-    {
-      return description;
-    }
-    else
-    {
-      return "No description available";
-    }
-  }
-
-  
-#if HAS_ORTHANC_EXCEPTION == 0
-  void PluginException::Check(OrthancPluginErrorCode code)
+  void MemoryBuffer::Check(OrthancPluginErrorCode code)
   {
     if (code != OrthancPluginErrorCode_Success)
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(code);
+      // Prevent using garbage information
+      buffer_.data = NULL;
+      buffer_.size = 0;
+      ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code);
     }
   }
-#endif
 
 
-  void MemoryBuffer::Check(OrthancPluginErrorCode code)
+  bool MemoryBuffer::CheckHttp(OrthancPluginErrorCode code)
   {
     if (code != OrthancPluginErrorCode_Success)
     {
       // Prevent using garbage information
       buffer_.data = NULL;
       buffer_.size = 0;
-      ORTHANC_PLUGINS_THROW_EXCEPTION(code);
+    }
+
+    if (code == OrthancPluginErrorCode_Success)
+    {
+      return true;
+    }
+    else if (code == OrthancPluginErrorCode_UnknownResource ||
+             code == OrthancPluginErrorCode_InexistentItem)
+    {
+      return false;
+    }
+    else
+    {
+      ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code);
     }
   }
 
@@ -125,7 +125,7 @@ namespace OrthancPlugins
     if (buffer_.data == NULL ||
         buffer_.size == 0)
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_InternalError);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
     }
 
     const char* tmp = reinterpret_cast<const char*>(buffer_.data);
@@ -134,7 +134,7 @@ namespace OrthancPlugins
     if (!reader.parse(tmp, tmp + buffer_.size, target))
     {
       OrthancPluginLogError(context_, "Cannot convert some memory buffer to JSON");
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
     }
   }
 
@@ -144,29 +144,13 @@ namespace OrthancPlugins
   {
     Clear();
 
-    OrthancPluginErrorCode error;
-
     if (applyPlugins)
     {
-      error = OrthancPluginRestApiGetAfterPlugins(context_, &buffer_, uri.c_str());
-    }
-    else
-    {
-      error = OrthancPluginRestApiGet(context_, &buffer_, uri.c_str());
-    }
-
-    if (error == OrthancPluginErrorCode_Success)
-    {
-      return true;
-    }
-    else if (error == OrthancPluginErrorCode_UnknownResource ||
-             error == OrthancPluginErrorCode_InexistentItem)
-    {
-      return false;
+      return CheckHttp(OrthancPluginRestApiGetAfterPlugins(context_, &buffer_, uri.c_str()));
     }
     else
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(error);
+      return CheckHttp(OrthancPluginRestApiGet(context_, &buffer_, uri.c_str()));
     }
   }
 
@@ -178,29 +162,13 @@ namespace OrthancPlugins
   {
     Clear();
 
-    OrthancPluginErrorCode error;
-
     if (applyPlugins)
     {
-      error = OrthancPluginRestApiPostAfterPlugins(context_, &buffer_, uri.c_str(), body, bodySize);
+      return CheckHttp(OrthancPluginRestApiPostAfterPlugins(context_, &buffer_, uri.c_str(), body, bodySize));
     }
     else
     {
-      error = OrthancPluginRestApiPost(context_, &buffer_, uri.c_str(), body, bodySize);
-    }
-
-    if (error == OrthancPluginErrorCode_Success)
-    {
-      return true;
-    }
-    else if (error == OrthancPluginErrorCode_UnknownResource ||
-             error == OrthancPluginErrorCode_InexistentItem)
-    {
-      return false;
-    }
-    else
-    {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(error);
+      return CheckHttp(OrthancPluginRestApiPost(context_, &buffer_, uri.c_str(), body, bodySize));
     }
   }
 
@@ -212,29 +180,13 @@ namespace OrthancPlugins
   {
     Clear();
 
-    OrthancPluginErrorCode error;
-
     if (applyPlugins)
     {
-      error = OrthancPluginRestApiPutAfterPlugins(context_, &buffer_, uri.c_str(), body, bodySize);
+      return CheckHttp(OrthancPluginRestApiPutAfterPlugins(context_, &buffer_, uri.c_str(), body, bodySize));
     }
     else
     {
-      error = OrthancPluginRestApiPut(context_, &buffer_, uri.c_str(), body, bodySize);
-    }
-
-    if (error == OrthancPluginErrorCode_Success)
-    {
-      return true;
-    }
-    else if (error == OrthancPluginErrorCode_UnknownResource ||
-             error == OrthancPluginErrorCode_InexistentItem)
-    {
-      return false;
-    }
-    else
-    {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(error);
+      return CheckHttp(OrthancPluginRestApiPut(context_, &buffer_, uri.c_str(), body, bodySize));
     }
   }
 
@@ -287,7 +239,7 @@ namespace OrthancPlugins
   {
     if (str == NULL)
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_InternalError);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
     }
     else
     {
@@ -325,14 +277,14 @@ namespace OrthancPlugins
     if (str_ == NULL)
     {
       OrthancPluginLogError(context_, "Cannot convert an empty memory buffer to JSON");
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_InternalError);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
     }
 
     Json::Reader reader;
     if (!reader.parse(str_, target))
     {
       OrthancPluginLogError(context_, "Cannot convert some memory buffer to JSON");
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
     }
   }
 
@@ -347,6 +299,69 @@ namespace OrthancPlugins
     str.ToJson(target);
   }
 
+
+  bool MemoryBuffer::HttpGet(const std::string& url,
+                             const std::string& username,
+                             const std::string& password)
+  {
+    Clear();
+    return CheckHttp(OrthancPluginHttpGet(context_, &buffer_, url.c_str(),
+                                          username.empty() ? NULL : username.c_str(),
+                                          password.empty() ? NULL : password.c_str()));
+  }
+
+  
+  bool MemoryBuffer::HttpPost(const std::string& url,
+                              const std::string& body,
+                              const std::string& username,
+                              const std::string& password)
+  {
+    Clear();
+    return CheckHttp(OrthancPluginHttpPost(context_, &buffer_, url.c_str(),
+                                           body.c_str(), body.size(),
+                                           username.empty() ? NULL : username.c_str(),
+                                           password.empty() ? NULL : password.c_str()));
+  }
+  
+ 
+  bool MemoryBuffer::HttpPut(const std::string& url,
+                             const std::string& body,
+                             const std::string& username,
+                             const std::string& password)
+  {
+    Clear();
+    return CheckHttp(OrthancPluginHttpPut(context_, &buffer_, url.c_str(),
+                                          body.empty() ? NULL : body.c_str(),
+                                          body.size(),
+                                          username.empty() ? NULL : username.c_str(),
+                                          password.empty() ? NULL : password.c_str()));
+  }
+  
+ 
+  bool HttpDelete(OrthancPluginContext* context_,
+                  const std::string& url,
+                  const std::string& username,
+                  const std::string& password)
+  {
+    OrthancPluginErrorCode error = OrthancPluginHttpDelete
+      (context_, url.c_str(),
+       username.empty() ? NULL : username.c_str(),
+       password.empty() ? NULL : password.c_str());
+  
+    if (error == OrthancPluginErrorCode_Success)
+    {
+      return true;
+    }
+    else if (error == OrthancPluginErrorCode_UnknownResource ||
+             error == OrthancPluginErrorCode_InexistentItem)
+    {
+      return false;
+    }
+    else
+    {
+      ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(error);
+    }
+  }
   
 
   OrthancConfiguration::OrthancConfiguration(OrthancPluginContext* context) : 
@@ -358,7 +373,7 @@ namespace OrthancPlugins
     if (str.GetContent() == NULL)
     {
       OrthancPluginLogError(context, "Cannot access the Orthanc configuration");
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_InternalError);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
     }
 
     str.ToJson(configuration_);
@@ -366,7 +381,7 @@ namespace OrthancPlugins
     if (configuration_.type() != Json::objectValue)
     {
       OrthancPluginLogError(context, "Unable to read the Orthanc configuration");
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_InternalError);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
     }
   }
 
@@ -375,7 +390,7 @@ namespace OrthancPlugins
   {
     if (context_ == NULL)
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_Plugin);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(Plugin);
     }
     else
     {
@@ -428,7 +443,7 @@ namespace OrthancPlugins
           OrthancPluginLogError(context_, s.c_str());
         }
 
-        ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+        ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
       }
 
       target.configuration_ = configuration_[key];
@@ -454,7 +469,7 @@ namespace OrthancPlugins
         OrthancPluginLogError(context_, s.c_str());
       }
 
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
     }
 
     target = configuration_[key].asString();
@@ -489,7 +504,7 @@ namespace OrthancPlugins
           OrthancPluginLogError(context_, s.c_str());
         }
 
-        ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+        ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
     }
   }
 
@@ -511,7 +526,7 @@ namespace OrthancPlugins
         OrthancPluginLogError(context_, s.c_str());
       }
 
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
     }
     else
     {
@@ -539,7 +554,7 @@ namespace OrthancPlugins
         OrthancPluginLogError(context_, s.c_str());
       }
 
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
     }
 
     target = configuration_[key].asBool();
@@ -578,7 +593,95 @@ namespace OrthancPlugins
           OrthancPluginLogError(context_, s.c_str());
         }
 
-        ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+        ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
+    }
+  }
+
+
+  bool OrthancConfiguration::LookupListOfStrings(std::list<std::string>& target,
+                                                 const std::string& key,
+                                                 bool allowSingleString) const
+  {
+    assert(configuration_.type() == Json::objectValue);
+
+    target.clear();
+
+    if (!configuration_.isMember(key))
+    {
+      return false;
+    }
+
+    switch (configuration_[key].type())
+    {
+      case Json::arrayValue:
+      {
+        bool ok = true;
+    
+        for (Json::Value::ArrayIndex i = 0; ok && i < configuration_[key].size(); i++)
+        {
+          if (configuration_[key][i].type() == Json::stringValue)
+          {
+            target.push_back(configuration_[key][i].asString());
+          }
+          else
+          {
+            ok = false;
+          }
+        }
+
+        if (ok)
+        {
+          return true;
+        }
+
+        break;
+      }
+
+      case Json::stringValue:
+        if (allowSingleString)
+        {
+          target.push_back(configuration_[key].asString());
+          return true;
+        }
+
+        break;
+
+      default:
+        break;
+    }
+
+    if (context_ != NULL)
+    {
+      std::string s = ("The configuration option \"" + GetPath(key) +
+                       "\" is not a list of strings as expected");
+      OrthancPluginLogError(context_, s.c_str());
+    }
+
+    ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
+  }
+
+
+  bool OrthancConfiguration::LookupSetOfStrings(std::set<std::string>& target,
+                                                const std::string& key,
+                                                bool allowSingleString) const
+  {
+    std::list<std::string> lst;
+
+    if (LookupListOfStrings(lst, key, allowSingleString))
+    {
+      target.clear();
+
+      for (std::list<std::string>::const_iterator
+             it = lst.begin(); it != lst.end(); ++it)
+      {
+        target.insert(*it);
+      }
+
+      return true;
+    }
+    else
+    {
+      return false;
     }
   }
 
@@ -673,7 +776,7 @@ namespace OrthancPlugins
     if (image_ == NULL)
     {
       OrthancPluginLogError(context_, "Trying to access a NULL image");
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_ParameterOutOfRange);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange);
     }
   }
 
@@ -684,7 +787,7 @@ namespace OrthancPlugins
   {
     if (context == NULL)
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_ParameterOutOfRange);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange);
     }
   }
 
@@ -696,7 +799,7 @@ namespace OrthancPlugins
   {
     if (context == NULL)
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_ParameterOutOfRange);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange);
     }
   }
   
@@ -709,7 +812,7 @@ namespace OrthancPlugins
   {
     if (context == NULL)
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_ParameterOutOfRange);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange);
     }
     else
     {
@@ -726,7 +829,7 @@ namespace OrthancPlugins
     if (image_ == NULL)
     {
       OrthancPluginLogError(context_, "Cannot uncompress a PNG image");
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_ParameterOutOfRange);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange);
     }
   }
 
@@ -739,7 +842,7 @@ namespace OrthancPlugins
     if (image_ == NULL)
     {
       OrthancPluginLogError(context_, "Cannot uncompress a JPEG image");
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_ParameterOutOfRange);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange);
     }
   }
 
@@ -753,7 +856,7 @@ namespace OrthancPlugins
     if (image_ == NULL)
     {
       OrthancPluginLogError(context_, "Cannot uncompress a DICOM image");
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_ParameterOutOfRange);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange);
     }
   }
 
@@ -835,6 +938,8 @@ namespace OrthancPlugins
   }
 
 
+
+#if HAS_ORTHANC_PLUGIN_FIND_MATCHER == 1
   FindMatcher::FindMatcher(OrthancPluginContext*              context,
                            const OrthancPluginWorklistQuery*  worklist) :
     context_(context),
@@ -843,7 +948,7 @@ namespace OrthancPlugins
   {
     if (worklist_ == NULL)
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_ParameterOutOfRange);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(ParameterOutOfRange);
     }
   }
 
@@ -858,7 +963,7 @@ namespace OrthancPlugins
     matcher_ = OrthancPluginCreateFindMatcher(context_, query, size);
     if (matcher_ == NULL)
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_InternalError);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
     }
   }
 
@@ -890,7 +995,7 @@ namespace OrthancPlugins
     }
     else
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_InternalError);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
     }
 
     if (result == 0)
@@ -903,10 +1008,11 @@ namespace OrthancPlugins
     }
     else
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_InternalError);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(InternalError);
     }
   }
 
+#endif /* HAS_ORTHANC_PLUGIN_FIND_MATCHER == 1 */
 
 
   bool RestApiGet(Json::Value& result,
@@ -1015,20 +1121,25 @@ namespace OrthancPlugins
     }
     else
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(error);
+      ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(error);
     }
   }
 
 
-  static void ReportIncompatibleVersion(OrthancPluginContext* context,
-                                        unsigned int major,
-                                        unsigned int minor,
-                                        unsigned int revision)
+  void ReportMinimalOrthancVersion(OrthancPluginContext* context,
+                                   unsigned int major,
+                                   unsigned int minor,
+                                   unsigned int revision)
   {
-    char buf[128];
-    sprintf(buf, "Your version of the Orthanc core (%s) is too old to run this plugin (%d.%d.%d is required)",
-            context->orthancVersion, major, minor, revision);
-    OrthancPluginLogError(context, buf);
+    std::string s = ("Your version of the Orthanc core (" +
+                     std::string(context->orthancVersion) +
+                     ") is too old to run this plugin (version " +
+                     boost::lexical_cast<std::string>(major) + "." +
+                     boost::lexical_cast<std::string>(minor) + "." +
+                     boost::lexical_cast<std::string>(revision) + 
+                     " is required)");
+    
+    OrthancPluginLogError(context, s.c_str());
   }
 
 
@@ -1078,7 +1189,6 @@ namespace OrthancPlugins
 
     if (a < major)
     {
-      ReportIncompatibleVersion(context, major, minor, revision);
       return false;
     }
 
@@ -1093,7 +1203,6 @@ namespace OrthancPlugins
 
     if (b < minor)
     {
-      ReportIncompatibleVersion(context, major, minor, revision);
       return false;
     }
 
@@ -1106,7 +1215,6 @@ namespace OrthancPlugins
     }
     else
     {
-      ReportIncompatibleVersion(context, major, minor, revision);
       return false;
     }
   }
diff --git a/Plugins/Samples/Common/OrthancPluginCppWrapper.h b/Plugins/Samples/Common/OrthancPluginCppWrapper.h
index bbb69e8..4f8c1df 100644
--- a/Plugins/Samples/Common/OrthancPluginCppWrapper.h
+++ b/Plugins/Samples/Common/OrthancPluginCppWrapper.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -32,21 +33,30 @@
 
 #pragma once
 
+#include "OrthancPluginException.h"
+
 #include <orthanc/OrthancCPlugin.h>
 #include <boost/noncopyable.hpp>
 #include <boost/lexical_cast.hpp>
 #include <json/value.h>
+#include <list>
+#include <set>
 
-#if !defined(HAS_ORTHANC_EXCEPTION)
-#  error The macro HAS_ORTHANC_EXCEPTION must be defined
-#endif
 
 
-#if HAS_ORTHANC_EXCEPTION == 1
-#  include "../../../Core/OrthancException.h"
-#  define ORTHANC_PLUGINS_THROW_EXCEPTION(code)  throw ::Orthanc::OrthancException(static_cast<Orthanc::ErrorCode>(code))
+#define ORTHANC_PLUGINS_VERSION_IS_ABOVE(major, minor, revision) \
+  (ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER > major ||               \
+   (ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER == major &&             \
+    (ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER > minor ||             \
+     (ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER == minor &&           \
+      ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER >= revision))))
+  
+
+#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 2, 0)
+// The "OrthancPluginFindMatcher()" primitive was introduced in Orthanc 1.2.0
+#  define HAS_ORTHANC_PLUGIN_FIND_MATCHER  1
 #else
-#  define ORTHANC_PLUGINS_THROW_EXCEPTION(code)  throw ::OrthancPlugins::PluginException(code)
+#  define HAS_ORTHANC_PLUGIN_FIND_MATCHER  0
 #endif
 
 
@@ -57,35 +67,6 @@ namespace OrthancPlugins
                                 const char* url,
                                 const OrthancPluginHttpRequest* request);
 
-  const char* GetErrorDescription(OrthancPluginContext* context,
-                                  OrthancPluginErrorCode code);
-
-#if HAS_ORTHANC_EXCEPTION == 0
-  class PluginException
-  {
-  private:
-    OrthancPluginErrorCode  code_;
-
-  public:
-    PluginException(OrthancPluginErrorCode code) : code_(code)
-    {
-    }
-
-    OrthancPluginErrorCode GetErrorCode() const
-    {
-      return code_;
-    }
-
-    const char* What(OrthancPluginContext* context) const
-    {
-      return ::OrthancPlugins::GetErrorDescription(context, code_);
-    }
-
-    static void Check(OrthancPluginErrorCode code);
-  };
-#endif
-
-
   class MemoryBuffer : public boost::noncopyable
   {
   private:
@@ -94,6 +75,8 @@ namespace OrthancPlugins
 
     void Check(OrthancPluginErrorCode code);
 
+    bool CheckHttp(OrthancPluginErrorCode code);
+
   public:
     MemoryBuffer(OrthancPluginContext* context);
 
@@ -179,6 +162,20 @@ namespace OrthancPlugins
                      OrthancPluginDicomToJsonFormat format,
                      OrthancPluginDicomToJsonFlags flags,
                      uint32_t maxStringLength);
+
+    bool HttpGet(const std::string& url,
+                 const std::string& username,
+                 const std::string& password);
+ 
+    bool HttpPost(const std::string& url,
+                  const std::string& body,
+                  const std::string& username,
+                  const std::string& password);
+ 
+    bool HttpPut(const std::string& url,
+                 const std::string& body,
+                 const std::string& username,
+                 const std::string& password);
   };
 
 
@@ -260,6 +257,14 @@ namespace OrthancPlugins
     bool LookupFloatValue(float& target,
                           const std::string& key) const;
 
+    bool LookupListOfStrings(std::list<std::string>& target,
+                             const std::string& key,
+                             bool allowSingleString) const;
+
+    bool LookupSetOfStrings(std::set<std::string>& target,
+                            const std::string& key,
+                            bool allowSingleString) const;
+
     std::string GetStringValue(const std::string& key,
                                const std::string& defaultValue) const;
 
@@ -334,6 +339,7 @@ namespace OrthancPlugins
   };
 
 
+#if HAS_ORTHANC_PLUGIN_FIND_MATCHER == 1
   class FindMatcher : public boost::noncopyable
   {
   private:
@@ -372,6 +378,7 @@ namespace OrthancPlugins
       return IsMatch(dicom.GetData(), dicom.GetSize());
     }
   };
+#endif
 
 
   bool RestApiGet(Json::Value& result,
@@ -429,6 +436,11 @@ namespace OrthancPlugins
                      const std::string& uri,
                      bool applyPlugins);
 
+  bool HttpDelete(OrthancPluginContext* context,
+                  const std::string& url,
+                  const std::string& username,
+                  const std::string& password);
+
   inline void LogError(OrthancPluginContext* context,
                        const std::string& message)
   {
@@ -456,6 +468,11 @@ namespace OrthancPlugins
     }
   }
 
+  void ReportMinimalOrthancVersion(OrthancPluginContext* context,
+                                   unsigned int major,
+                                   unsigned int minor,
+                                   unsigned int revision);
+  
   bool CheckMinimalOrthancVersion(OrthancPluginContext* context,
                                   unsigned int major,
                                   unsigned int minor,
@@ -474,17 +491,10 @@ namespace OrthancPlugins
         Callback(output, url, request);
         return OrthancPluginErrorCode_Success;
       }
-#if HAS_ORTHANC_EXCEPTION == 1
-      catch (Orthanc::OrthancException& e)
+      catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e)
       {
         return static_cast<OrthancPluginErrorCode>(e.GetErrorCode());
       }
-#else
-      catch (OrthancPlugins::PluginException& e)
-      {
-        return e.GetErrorCode();
-      }
-#endif
       catch (boost::bad_lexical_cast&)
       {
         return OrthancPluginErrorCode_BadFileFormat;
diff --git a/Plugins/Samples/Common/OrthancPluginException.h b/Plugins/Samples/Common/OrthancPluginException.h
new file mode 100644
index 0000000..e549a26
--- /dev/null
+++ b/Plugins/Samples/Common/OrthancPluginException.h
@@ -0,0 +1,101 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * In addition, as a special exception, the copyright holders of this
+ * program give permission to link the code of its release with the
+ * OpenSSL project's "OpenSSL" library (or with modified versions of it
+ * that use the same license as the "OpenSSL" library), and distribute
+ * the linked executables. You must obey the GNU General Public License
+ * in all respects for all of the code used other than "OpenSSL". If you
+ * modify file(s) with this exception, you may extend this exception to
+ * your version of the file(s), but you are not obligated to do so. If
+ * you do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source files
+ * in the program, then also delete it here.
+ * 
+ * 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#if !defined(HAS_ORTHANC_EXCEPTION)
+#  error The macro HAS_ORTHANC_EXCEPTION must be defined
+#endif
+
+
+#if HAS_ORTHANC_EXCEPTION == 1
+#  include "../../../Core/OrthancException.h"
+#  define ORTHANC_PLUGINS_ERROR_ENUMERATION     ::Orthanc::ErrorCode
+#  define ORTHANC_PLUGINS_EXCEPTION_CLASS       ::Orthanc::OrthancException
+#  define ORTHANC_PLUGINS_GET_ERROR_CODE(code)  ::Orthanc::ErrorCode_ ## code
+#else
+#  include <orthanc/OrthancCPlugin.h>
+#  define ORTHANC_PLUGINS_ERROR_ENUMERATION     ::OrthancPluginErrorCode
+#  define ORTHANC_PLUGINS_EXCEPTION_CLASS       ::OrthancPlugins::PluginException
+#  define ORTHANC_PLUGINS_GET_ERROR_CODE(code)  ::OrthancPluginErrorCode_ ## code
+#endif
+
+
+#define ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code)                   \
+  throw ORTHANC_PLUGINS_EXCEPTION_CLASS(static_cast<ORTHANC_PLUGINS_ERROR_ENUMERATION>(code));
+
+
+#define ORTHANC_PLUGINS_THROW_EXCEPTION(code)                           \
+  throw ORTHANC_PLUGINS_EXCEPTION_CLASS(ORTHANC_PLUGINS_GET_ERROR_CODE(code));
+                                                  
+
+#define ORTHANC_PLUGINS_CHECK_ERROR(code)                           \
+  if (code != ORTHANC_PLUGINS_GET_ERROR_CODE(Success))              \
+  {                                                                 \
+    ORTHANC_PLUGINS_THROW_EXCEPTION(code);                          \
+  }
+
+
+namespace OrthancPlugins
+{
+#if HAS_ORTHANC_EXCEPTION == 0
+  class PluginException
+  {
+  private:
+    OrthancPluginErrorCode  code_;
+
+  public:
+    explicit PluginException(OrthancPluginErrorCode code) : code_(code)
+    {
+    }
+
+    OrthancPluginErrorCode GetErrorCode() const
+    {
+      return code_;
+    }
+
+    const char* What(OrthancPluginContext* context) const
+    {
+      const char* description = OrthancPluginGetErrorDescription(context, code_);
+      if (description)
+      {
+        return description;
+      }
+      else
+      {
+        return "No description available";
+      }
+    }
+  };
+#endif
+}
diff --git a/Plugins/Samples/Common/SimplifiedOrthancDataset.cpp b/Plugins/Samples/Common/SimplifiedOrthancDataset.cpp
index 1fa2bea..d7c79ee 100644
--- a/Plugins/Samples/Common/SimplifiedOrthancDataset.cpp
+++ b/Plugins/Samples/Common/SimplifiedOrthancDataset.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -32,7 +33,7 @@
 
 #include "SimplifiedOrthancDataset.h"
 
-#include "OrthancPluginCppWrapper.h"
+#include "OrthancPluginException.h"
 
 namespace OrthancPlugins
 {
@@ -45,7 +46,7 @@ namespace OrthancPlugins
       const char* name = path.GetPrefixTag(depth).GetName();
       if (content->type() != Json::objectValue)
       {
-        ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+        ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
       }
 
       if (!content->isMember(name))
@@ -56,7 +57,7 @@ namespace OrthancPlugins
       const Json::Value& sequence = (*content) [name];
       if (sequence.type() != Json::arrayValue)
       {
-        ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+        ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
       }
 
       size_t index = path.GetPrefixIndex(depth);
@@ -74,7 +75,7 @@ namespace OrthancPlugins
 
     if (content->type() != Json::objectValue)
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
     }
     if (!content->isMember(name))
     {
@@ -91,7 +92,7 @@ namespace OrthancPlugins
   {
     if (root_.type() != Json::objectValue)
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
     }
   }
 
@@ -122,7 +123,7 @@ namespace OrthancPlugins
     }
     else if (value->type() != Json::stringValue)
     {
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
     }
     else
     {
@@ -145,7 +146,7 @@ namespace OrthancPlugins
     else if (sequence->type() != Json::arrayValue)
     {
       // Not a sequence
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
     }
     else
     {
diff --git a/Plugins/Samples/Common/SimplifiedOrthancDataset.h b/Plugins/Samples/Common/SimplifiedOrthancDataset.h
index a71e1e0..a757e66 100644
--- a/Plugins/Samples/Common/SimplifiedOrthancDataset.h
+++ b/Plugins/Samples/Common/SimplifiedOrthancDataset.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/CustomImageDecoder/Plugin.cpp b/Plugins/Samples/CustomImageDecoder/Plugin.cpp
index 5dc10ef..83b4aa5 100644
--- a/Plugins/Samples/CustomImageDecoder/Plugin.cpp
+++ b/Plugins/Samples/CustomImageDecoder/Plugin.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/DatabasePlugin/Database.cpp b/Plugins/Samples/DatabasePlugin/Database.cpp
index 4c48944..c97bd89 100644
--- a/Plugins/Samples/DatabasePlugin/Database.cpp
+++ b/Plugins/Samples/DatabasePlugin/Database.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/DatabasePlugin/Database.h b/Plugins/Samples/DatabasePlugin/Database.h
index 26632e6..b92875b 100644
--- a/Plugins/Samples/DatabasePlugin/Database.h
+++ b/Plugins/Samples/DatabasePlugin/Database.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/DatabasePlugin/Plugin.cpp b/Plugins/Samples/DatabasePlugin/Plugin.cpp
index 88509d2..e0ac790 100644
--- a/Plugins/Samples/DatabasePlugin/Plugin.cpp
+++ b/Plugins/Samples/DatabasePlugin/Plugin.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/GdcmDecoder/GdcmDecoderCache.cpp b/Plugins/Samples/GdcmDecoder/GdcmDecoderCache.cpp
index 6f608e2..d9d9a57 100644
--- a/Plugins/Samples/GdcmDecoder/GdcmDecoderCache.cpp
+++ b/Plugins/Samples/GdcmDecoder/GdcmDecoderCache.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/GdcmDecoder/GdcmDecoderCache.h b/Plugins/Samples/GdcmDecoder/GdcmDecoderCache.h
index f606305..44e12c3 100644
--- a/Plugins/Samples/GdcmDecoder/GdcmDecoderCache.h
+++ b/Plugins/Samples/GdcmDecoder/GdcmDecoderCache.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.cpp b/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.cpp
index 892a175..9ebb67b 100644
--- a/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.cpp
+++ b/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.h b/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.h
index 815b794..ee80750 100644
--- a/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.h
+++ b/Plugins/Samples/GdcmDecoder/GdcmImageDecoder.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/GdcmDecoder/OrthancImageWrapper.cpp b/Plugins/Samples/GdcmDecoder/OrthancImageWrapper.cpp
index 12900dd..520a322 100644
--- a/Plugins/Samples/GdcmDecoder/OrthancImageWrapper.cpp
+++ b/Plugins/Samples/GdcmDecoder/OrthancImageWrapper.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/GdcmDecoder/OrthancImageWrapper.h b/Plugins/Samples/GdcmDecoder/OrthancImageWrapper.h
index c3f7619..7a49086 100644
--- a/Plugins/Samples/GdcmDecoder/OrthancImageWrapper.h
+++ b/Plugins/Samples/GdcmDecoder/OrthancImageWrapper.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/GdcmDecoder/Plugin.cpp b/Plugins/Samples/GdcmDecoder/Plugin.cpp
index 2665e46..84c56e7 100644
--- a/Plugins/Samples/GdcmDecoder/Plugin.cpp
+++ b/Plugins/Samples/GdcmDecoder/Plugin.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/ModalityWorklists/Plugin.cpp b/Plugins/Samples/ModalityWorklists/Plugin.cpp
index 8aebfa8..7d2c442 100644
--- a/Plugins/Samples/ModalityWorklists/Plugin.cpp
+++ b/Plugins/Samples/ModalityWorklists/Plugin.cpp
@@ -2,12 +2,13 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU 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
@@ -29,12 +30,12 @@
 
 static OrthancPluginContext* context_ = NULL;
 static std::string folder_;
-
+static bool filterIssuerAet_ = false;
 
 /**
  * This is the main function for matching a DICOM worklist against a query.
  **/
-static void  MatchWorklist(OrthancPluginWorklistAnswers*      answers,
+static bool MatchWorklist(OrthancPluginWorklistAnswers*      answers,
                            const OrthancPluginWorklistQuery*  query,
                            const OrthancPlugins::FindMatcher& matcher,
                            const std::string& path)
@@ -51,14 +52,18 @@ static void  MatchWorklist(OrthancPluginWorklistAnswers*      answers,
     if (code != OrthancPluginErrorCode_Success)
     {
       OrthancPlugins::LogError(context_, "Error while adding an answer to a worklist request");
-      ORTHANC_PLUGINS_THROW_EXCEPTION(code);
+      ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code);
     }
+
+    return true;
   }
+
+  return false;
 }
 
 
 static OrthancPlugins::FindMatcher* CreateMatcher(const OrthancPluginWorklistQuery* query,
-                                                  const char*                       remoteAet)
+                                                  const char*                       issuerAet)
 {
   // Extract the DICOM instance underlying the C-Find query
   OrthancPlugins::MemoryBuffer dicom(context_);
@@ -66,81 +71,85 @@ static OrthancPlugins::FindMatcher* CreateMatcher(const OrthancPluginWorklistQue
 
   // Convert the DICOM as JSON, and dump it to the user in "--verbose" mode
   Json::Value json;
-  dicom.DicomToJson(json, OrthancPluginDicomToJsonFormat_Short, 
+  dicom.DicomToJson(json, OrthancPluginDicomToJsonFormat_Short,
                     static_cast<OrthancPluginDicomToJsonFlags>(0), 0);
-  
-  OrthancPlugins::LogInfo(context_, "Received worklist query from remote modality " + 
-                          std::string(remoteAet) + ":\n" + json.toStyledString());
 
-#if 1
-  return new OrthancPlugins::FindMatcher(context_, query);
+  OrthancPlugins::LogInfo(context_, "Received worklist query from remote modality " +
+                          std::string(issuerAet) + ":\n" + json.toStyledString());
 
-#else
-  // Alternative sample showing how to fine-tune an incoming C-Find
-  // request, before matching it against the worklist database. The
-  // code below will restrict the original DICOM request by requesting
-  // the ScheduledStationAETitle to correspond to the AET of the
-  // issuer. This code will make the integration test "test_other_aet"
-  // succeed (cf. the orthanc-tests repository).
-
-  static const char* SCHEDULED_PROCEDURE_STEP_SEQUENCE = "0040,0100";
-  static const char* SCHEDULED_STATION_AETITLE = "0040,0001";
-
-  if (!json.isMember(SCHEDULED_PROCEDURE_STEP_SEQUENCE))
+  if (!filterIssuerAet_)
   {
-    // Create a ScheduledProcedureStepSequence sequence, with one empty element
-    json[SCHEDULED_PROCEDURE_STEP_SEQUENCE] = Json::arrayValue;
-    json[SCHEDULED_PROCEDURE_STEP_SEQUENCE].append(Json::objectValue);
+    return new OrthancPlugins::FindMatcher(context_, query);
   }
+  else
+  {
+    // Alternative sample showing how to fine-tune an incoming C-Find
+    // request, before matching it against the worklist database. The
+    // code below will restrict the original DICOM request by
+    // requesting the ScheduledStationAETitle to correspond to the AET
+    // of the C-Find issuer. This code will make the integration test
+    // "test_filter_issuer_aet" succeed (cf. the orthanc-tests repository).
 
-  Json::Value& v = json[SCHEDULED_PROCEDURE_STEP_SEQUENCE];
+    static const char* SCHEDULED_PROCEDURE_STEP_SEQUENCE = "0040,0100";
+    static const char* SCHEDULED_STATION_AETITLE = "0040,0001";
 
-  if (v.type() != Json::arrayValue ||
-      v.size() != 1 ||
-      v[0].type() != Json::objectValue)
-  {
-    ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
-  }
+    if (!json.isMember(SCHEDULED_PROCEDURE_STEP_SEQUENCE))
+    {
+      // Create a ScheduledProcedureStepSequence sequence, with one empty element
+      json[SCHEDULED_PROCEDURE_STEP_SEQUENCE] = Json::arrayValue;
+      json[SCHEDULED_PROCEDURE_STEP_SEQUENCE].append(Json::objectValue);
+    }
 
-  // Set the ScheduledStationAETitle if none was provided
-  if (!v[0].isMember(SCHEDULED_STATION_AETITLE) ||
-      v[0].type() != Json::stringValue ||
-      v[0][SCHEDULED_STATION_AETITLE].asString().size() == 0 ||
-      v[0][SCHEDULED_STATION_AETITLE].asString() == "*")
-  {
-    v[0][SCHEDULED_STATION_AETITLE] = remoteAet;
-  }
+    Json::Value& v = json[SCHEDULED_PROCEDURE_STEP_SEQUENCE];
 
-  if (json.isMember("0010,21c0") &&
-      json["0010,21c0"].asString().size() == 0)
-  {
-    json.removeMember("0010,21c0");
-  }
+    if (v.type() != Json::arrayValue ||
+        v.size() != 1 ||
+        v[0].type() != Json::objectValue)
+    {
+      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
+    }
 
-  // Encode the modified JSON as a DICOM instance, then convert it to a C-Find matcher
-  OrthancPlugins::MemoryBuffer modified(context_);
-  modified.CreateDicom(json, OrthancPluginCreateDicomFlags_None);
-  return new OrthancPlugins::FindMatcher(context_, modified);
-#endif
+    // Set the ScheduledStationAETitle if none was provided
+    if (!v[0].isMember(SCHEDULED_STATION_AETITLE) ||
+        v[0].type() != Json::stringValue ||
+        v[0][SCHEDULED_STATION_AETITLE].asString().size() == 0 ||
+        v[0][SCHEDULED_STATION_AETITLE].asString() == "*")
+    {
+      v[0][SCHEDULED_STATION_AETITLE] = issuerAet;
+    }
+
+    if (json.isMember("0010,21c0") &&
+        json["0010,21c0"].asString().size() == 0)
+    {
+      json.removeMember("0010,21c0");
+    }
+
+    // Encode the modified JSON as a DICOM instance, then convert it to a C-Find matcher
+    OrthancPlugins::MemoryBuffer modified(context_);
+    modified.CreateDicom(json, OrthancPluginCreateDicomFlags_None);
+    return new OrthancPlugins::FindMatcher(context_, modified);
+  }
 }
 
 
 
 OrthancPluginErrorCode Callback(OrthancPluginWorklistAnswers*     answers,
                                 const OrthancPluginWorklistQuery* query,
-                                const char*                       remoteAet,
+                                const char*                       issuerAet,
                                 const char*                       calledAet)
 {
   try
   {
     // Construct an object to match the worklists in the database against the C-Find query
-    std::auto_ptr<OrthancPlugins::FindMatcher> matcher(CreateMatcher(query, remoteAet));
+    std::auto_ptr<OrthancPlugins::FindMatcher> matcher(CreateMatcher(query, issuerAet));
 
     // Loop over the regular files in the database folder
-    namespace fs = boost::filesystem;  
+    namespace fs = boost::filesystem;
 
     fs::path source(folder_);
     fs::directory_iterator end;
+    int parsedFilesCount = 0;
+    int matchedWorklistCount = 0;
 
     try
     {
@@ -156,11 +165,21 @@ OrthancPluginErrorCode Callback(OrthancPluginWorklistAnswers*     answers,
 
           if (extension == ".wl")
           {
+            parsedFilesCount++;
             // We found a worklist (i.e. a DICOM find with extension ".wl"), match it against the query
-            MatchWorklist(answers, query, *matcher, it->path().string());
+            if (MatchWorklist(answers, query, *matcher, it->path().string()))
+            {
+              OrthancPlugins::LogInfo(context_, "Worklist matched: " + it->path().string());
+              matchedWorklistCount++;
+            }
           }
         }
       }
+
+      std::ostringstream message;
+      message << "Worklist C-Find: parsed " << parsedFilesCount << " files, found " << matchedWorklistCount << " match(es)";
+      OrthancPlugins::LogInfo(context_, message.str());
+
     }
     catch (fs::filesystem_error&)
     {
@@ -189,13 +208,10 @@ extern "C"
     /* Check the version of the Orthanc core */
     if (OrthancPluginCheckVersion(c) == 0)
     {
-      char info[1024];
-      sprintf(info, "Your version of Orthanc (%s) must be above %d.%d.%d to run this plugin",
-              context_->orthancVersion,
-              ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER,
-              ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER,
-              ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER);
-      OrthancPluginLogError(context_, info);
+      OrthancPlugins::ReportMinimalOrthancVersion(context_,
+                                                  ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER,
+                                                  ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER,
+                                                  ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER);
       return -1;
     }
 
@@ -220,10 +236,12 @@ extern "C"
         OrthancPlugins::LogError(context_, "The configuration option \"Worklists.Database\" must contain a path");
         return -1;
       }
+
+      filterIssuerAet_ = worklists.GetBooleanValue("FilterIssuerAet", false);
     }
     else
     {
-      OrthancPlugins::LogWarning(context_, "Worklists server is disabled by the configuration file");
+      OrthancPlugins::LogWarning(context_, "Worklist server is disabled by the configuration file");
     }
 
     return 0;
diff --git a/Plugins/Samples/ServeFolders/Plugin.cpp b/Plugins/Samples/ServeFolders/Plugin.cpp
index 6e8c64e..8a444f2 100644
--- a/Plugins/Samples/ServeFolders/Plugin.cpp
+++ b/Plugins/Samples/ServeFolders/Plugin.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -204,7 +205,7 @@ void ServeFolder(OrthancPluginRestOutput* output,
       }
       catch (...)
       {
-        ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_InexistentFile);
+        ORTHANC_PLUGINS_THROW_EXCEPTION(InexistentFile);
       }
 
       boost::posix_time::ptime lastModification = boost::posix_time::from_time_t(fs::last_write_time(path));
@@ -257,7 +258,7 @@ static void ConfigureFolders(const Json::Value& folders)
   if (folders.type() != Json::objectValue)
   {
     OrthancPlugins::LogError(context_, "The list of folders to be served is badly formatted (must be a JSON object)");
-    ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+    ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
   }
 
   Json::Value::Members members = folders.getMemberNames();
@@ -270,7 +271,7 @@ static void ConfigureFolders(const Json::Value& folders)
     {
       OrthancPlugins::LogError(context_, "The folder to be served \"" + *it + 
                                "\" must be associated with a string value (its mapped URI)");
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
     }
 
     std::string baseUri = *it;
@@ -291,7 +292,7 @@ static void ConfigureFolders(const Json::Value& folders)
     if (baseUri.empty())
     {
       OrthancPlugins::LogError(context_, "The URI of a folder to be served cannot be empty");
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
     }
 
     // Check whether the source folder exists and is indeed a directory
@@ -299,7 +300,7 @@ static void ConfigureFolders(const Json::Value& folders)
     if (!boost::filesystem::is_directory(folder))
     {
       OrthancPlugins::LogError(context_, "Trying and serve an inexistent folder: " + folder);
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_InexistentFile);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(InexistentFile);
     }
 
     folders_[baseUri] = folder;
@@ -318,7 +319,7 @@ static void ConfigureExtensions(const Json::Value& extensions)
   if (extensions.type() != Json::objectValue)
   {
     OrthancPlugins::LogError(context_, "The list of extensions is badly formatted (must be a JSON object)");
-    ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+    ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
   }
 
   Json::Value::Members members = extensions.getMemberNames();
@@ -330,7 +331,7 @@ static void ConfigureExtensions(const Json::Value& extensions)
     {
       OrthancPlugins::LogError(context_, "The file extension \"" + *it + 
                                "\" must be associated with a string value (its MIME type)");
-      ORTHANC_PLUGINS_THROW_EXCEPTION(OrthancPluginErrorCode_BadFileFormat);
+      ORTHANC_PLUGINS_THROW_EXCEPTION(BadFileFormat);
     }
 
     const std::string& mime = extensions[*it].asString();
@@ -415,13 +416,10 @@ extern "C"
     /* Check the version of the Orthanc core */
     if (OrthancPluginCheckVersion(context_) == 0)
     {
-      char info[1024];
-      sprintf(info, "Your version of Orthanc (%s) must be above %d.%d.%d to run this plugin",
-              context_->orthancVersion,
-              ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER,
-              ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER,
-              ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER);
-      OrthancPluginLogError(context_, info);
+      OrthancPlugins::ReportMinimalOrthancVersion(context_, 
+                                                  ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER,
+                                                  ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER,
+                                                  ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER);
       return -1;
     }
 
diff --git a/Plugins/Samples/StorageArea/Plugin.cpp b/Plugins/Samples/StorageArea/Plugin.cpp
index 1d201c1..8e2296c 100644
--- a/Plugins/Samples/StorageArea/Plugin.cpp
+++ b/Plugins/Samples/StorageArea/Plugin.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/WebSkeleton/Configuration.h b/Plugins/Samples/WebSkeleton/Configuration.h
index c0bdb9e..b4b9696 100644
--- a/Plugins/Samples/WebSkeleton/Configuration.h
+++ b/Plugins/Samples/WebSkeleton/Configuration.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/WebSkeleton/Framework/EmbedResources.py b/Plugins/Samples/WebSkeleton/Framework/EmbedResources.py
index 04c1206..54ea05c 100644
--- a/Plugins/Samples/WebSkeleton/Framework/EmbedResources.py
+++ b/Plugins/Samples/WebSkeleton/Framework/EmbedResources.py
@@ -1,6 +1,7 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017 Osimis, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/WebSkeleton/Framework/Framework.cmake b/Plugins/Samples/WebSkeleton/Framework/Framework.cmake
index 5aa4baf..1c66934 100644
--- a/Plugins/Samples/WebSkeleton/Framework/Framework.cmake
+++ b/Plugins/Samples/WebSkeleton/Framework/Framework.cmake
@@ -1,6 +1,7 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017 Osimis, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
diff --git a/Plugins/Samples/WebSkeleton/Framework/Plugin.cpp b/Plugins/Samples/WebSkeleton/Framework/Plugin.cpp
index c1ff3d9..21cc90e 100644
--- a/Plugins/Samples/WebSkeleton/Framework/Plugin.cpp
+++ b/Plugins/Samples/WebSkeleton/Framework/Plugin.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Resources/CMake/BoostConfiguration.cmake b/Resources/CMake/BoostConfiguration.cmake
index fa54bf5..59728b5 100644
--- a/Resources/CMake/BoostConfiguration.cmake
+++ b/Resources/CMake/BoostConfiguration.cmake
@@ -39,10 +39,10 @@ endif()
 
 
 if (BOOST_STATIC)
-  # Parameters for Boost 1.60.0
-  set(BOOST_NAME boost_1_60_0)
-  set(BOOST_BCP_SUFFIX bcpdigest-1.0.1)
-  set(BOOST_MD5 "a789f8ec2056ad1c2d5f0cb64687cc7b")
+  # Parameters for Boost 1.64.0
+  set(BOOST_NAME boost_1_64_0)
+  set(BOOST_BCP_SUFFIX bcpdigest-1.3.0)
+  set(BOOST_MD5 "ecb266cf46adcc7f695ad12685871174")
   set(BOOST_URL "http://www.orthanc-server.com/downloads/third-party/${BOOST_NAME}_${BOOST_BCP_SUFFIX}.tar.gz")
   set(BOOST_FILESYSTEM_SOURCES_DIR "${BOOST_NAME}/libs/filesystem/src") 
   set(BOOST_SOURCES_DIR ${CMAKE_BINARY_DIR}/${BOOST_NAME})
@@ -99,6 +99,13 @@ if (BOOST_STATIC)
       -DBOOST_LOCALE_NO_POSIX_BACKEND=1
       -DBOOST_LOCALE_NO_STD_BACKEND=1
       )
+
+  elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten")
+    add_definitions(
+      -DBOOST_LOCALE_NO_POSIX_BACKEND=1
+      -DBOOST_LOCALE_NO_STD_BACKEND=1
+      )
+
   else()
     message(FATAL_ERROR "Support your platform here")
   endif()
@@ -114,10 +121,15 @@ if (BOOST_STATIC)
   list(APPEND BOOST_SOURCES
     ${BOOST_REGEX_SOURCES}
     ${BOOST_SOURCES_DIR}/libs/date_time/src/gregorian/greg_month.cpp
-    ${BOOST_SOURCES_DIR}/libs/locale/src/encoding/codepage.cpp
     ${BOOST_SOURCES_DIR}/libs/system/src/error_code.cpp
     )
 
+  if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten")
+    list(APPEND BOOST_SOURCES
+      ${BOOST_SOURCES_DIR}/libs/locale/src/encoding/codepage.cpp
+      )
+  endif()
+
   if (${CMAKE_SYSTEM_NAME} STREQUAL "PNaCl" OR
       ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl32" OR
       ${CMAKE_SYSTEM_NAME} STREQUAL "NaCl64")
@@ -138,7 +150,7 @@ if (BOOST_STATIC)
       )
   endif()
 
-  if (USE_BOOST_LOCALE_BACKENDS)
+  if (USE_BOOST_LOCALE_BACKEND)
     if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" OR
         ${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" OR
         ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR
diff --git a/Resources/CMake/BoostConfiguration.sh b/Resources/CMake/BoostConfiguration.sh
index 92c98b4..2e0ca40 100755
--- a/Resources/CMake/BoostConfiguration.sh
+++ b/Resources/CMake/BoostConfiguration.sh
@@ -15,22 +15,23 @@ set -u
 ##   - Orthanc between 0.7.4 and 0.9.1: Boost 1.55.0
 ##   - Orthanc between 0.9.2 and 0.9.4: Boost 1.58.0
 ##   - Orthanc between 0.9.5 and 1.0.0: Boost 1.59.0
-##   - Orthanc >= 1.0.1: Boost 1.60.0
+##   - Orthanc between 1.1.0 and 1.2.0: Boost 1.60.0
+##   - Orthanc >= 1.3.0: Boost 1.64.0
 
-rm -rf /tmp/boost_1_60_0
-rm -rf /tmp/bcp/boost_1_60_0
+rm -rf /tmp/boost_1_64_0
+rm -rf /tmp/bcp/boost_1_64_0
 
 cd /tmp
-echo "Uncompressing the sources of Boost 1.60.0..."
-tar xfz ./boost_1_60_0.tar.gz 
+echo "Uncompressing the sources of Boost 1.64.0..."
+tar xfz ./boost_1_64_0.tar.gz 
 
 echo "Generating the subset..."
-mkdir -p /tmp/bcp/boost_1_60_0
-bcp --boost=/tmp/boost_1_60_0 thread system locale date_time filesystem math/special_functions algorithm uuid atomic iostreams program_options numeric/ublas /tmp/bcp/boost_1_60_0
+mkdir -p /tmp/bcp/boost_1_64_0
+bcp --boost=/tmp/boost_1_64_0 thread system locale date_time filesystem math/special_functions algorithm uuid atomic iostreams program_options numeric/ublas /tmp/bcp/boost_1_64_0
 cd /tmp/bcp
 
 echo "Compressing the subset..."
-tar cfz boost_1_60_0_bcpdigest-1.0.1.tar.gz boost_1_60_0
-ls -l boost_1_60_0_bcpdigest-1.0.1.tar.gz
-md5sum boost_1_60_0_bcpdigest-1.0.1.tar.gz
-readlink -f boost_1_60_0_bcpdigest-1.0.1.tar.gz
+tar cfz boost_1_64_0_bcpdigest-1.3.0.tar.gz boost_1_64_0
+ls -l boost_1_64_0_bcpdigest-1.3.0.tar.gz
+md5sum boost_1_64_0_bcpdigest-1.3.0.tar.gz
+readlink -f boost_1_64_0_bcpdigest-1.3.0.tar.gz
diff --git a/Resources/CMake/DcmtkConfiguration.cmake b/Resources/CMake/DcmtkConfiguration.cmake
index 8534a93..0d88735 100644
--- a/Resources/CMake/DcmtkConfiguration.cmake
+++ b/Resources/CMake/DcmtkConfiguration.cmake
@@ -3,21 +3,7 @@ if (NOT DEFINED ENABLE_DCMTK_NETWORKING)
 endif()
 
 if (STATIC_BUILD OR NOT USE_SYSTEM_DCMTK)
-  if (USE_DCMTK_361)
-    SET(DCMTK_VERSION_NUMBER 361)
-    SET(DCMTK_PACKAGE_VERSION "3.6.1")
-    SET(DCMTK_SOURCES_DIR ${CMAKE_BINARY_DIR}/dcmtk-3.6.1_20160216)
-    SET(DCMTK_URL "http://www.orthanc-server.com/downloads/third-party/dcmtk-3.6.1_20160216.tar.gz")
-    SET(DCMTK_MD5 "273c8a544b9fe09b8a4fb4eb51df8e52")
-    SET(DCMTK_PATCH_SPEED "${ORTHANC_ROOT}/Resources/Patches/dcmtk-3.6.1-speed.patch")
-
-    macro(DCMTK_UNSET)
-    endmacro()
-
-    set(DCMTK_BINARY_DIR ${DCMTK_SOURCES_DIR}/)
-    set(DCMTK_CMAKE_INCLUDE ${DCMTK_SOURCES_DIR}/)
-    add_definitions(-DDCMTK_INSIDE_LOG4CPLUS=1)
-  else()
+  if (USE_DCMTK_360)
     SET(DCMTK_VERSION_NUMBER 360)
     SET(DCMTK_PACKAGE_VERSION "3.6.0")
     SET(DCMTK_SOURCES_DIR ${CMAKE_BINARY_DIR}/dcmtk-3.6.0)
@@ -25,8 +11,24 @@ if (STATIC_BUILD OR NOT USE_SYSTEM_DCMTK)
     SET(DCMTK_MD5 "219ad631b82031806147e4abbfba4fa4")
     SET(DCMTK_PATCH_SPEED "${ORTHANC_ROOT}/Resources/Patches/dcmtk-3.6.0-speed.patch")
     SET(DCMTK_PATCH_MINGW64 "${ORTHANC_ROOT}/Resources/Patches/dcmtk-3.6.0-mingw64.patch")
-  endif()
+  else()
+    SET(DCMTK_VERSION_NUMBER 362)
+    SET(DCMTK_PACKAGE_VERSION "3.6.2")
+    SET(DCMTK_SOURCES_DIR ${CMAKE_BINARY_DIR}/dcmtk-3.6.2)
+    SET(DCMTK_URL "http://www.orthanc-server.com/downloads/third-party/dcmtk-3.6.2.tar.gz")
+    SET(DCMTK_MD5 "d219a4152772985191c9b89d75302d12")
+
+    macro(DCMTK_UNSET)
+    endmacro()
+
+    macro(DCMTK_UNSET_CACHE)
+    endmacro()
 
+    set(DCMTK_BINARY_DIR ${DCMTK_SOURCES_DIR}/)
+    set(DCMTK_CMAKE_INCLUDE ${DCMTK_SOURCES_DIR}/)
+    add_definitions(-DDCMTK_INSIDE_LOG4CPLUS=1)
+  endif()
+  
   if (IS_DIRECTORY "${DCMTK_SOURCES_DIR}")
     set(FirstRun OFF)
   else()
@@ -36,37 +38,65 @@ if (STATIC_BUILD OR NOT USE_SYSTEM_DCMTK)
   DownloadPackage(${DCMTK_MD5} ${DCMTK_URL} "${DCMTK_SOURCES_DIR}")
 
   
-  if (FirstRun AND
-      NOT USE_DCMTK_361)
-    if (USE_DCMTK_361_PRIVATE_DIC)
+  if (FirstRun)
+    if (USE_DCMTK_360)
       # If using DCMTK 3.6.0, backport the "private.dic" file from DCMTK
-      # 3.6.1 snapshot. This adds support for more private tags, and
-      # fixes some import problems with Philips MRI Achieva.
-      message("Using the dictionary of private tags from DCMTK 3.6.1")
-      configure_file(
-        ${ORTHANC_ROOT}/Resources/Patches/dcmtk-3.6.1-private.dic
-        ${DCMTK_SOURCES_DIR}/dcmdata/data/private.dic
-        COPYONLY)
-    else()
-      message("Using the dictionary of private tags from DCMTK 3.6.0")
-    endif()
+      # 3.6.2. This adds support for more private tags, and fixes some
+      # import problems with Philips MRI Achieva.
+      if (USE_DCMTK_362_PRIVATE_DIC)
+        message("Using the dictionary of private tags from DCMTK 3.6.2")
+        configure_file(
+          ${ORTHANC_ROOT}/Resources/Patches/dcmtk-3.6.2-private.dic
+          ${DCMTK_SOURCES_DIR}/dcmdata/data/private.dic
+          COPYONLY)
+      else()
+        message("Using the dictionary of private tags from DCMTK 3.6.0")
+      endif()
+      
+      # Patches specific to DCMTK 3.6.0
+      message("Applying patch to solve vulnerability in DCMTK 3.6.0")
+      execute_process(
+        COMMAND ${PATCH_EXECUTABLE} -p0 -N -i
+        ${ORTHANC_ROOT}/Resources/Patches/dcmtk-3.6.0-dulparse-vulnerability.patch
+        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+        RESULT_VARIABLE Failure
+        )
 
-    # Patches specific to DCMTK 3.6.0
-    execute_process(
-      COMMAND ${PATCH_EXECUTABLE} -p0 -N -i ${ORTHANC_ROOT}/Resources/Patches/dcmtk-3.6.0-dulparse-vulnerability.patch
-      WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
-      RESULT_VARIABLE Failure
-      )
+      if (Failure)
+        message(FATAL_ERROR "Error while patching a file")
+      endif()
+
+      # This patch is not needed anymore thanks to the following commit
+      # (information sent by Jorg Riesmeier on Twitter on 2017-07-19):
+      # http://git.dcmtk.org/?p=dcmtk.git;a=commit;h=8df1f5e517b8629ae09088d0935c2a8dd333c76f
+      message("Applying patch for speed in DCMTK 3.6.0")
+      execute_process(
+        COMMAND ${PATCH_EXECUTABLE} -p0 -N -i
+        ${ORTHANC_ROOT}/Resources/Patches/dcmtk-3.6.0-speed.patch
+        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+        RESULT_VARIABLE Failure
+        )
 
-    if (Failure)
-      message(FATAL_ERROR "Error while patching a file")
+      if (Failure)
+        message(FATAL_ERROR "Error while patching a file")
+      endif()
+
+    else (FirstRun())
+      message("No need to apply a patch for speed in DCMTK")
     endif()
+  else()
+    message("The patches for DCMTK have already been applied")
   endif()
 
-
   IF (CMAKE_CROSSCOMPILING)
-    SET(C_CHAR_UNSIGNED 1 CACHE INTERNAL "Whether char is unsigned.")
+    if (CMAKE_COMPILER_IS_GNUCXX AND
+        ${CMAKE_SYSTEM_NAME} STREQUAL "Windows")  # MinGW
+      SET(C_CHAR_UNSIGNED 1 CACHE INTERNAL "Whether char is unsigned.")
+    else()
+      message(FATAL_ERROR "Support your platform here")
+    endif()
   ENDIF()
+  
   SET(DCMTK_SOURCE_DIR ${DCMTK_SOURCES_DIR})
   include(${DCMTK_SOURCES_DIR}/CMake/CheckFunctionWithHeaderExists.cmake)
   include(${DCMTK_SOURCES_DIR}/CMake/GenerateDCMTKConfigure.cmake)
@@ -91,7 +121,20 @@ if (STATIC_BUILD OR NOT USE_SYSTEM_DCMTK)
     ${DCMTK_SOURCES_DIR}/CMake/osconfig.h.in
     ${DCMTK_SOURCES_DIR}/config/include/dcmtk/config/osconfig.h)
 
-  if (USE_DCMTK_361)
+  if (NOT USE_DCMTK_360)
+    if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
+      link_libraries(netapi32)  # For NetWkstaUserGetInfo at 12
+      link_libraries(iphlpapi)  # For GetAdaptersInfo at 8
+
+      # Configure Wine if cross-compiling for Windows
+      if (CMAKE_COMPILER_IS_GNUCXX)
+        include(${DCMTK_SOURCES_DIR}/CMake/dcmtkUseWine.cmake)
+        FIND_PROGRAM(WINE_WINE_PROGRAM wine)
+        FIND_PROGRAM(WINE_WINEPATH_PROGRAM winepath)
+        list(APPEND DCMTK_TRY_COMPILE_REQUIRED_CMAKE_FLAGS "-DCMAKE_EXE_LINKER_FLAGS=-static")
+      endif()
+    endif()
+
     # This step must be after the generation of "osconfig.h"
     INSPECT_FUNDAMENTAL_ARITHMETIC_TYPES()
   endif()
@@ -165,23 +208,16 @@ if (STATIC_BUILD OR NOT USE_SYSTEM_DCMTK)
       ${DCMTK_SOURCES_DIR}/oflog/libsrc/windebap.cc
       ${DCMTK_SOURCES_DIR}/oflog/libsrc/winsock.cc
       )
-    
-    execute_process(
-      COMMAND ${PATCH_EXECUTABLE} -p0 -N -i ${DCMTK_PATCH_SPEED}
-      WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
-      RESULT_VARIABLE Failure
-      )
-
-    if (Failure AND FirstRun)
-      message(FATAL_ERROR "Error while patching a file")
-    endif()
 
   elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
     list(REMOVE_ITEM DCMTK_SOURCES 
       ${DCMTK_SOURCES_DIR}/oflog/libsrc/unixsock.cc
+      ${DCMTK_SOURCES_DIR}/oflog/libsrc/clfsap.cc
       )
 
-    if (CMAKE_COMPILER_IS_GNUCXX AND DCMTK_PATCH_MINGW64)
+    if (CMAKE_COMPILER_IS_GNUCXX AND
+        DCMTK_PATCH_MINGW64 AND
+        USE_DCMTK_360)
       # This is a patch for MinGW64
       execute_process(
         COMMAND ${PATCH_EXECUTABLE} -p0 -N -i ${DCMTK_PATCH_MINGW64}
@@ -193,18 +229,6 @@ if (STATIC_BUILD OR NOT USE_SYSTEM_DCMTK)
         message(FATAL_ERROR "Error while patching a file")
       endif()
     endif()
-
-    # This patch improves speed, even for Windows
-    execute_process(
-      COMMAND ${PATCH_EXECUTABLE} -p0 -N 
-      INPUT_FILE ${DCMTK_PATCH_SPEED}
-      WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
-      RESULT_VARIABLE Failure
-      )
-
-    if (Failure AND FirstRun)
-      message(FATAL_ERROR "Error while patching a file")
-    endif()
   endif()
 
   list(REMOVE_ITEM DCMTK_SOURCES 
@@ -212,7 +236,7 @@ if (STATIC_BUILD OR NOT USE_SYSTEM_DCMTK)
     ${DCMTK_SOURCES_DIR}/dcmdata/libsrc/mkdeftag.cc
     )
 
-  if (NOT USE_DCMTK_361)
+  if (USE_DCMTK_360)
     # Removing this file is required with DCMTK 3.6.0
     list(REMOVE_ITEM DCMTK_SOURCES 
       ${DCMTK_SOURCES_DIR}/dcmdata/libsrc/dcdictbi.cc
@@ -270,10 +294,14 @@ else()
     set(DCMTK_CONFIGURATION_FILE "${DCMTK_config_INCLUDE_DIR}/cfunix.h")
   elseif (EXISTS "${DCMTK_config_INCLUDE_DIR}/osconfig.h")  # This is for Arch Linux
     set(DCMTK_CONFIGURATION_FILE "${DCMTK_config_INCLUDE_DIR}/osconfig.h")
+  elseif (EXISTS "${DCMTK_INCLUDE_DIRS}/dcmtk/config/osconfig.h")  # This is for Debian Buster
+    set(DCMTK_CONFIGURATION_FILE "${DCMTK_INCLUDE_DIRS}/dcmtk/config/osconfig.h")
   else()
     message(FATAL_ERROR "Please install libdcmtk*-dev")
   endif()
 
+  message("DCMTK configuration file: ${DCMTK_CONFIGURATION_FILE}")
+  
   # Autodetection of the version of DCMTK
   file(STRINGS
     "${DCMTK_CONFIGURATION_FILE}" 
@@ -309,6 +337,13 @@ if (NOT DCMTK_USE_EMBEDDED_DICTIONARIES)
       /usr/share/libdcmtk7
       /usr/share/libdcmtk8
       /usr/share/libdcmtk9
+      /usr/share/libdcmtk10
+      /usr/share/libdcmtk11
+      /usr/share/libdcmtk12
+      /usr/share/libdcmtk13
+      /usr/share/libdcmtk14
+      /usr/share/libdcmtk15
+      /usr/share/libdcmtk16
       /usr/local/share/dcmtk
       )
 
diff --git a/Resources/CMake/LibIconvConfiguration.cmake b/Resources/CMake/LibIconvConfiguration.cmake
index d381798..c4fe211 100644
--- a/Resources/CMake/LibIconvConfiguration.cmake
+++ b/Resources/CMake/LibIconvConfiguration.cmake
@@ -1,6 +1,6 @@
-set(LIBICONV_SOURCES_DIR ${CMAKE_BINARY_DIR}/libiconv-1.14)
-set(LIBICONV_URL "http://www.orthanc-server.com/downloads/third-party/libiconv-1.14.tar.gz")
-set(LIBICONV_MD5 "e34509b1623cec449dfeb73d7ce9c6c6")
+set(LIBICONV_SOURCES_DIR ${CMAKE_BINARY_DIR}/libiconv-1.15)
+set(LIBICONV_URL "http://www.orthanc-server.com/downloads/third-party/libiconv-1.15.tar.gz")
+set(LIBICONV_MD5 "ace8b5f2db42f7b3b3057585e80d9808")
 
 DownloadPackage(${LIBICONV_MD5} ${LIBICONV_URL} "${LIBICONV_SOURCES_DIR}")
 
diff --git a/Resources/CMake/SQLiteConfiguration.cmake b/Resources/CMake/SQLiteConfiguration.cmake
index e15a6e0..49ae259 100644
--- a/Resources/CMake/SQLiteConfiguration.cmake
+++ b/Resources/CMake/SQLiteConfiguration.cmake
@@ -19,6 +19,8 @@ if (SQLITE_STATIC)
   SET(SQLITE_MD5 "5fbeff9645ab035a1f580e90b279a16d")
   SET(SQLITE_URL "http://www.orthanc-server.com/downloads/third-party/sqlite-amalgamation-3071300.zip")
 
+  add_definitions(-DORTHANC_SQLITE_VERSION=3007013)
+
   DownloadPackage(${SQLITE_MD5} ${SQLITE_URL} "${SQLITE_SOURCES_DIR}")
 
   set(SQLITE_SOURCES
@@ -52,7 +54,10 @@ else()
 
   # Autodetection of the version of SQLite
   file(STRINGS "${SQLITE_INCLUDE_DIR}/sqlite3.h" SQLITE_VERSION_NUMBER1 REGEX "#define SQLITE_VERSION_NUMBER.*$")    
-  string(REGEX REPLACE "#define SQLITE_VERSION_NUMBER(.*)$" "\\1" SQLITE_VERSION_NUMBER ${SQLITE_VERSION_NUMBER1})
+  string(REGEX REPLACE "#define SQLITE_VERSION_NUMBER(.*)$" "\\1" SQLITE_VERSION_NUMBER2 ${SQLITE_VERSION_NUMBER1})
+
+  # Remove the trailing spaces to convert the string to a proper integer
+  string(STRIP ${SQLITE_VERSION_NUMBER2} SQLITE_VERSION_NUMBER)
 
   message("Detected version of SQLite: ${SQLITE_VERSION_NUMBER}")
 
@@ -61,5 +66,7 @@ else()
     message(FATAL_ERROR "SQLite version must be above 3.7.0. Please set the CMake variable USE_SYSTEM_SQLITE to OFF.")
   ENDIF()
 
+  add_definitions(-DORTHANC_SQLITE_VERSION=${SQLITE_VERSION_NUMBER})
+
   link_libraries(sqlite3)
 endif()
diff --git a/Resources/Configuration.json b/Resources/Configuration.json
index 43975bf..069c6cd 100644
--- a/Resources/Configuration.json
+++ b/Resources/Configuration.json
@@ -7,13 +7,14 @@
   // displayed in Orthanc Explorer and at the URI "/system".
   "Name" : "MyOrthanc",
 
-  // Path to the directory that holds the heavyweight files
-  // (i.e. the raw DICOM instances)
+  // Path to the directory that holds the heavyweight files (i.e. the
+  // raw DICOM instances). Backslashes must be either escaped by
+  // doubling them, or replaced by forward slashes "/".
   "StorageDirectory" : "OrthancStorage",
 
-  // Path to the directory that holds the SQLite index (if unset,
-  // the value of StorageDirectory is used). This index could be
-  // stored on a RAM-drive or a SSD device for performance reasons.
+  // Path to the directory that holds the SQLite index (if unset, the
+  // value of StorageDirectory is used). This index could be stored on
+  // a RAM-drive or a SSD device for performance reasons.
   "IndexDirectory" : "OrthancStorage",
 
   // Enable the transparent compression of the DICOM instances
@@ -37,7 +38,8 @@
   // instance of Orthanc (e.g. "./libPluginTest.so" for Linux, or
   // "./PluginTest.dll" for Windows). These paths can refer to
   // folders, in which case they will be scanned non-recursively to
-  // find shared libraries.
+  // find shared libraries. Backslashes must be either escaped by
+  // doubling them, or replaced by forward slashes "/".
   "Plugins" : [
   ],
 
@@ -80,7 +82,8 @@
   // The DICOM Application Entity Title
   "DicomAet" : "ORTHANC",
 
-  // Check whether the called AET corresponds during a DICOM request
+  // Check whether the called AET corresponds to the AET of Orthanc
+  // during an incoming DICOM SCU request
   "DicomCheckCalledAet" : false,
 
   // The DICOM port
@@ -154,16 +157,31 @@
     // "sample" : [ "STORESCP", "127.0.0.1", 2000 ]
 
     /**
-     * A fourth parameter is available to enable patches for a
-     * specific PACS manufacturer. The allowed values are currently
-     * "Generic" (default value), "StoreScp" (storescp tool from
-     * DCMTK), "ClearCanvas", "MedInria", "Dcm4Chee", "SyngoVia",
-     * "AgfaImpax" (Agfa IMPAX), "EFilm2" (eFilm version 2), and
-     * "Vitrea". This parameter is case-sensitive.
+     * A fourth parameter is available to enable patches for
+     * specific PACS manufacturers. The allowed values are currently:
+     * - "Generic" (default value),
+     * - "GenericNoWildcardInDates" (to replace "*" by "" in date fields 
+     *   in outgoing C-Find requests originating from Orthanc)
+     * - "GenericNoUniversalWildcard" (to replace "*" by "" in all fields
+     *   in outgoing C-Find SCU requests originating from Orthanc)
+     * - "StoreScp" (storescp tool from DCMTK),
+     * - "ClearCanvas", "Dcm4Chee" and "Vitrea".
+     * This parameter is case-sensitive.
      **/
     // "clearcanvas" : [ "CLEARCANVAS", "192.168.1.1", 104, "ClearCanvas" ]
   },
 
+  // Whether the Orthanc SCP allows incoming C-Store requests, even
+  // from SCU modalities it does not know about (i.e. that are not
+  // listed in the "DicomModalities" option above)
+  "DicomAlwaysAllowStore" : true,
+
+  // Whether Orthanc checks the IP/hostname address of the remote
+  // modality initiating a DICOM connection (as listed in the
+  // "DicomModalities" option above). If this option is set to
+  // "false", Orthanc only checks the AET of the remote modality.
+  "DicomCheckModalityHost" : false,
+
   // The timeout (in seconds) after which the DICOM associations are
   // considered as closed by the Orthanc SCU (client) if the remote
   // DICOM SCP (server) does not answer.
@@ -330,6 +348,11 @@
   // interest in the "Dictionary" configuration option below.
   "LoadPrivateDictionary" : true,
 
+  // Locale to be used by Orthanc. Currently, only used if comparing
+  // strings in a case-insensitive way. It should be safe to keep this
+  // value undefined, which lets Orthanc autodetect the suitable locale.
+  // "Locale" : "en_US.UTF-8",
+
   // Register a new tag in the dictionary of DICOM tags that are known
   // to Orthanc. Each line must contain the tag (formatted as 2
   // hexadecimal numbers), the value representation (2 upcase
diff --git a/Resources/DicomConformanceStatement.py b/Resources/DicomConformanceStatement.py
index c9f8ee8..df4a46b 100755
--- a/Resources/DicomConformanceStatement.py
+++ b/Resources/DicomConformanceStatement.py
@@ -3,6 +3,7 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017 Osimis, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
diff --git a/Resources/EmbedResources.py b/Resources/EmbedResources.py
index ad5cf61..a528468 100755
--- a/Resources/EmbedResources.py
+++ b/Resources/EmbedResources.py
@@ -3,6 +3,7 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017 Osimis, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
diff --git a/Resources/EncodingTests.h b/Resources/EncodingTests.h
index 4266c94..8415aa3 100644
--- a/Resources/EncodingTests.h
+++ b/Resources/EncodingTests.h
@@ -59,3 +59,5 @@ static const char *testEncodingsExpected[18] = {
   "\xd0\xa2\xd0\xb0\xd0\xb7",
   "\xd0\x9f\xd1\x80\xd1\x8f\xd0\xbc\xd0\xb0\xd1\x8f"
 };
+static const char *toUpperSource = "\x67\x72\xc3\xbc\xc3\x9f\x45\x4e\x20\x53\xc3\xa9\x62\x61\x73\x54\x49\x65\x6e\x20\x54\x65\x73\x74\xc3\xa9\xc3\xa4\xc3\xb6\xc3\xb2\xd0\x94\xce\x98\xc4\x9d\xd7\x93\xd8\xb5\xc4\xb7\xd1\x9b\xe0\xb9\x9b\xef\xbe\x88\xc4\xb0";
+static const char *toUpperResult = "\x47\x52\xc3\x9c\xc3\x9f\x45\x4e\x20\x53\xc3\x89\x42\x41\x53\x54\x49\x45\x4e\x20\x54\x45\x53\x54\xc3\x89\xc3\x84\xc3\x96\xc3\x92\xd0\x94\xce\x98\xc4\x9c\xd7\x93\xd8\xb5\xc4\xb6\xd0\x8b\xe0\xb9\x9b\xef\xbe\x88\xc4\xb0";
diff --git a/Resources/EncodingTests.py b/Resources/EncodingTests.py
index ece3457..cb39276 100755
--- a/Resources/EncodingTests.py
+++ b/Resources/EncodingTests.py
@@ -72,3 +72,9 @@ else:
     for i in range(len(expected)):
         print expected[i]
         #print '%s: %s' % (expected[i], l[i])
+
+
+
+u = (u'grüßEN SébasTIen %s' % source)
+print 'static const char *toUpperSource = %s;' % ToArray(u.encode('utf-8'))
+print 'static const char *toUpperResult = %s;' % ToArray(u.upper().encode('utf-8'))
diff --git a/Resources/Fonts/GenerateFont.py b/Resources/Fonts/GenerateFont.py
index e49f332..ad84608 100755
--- a/Resources/Fonts/GenerateFont.py
+++ b/Resources/Fonts/GenerateFont.py
@@ -3,6 +3,7 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017 Osimis, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
diff --git a/Resources/GenerateAnonymizationProfile.py b/Resources/GenerateAnonymizationProfile.py
new file mode 100755
index 0000000..a9b2a0d
--- /dev/null
+++ b/Resources/GenerateAnonymizationProfile.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+
+# Orthanc - A Lightweight, RESTful DICOM Store
+# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+# Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017 Osimis, Belgium
+#
+# This program is free software: you can redistribute it and/or
+# modify it under the terms of the GNU 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
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+import re
+import sys
+import xml.etree.ElementTree as ET
+
+# Usage:
+# ./GenerateAnonymizationProfile.py ~/Subversion/dicom-specification/2017c/part15.xml 
+
+if len(sys.argv) != 2:
+    raise Exception('Please provide the path to the part15.xml file from the DICOM standard')
+
+with open(sys.argv[1], 'r') as f:
+    root = ET.fromstring(f.read())
+
+br = '{http://docbook.org/ns/docbook}' # Shorthand variable
+
+
+LINES = []
+
+def FormatLine(command, name):
+    indentation = 65
+    
+    if len(command) > indentation:
+        raise Exception('Too long command')
+        
+    line = '    ' + command + (' ' * (indentation - len(command))) + '// ' + name
+    LINES.append(line)
+
+def FormatUnknown(rawTag, name, profile):
+    FormatLine('// TODO: %s with rule %s' % (rawTag, profile), name)
+
+    
+RAW_TAG_RE = re.compile(r'^\(\s*([0-9A-F]{4})\s*,\s*([0-9A-F]{4})\s*\)$')
+
+
+for table in root.iter('%stable' % br):
+    if table.attrib['label'] == 'E.1-1':
+        for row in table.find('%stbody' % br).iter('%str' % br):
+            rawTag = row.find('%std[2]/%spara' % (br, br)).text
+            name = row.find('%std[1]/%spara' % (br, br)).text
+            profile = row.find('%std[5]/%spara' % (br, br)).text
+
+            if len(name.strip()) == 0:
+                continue
+
+            match = RAW_TAG_RE.match(rawTag)
+            if match == None:
+                FormatUnknown(rawTag, name, profile)
+            else:
+                tag = '0x%s, 0x%s' % (match.group(1).lower(), match.group(2).lower())
+
+                if name in [
+                        'SOP Instance UID',
+                        'Series Instance UID',
+                        'Study Instance UID',
+                ]:
+                    FormatLine('// Tag (%s) is set in Apply()' % tag, name)
+                elif name in [
+                        'Patient\'s Name',
+                        'Patient ID',
+                ]:
+                    FormatLine('// Tag (%s) is set below (*)' % tag, name)
+                elif profile == 'X':
+                    FormatLine('removals_.insert(DicomTag(%s));' % tag, name)
+                elif profile.startswith('X/'):
+                    FormatLine('removals_.insert(DicomTag(%s));   /* %s */' % (tag, profile), name)
+                elif profile == 'Z':
+                    FormatLine('clearings_.insert(DicomTag(%s));' % tag, name)
+                elif profile == 'D' or profile.startswith('Z/'):
+                    FormatLine('clearings_.insert(DicomTag(%s));  /* %s */' % (tag, profile), name)
+                elif profile == 'U':
+                    FormatLine('removals_.insert(DicomTag(%s));   /* TODO UID */' % (tag), name)
+                else:
+                    FormatUnknown(rawTag, name, profile)
+
+for line in sorted(LINES):
+    print line
+    
+
+# D - replace with a non-zero length value that may be a dummy value and consistent with the VR
+# Z - replace with a zero length value, or a non-zero length value that may be a dummy value and consistent with the VR
+# X - remove
+# K - keep (unchanged for non-sequence attributes, cleaned for sequences)
+# C - clean, that is replace with values of similar meaning known not to contain identifying information and consistent with the VR
+# U - replace with a non-zero length UID that is internally consistent within a set of Instances
+# Z/D - Z unless D is required to maintain IOD conformance (Type 2 versus Type 1)
+# X/Z - X unless Z is required to maintain IOD conformance (Type 3 versus Type 2)
+# X/D - X unless D is required to maintain IOD conformance (Type 3 versus Type 1)
+# X/Z/D - X unless Z or D is required to maintain IOD conformance (Type 3 versus Type 2 versus Type 1)
+# X/Z/U* - X unless Z or replacement of contained instance UIDs (U) is required to maintain IOD conformance (Type 3 versus Type 2 versus Type 1 sequences containing UID references)
diff --git a/Resources/GenerateErrorCodes.py b/Resources/GenerateErrorCodes.py
index 863c283..3a80814 100755
--- a/Resources/GenerateErrorCodes.py
+++ b/Resources/GenerateErrorCodes.py
@@ -3,6 +3,7 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017 Osimis, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
diff --git a/Resources/Patches/dcmtk-3.6.0-speed.patch b/Resources/Patches/dcmtk-3.6.0-speed.patch
index 185dfe9..45ee396 100644
--- a/Resources/Patches/dcmtk-3.6.0-speed.patch
+++ b/Resources/Patches/dcmtk-3.6.0-speed.patch
@@ -1,7 +1,19 @@
 diff -urEb dcmtk-3.6.0.orig/dcmnet/libsrc/dul.cc dcmtk-3.6.0/dcmnet/libsrc/dul.cc
---- dcmtk-3.6.0.orig/dcmnet/libsrc/dul.cc	2016-04-05 14:30:18.254459281 +0200
-+++ dcmtk-3.6.0/dcmnet/libsrc/dul.cc	2016-04-05 14:32:07.246463713 +0200
-@@ -1770,7 +1770,7 @@
+--- dcmtk-3.6.0.orig/dcmnet/libsrc/dul.cc	2017-03-17 15:49:23.043061969 +0100
++++ dcmtk-3.6.0/dcmnet/libsrc/dul.cc	2017-03-17 15:50:44.075359547 +0100
+@@ -630,7 +630,10 @@
+     if (cond.bad())
+         return cond;
+ 
+-    cond = PRV_NextPDUType(association, block, timeout, &pduType);
++    /* This is the first time we read from this new connection, so in case it
++     * doesn't speak DICOM, we shouldn't wait forever (= DUL_NOBLOCK).
++     */
++    cond = PRV_NextPDUType(association, DUL_NOBLOCK, PRV_DEFAULTTIMEOUT, &pduType);
+ 
+     if (cond == DUL_NETWORKCLOSED)
+         event = TRANS_CONN_CLOSED;
+@@ -1770,7 +1773,7 @@
                  // send number of socket handle in child process over anonymous pipe
                  DWORD bytesWritten;
                  char buf[20];
@@ -10,7 +22,7 @@ diff -urEb dcmtk-3.6.0.orig/dcmnet/libsrc/dul.cc dcmtk-3.6.0/dcmnet/libsrc/dul.c
                  if (!WriteFile(hChildStdInWriteDup, buf, strlen(buf) + 1, &bytesWritten, NULL))
                  {
                      CloseHandle(hChildStdInWriteDup);
-@@ -1780,7 +1780,7 @@
+@@ -1780,7 +1783,7 @@
                  // return OF_ok status code DULC_FORKEDCHILD with descriptive text
                  OFOStringStream stream;
                  stream << "New child process started with pid " << OFstatic_cast(int, pi.dwProcessId)
@@ -19,7 +31,7 @@ diff -urEb dcmtk-3.6.0.orig/dcmnet/libsrc/dul.cc dcmtk-3.6.0/dcmnet/libsrc/dul.c
                  OFSTRINGSTREAM_GETOFSTRING(stream, msg)
                  return makeDcmnetCondition(DULC_FORKEDCHILD, OF_ok, msg.c_str());
              }
-@@ -1840,7 +1840,7 @@
+@@ -1840,7 +1843,7 @@
      }
  #endif
  #endif
@@ -28,10 +40,9 @@ diff -urEb dcmtk-3.6.0.orig/dcmnet/libsrc/dul.cc dcmtk-3.6.0/dcmnet/libsrc/dul.c
  
  #ifndef DONT_DISABLE_NAGLE_ALGORITHM
      /*
-Only in dcmtk-3.6.0/dcmnet/libsrc: dul.cc~
 diff -urEb dcmtk-3.6.0.orig/dcmnet/libsrc/dulfsm.cc dcmtk-3.6.0/dcmnet/libsrc/dulfsm.cc
---- dcmtk-3.6.0.orig/dcmnet/libsrc/dulfsm.cc	2016-04-05 14:30:18.250459281 +0200
-+++ dcmtk-3.6.0/dcmnet/libsrc/dulfsm.cc	2016-04-05 14:32:20.566464254 +0200
+--- dcmtk-3.6.0.orig/dcmnet/libsrc/dulfsm.cc	2017-03-17 15:49:23.043061969 +0100
++++ dcmtk-3.6.0/dcmnet/libsrc/dulfsm.cc	2017-03-17 15:49:48.467144792 +0100
 @@ -2417,7 +2417,7 @@
            return makeDcmnetCondition(DULC_TCPINITERROR, OF_error, msg.c_str());
          }
@@ -41,4 +52,3 @@ diff -urEb dcmtk-3.6.0.orig/dcmnet/libsrc/dulfsm.cc dcmtk-3.6.0/dcmnet/libsrc/du
  
  #ifndef DONT_DISABLE_NAGLE_ALGORITHM
          /*
-Only in dcmtk-3.6.0/dcmnet/libsrc: dulfsm.cc~
diff --git a/Resources/Patches/dcmtk-3.6.1-speed.patch b/Resources/Patches/dcmtk-3.6.1-speed.patch
deleted file mode 100644
index 97b4a25..0000000
--- a/Resources/Patches/dcmtk-3.6.1-speed.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-diff -urEb dcmtk-3.6.1_20160216.orig/dcmnet/libsrc/dul.cc dcmtk-3.6.1_20160216/dcmnet/libsrc/dul.cc
---- dcmtk-3.6.1_20160216.orig/dcmnet/libsrc/dul.cc	2016-04-05 12:56:28.962230391 +0200
-+++ dcmtk-3.6.1_20160216/dcmnet/libsrc/dul.cc	2016-04-05 12:57:15.814232296 +0200
-@@ -1841,7 +1841,7 @@
-         return makeDcmnetCondition(DULC_TCPINITERROR, OF_error, msg.c_str());
-     }
- #endif
--    setTCPBufferLength(sock);
-+    //setTCPBufferLength(sock);
- 
- #ifndef DONT_DISABLE_NAGLE_ALGORITHM
-     /*
-Only in dcmtk-3.6.1_20160216/dcmnet/libsrc: dul.cc~
-diff -urEb dcmtk-3.6.1_20160216.orig/dcmnet/libsrc/dulfsm.cc dcmtk-3.6.1_20160216/dcmnet/libsrc/dulfsm.cc
---- dcmtk-3.6.1_20160216.orig/dcmnet/libsrc/dulfsm.cc	2016-04-05 12:56:28.962230391 +0200
-+++ dcmtk-3.6.1_20160216/dcmnet/libsrc/dulfsm.cc	2016-04-05 12:57:31.946232952 +0200
-@@ -2431,7 +2431,7 @@
-           return makeDcmnetCondition(DULC_TCPINITERROR, OF_error, msg.c_str());
-         }
- #endif
--        setTCPBufferLength(s);
-+        //setTCPBufferLength(s);
- 
- #ifndef DONT_DISABLE_NAGLE_ALGORITHM
-         /*
-Only in dcmtk-3.6.1_20160216/dcmnet/libsrc: dulfsm.cc~
diff --git a/Resources/Patches/dcmtk-3.6.1-private.dic b/Resources/Patches/dcmtk-3.6.2-private.dic
similarity index 100%
rename from Resources/Patches/dcmtk-3.6.1-private.dic
rename to Resources/Patches/dcmtk-3.6.2-private.dic
diff --git a/Resources/Patches/dcmtk.txt b/Resources/Patches/dcmtk.txt
index f4c161b..8ffb7bf 100644
--- a/Resources/Patches/dcmtk.txt
+++ b/Resources/Patches/dcmtk.txt
@@ -2,9 +2,9 @@ Generate some patch
 ===================
 
 diff -urEb dcmtk-3.6.0.orig/ dcmtk-3.6.0
+diff -urEb dcmtk-3.6.2.orig/ dcmtk-3.6.2
 
-
-For "dcmtk-3.6.1-private.dic"
+For "dcmtk-3.6.2-private.dic"
 =============================
 
-# cp ../../ThirdPartyDownloads/dcmtk-3.6.1_20160216/dcmdata/data/private.dic dcmtk-3.6.1-private.dic
+# cp ../../ThirdPartyDownloads/dcmtk-3.6.2/dcmdata/data/private.dic dcmtk-3.6.2-private.dic
diff --git a/Resources/RetrieveCACertificates.py b/Resources/RetrieveCACertificates.py
index 5408c0b..81e224f 100755
--- a/Resources/RetrieveCACertificates.py
+++ b/Resources/RetrieveCACertificates.py
@@ -3,6 +3,7 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017 Osimis, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
diff --git a/Resources/Samples/ImportDicomFiles/ImportDicomFiles.py b/Resources/Samples/ImportDicomFiles/ImportDicomFiles.py
index adb3262..8f106a7 100755
--- a/Resources/Samples/ImportDicomFiles/ImportDicomFiles.py
+++ b/Resources/Samples/ImportDicomFiles/ImportDicomFiles.py
@@ -1,8 +1,9 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017 Osimis, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
diff --git a/Resources/Samples/Lua/AutomatedJpeg2kCompression.lua b/Resources/Samples/Lua/AutomatedJpeg2kCompression.lua
index df3a10e..766b508 100644
--- a/Resources/Samples/Lua/AutomatedJpeg2kCompression.lua
+++ b/Resources/Samples/Lua/AutomatedJpeg2kCompression.lua
@@ -16,7 +16,7 @@ function OnStoredInstance(instanceId, tags, metadata, origin)
 
       -- Compress to JPEG2000 using gdcm
       local compressed = instanceId .. '-compressed.dcm'
-      os.execute('gdcmconv --j2k ' .. uncompressed .. ' ' .. compressed)
+      os.execute('gdcmconv -U --j2k ' .. uncompressed .. ' ' .. compressed)
 
       -- Generate a new SOPInstanceUID for the JPEG2000 file, as
       -- gdcmconv does not do this by itself
diff --git a/Resources/Samples/Lua/CallWebService.js b/Resources/Samples/Lua/CallWebService.js
index 84f3130..5bb279d 100644
--- a/Resources/Samples/Lua/CallWebService.js
+++ b/Resources/Samples/Lua/CallWebService.js
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Resources/Samples/Lua/ModifyInstanceWithSequence.lua b/Resources/Samples/Lua/ModifyInstanceWithSequence.lua
index f5b8775..58cd710 100644
--- a/Resources/Samples/Lua/ModifyInstanceWithSequence.lua
+++ b/Resources/Samples/Lua/ModifyInstanceWithSequence.lua
@@ -17,7 +17,7 @@ function OnStoredInstance(instanceId, tags, metadata, origin)
 
       -- Create the modified instance
       local modified = RestApiPost('/instances/' .. instanceId .. '/modify',
-                                   DumpJson(request))
+                                   DumpJson(request, true))
 
       -- Upload the modified instance to the Orthanc store
       RestApiPost('/instances/', modified)
diff --git a/Resources/Samples/Lua/OnStableStudy.lua b/Resources/Samples/Lua/OnStableStudy.lua
index e83b549..fd6666a 100644
--- a/Resources/Samples/Lua/OnStableStudy.lua
+++ b/Resources/Samples/Lua/OnStableStudy.lua
@@ -40,7 +40,7 @@ function OnStableStudy(studyId, tags, metadata)
 
       -- Modify the entire study in one single call
       local m = RestApiPost('/studies/' .. studyId .. '/modify',
-                            DumpJson(command))
+                            DumpJson(command, true))
       print('Modified study: ' .. m)
    end
 end
diff --git a/Resources/Samples/Python/AnonymizeAllPatients.py b/Resources/Samples/Python/AnonymizeAllPatients.py
index b83bcb2..2848890 100755
--- a/Resources/Samples/Python/AnonymizeAllPatients.py
+++ b/Resources/Samples/Python/AnonymizeAllPatients.py
@@ -4,6 +4,7 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017 Osimis, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
diff --git a/Resources/Samples/Python/ArchiveAllPatients.py b/Resources/Samples/Python/ArchiveAllPatients.py
index 6c4be5c..1696431 100755
--- a/Resources/Samples/Python/ArchiveAllPatients.py
+++ b/Resources/Samples/Python/ArchiveAllPatients.py
@@ -4,6 +4,7 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017 Osimis, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
diff --git a/Resources/Samples/Python/ArchiveStudiesInTimeRange.py b/Resources/Samples/Python/ArchiveStudiesInTimeRange.py
index 986a286..e57126e 100755
--- a/Resources/Samples/Python/ArchiveStudiesInTimeRange.py
+++ b/Resources/Samples/Python/ArchiveStudiesInTimeRange.py
@@ -4,6 +4,7 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017 Osimis, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
diff --git a/Resources/Samples/Python/AutoClassify.py b/Resources/Samples/Python/AutoClassify.py
index 47922dd..d26ec59 100755
--- a/Resources/Samples/Python/AutoClassify.py
+++ b/Resources/Samples/Python/AutoClassify.py
@@ -4,6 +4,7 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017 Osimis, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
diff --git a/Resources/Samples/Python/ChangesLoop.py b/Resources/Samples/Python/ChangesLoop.py
index 8030ccc..447c95b 100755
--- a/Resources/Samples/Python/ChangesLoop.py
+++ b/Resources/Samples/Python/ChangesLoop.py
@@ -3,6 +3,7 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017 Osimis, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
diff --git a/Resources/Samples/Python/ContinuousPatientAnonymization.py b/Resources/Samples/Python/ContinuousPatientAnonymization.py
index ae60ea7..d1cadd8 100755
--- a/Resources/Samples/Python/ContinuousPatientAnonymization.py
+++ b/Resources/Samples/Python/ContinuousPatientAnonymization.py
@@ -3,6 +3,7 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017 Osimis, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
diff --git a/Resources/Samples/Python/DownloadAnonymized.py b/Resources/Samples/Python/DownloadAnonymized.py
index 4674af3..0fd4a64 100755
--- a/Resources/Samples/Python/DownloadAnonymized.py
+++ b/Resources/Samples/Python/DownloadAnonymized.py
@@ -4,6 +4,7 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017 Osimis, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
diff --git a/Resources/Samples/Python/HighPerformanceAutoRouting.py b/Resources/Samples/Python/HighPerformanceAutoRouting.py
index 3a00f8b..3dfe7fc 100755
--- a/Resources/Samples/Python/HighPerformanceAutoRouting.py
+++ b/Resources/Samples/Python/HighPerformanceAutoRouting.py
@@ -4,6 +4,7 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017 Osimis, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
diff --git a/Resources/Samples/Python/ManualModification.py b/Resources/Samples/Python/ManualModification.py
index 780de72..5cef901 100755
--- a/Resources/Samples/Python/ManualModification.py
+++ b/Resources/Samples/Python/ManualModification.py
@@ -3,6 +3,7 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017 Osimis, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
diff --git a/Resources/Samples/Python/Replicate.py b/Resources/Samples/Python/Replicate.py
index e1134ac..d9154f6 100755
--- a/Resources/Samples/Python/Replicate.py
+++ b/Resources/Samples/Python/Replicate.py
@@ -3,6 +3,7 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017 Osimis, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
diff --git a/Resources/Samples/Python/RestToolbox.py b/Resources/Samples/Python/RestToolbox.py
index fba0ad3..e07fb05 100644
--- a/Resources/Samples/Python/RestToolbox.py
+++ b/Resources/Samples/Python/RestToolbox.py
@@ -1,6 +1,7 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017 Osimis, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
diff --git a/Resources/Samples/Tools/RecoverCompressedFile.cpp b/Resources/Samples/Tools/RecoverCompressedFile.cpp
index 663ec72..22da7ed 100644
--- a/Resources/Samples/Tools/RecoverCompressedFile.cpp
+++ b/Resources/Samples/Tools/RecoverCompressedFile.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Resources/Samples/WebApplications/DrawingDicomizer.js b/Resources/Samples/WebApplications/DrawingDicomizer.js
index 93be150..d5fa9ca 100644
--- a/Resources/Samples/WebApplications/DrawingDicomizer.js
+++ b/Resources/Samples/WebApplications/DrawingDicomizer.js
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Resources/Samples/WebApplications/DrawingDicomizer/orthanc.js b/Resources/Samples/WebApplications/DrawingDicomizer/orthanc.js
index 49c1f6e..34a42a7 100644
--- a/Resources/Samples/WebApplications/DrawingDicomizer/orthanc.js
+++ b/Resources/Samples/WebApplications/DrawingDicomizer/orthanc.js
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Resources/Samples/WebApplications/NodeToolbox.js b/Resources/Samples/WebApplications/NodeToolbox.js
index 93fb267..d66a204 100644
--- a/Resources/Samples/WebApplications/NodeToolbox.js
+++ b/Resources/Samples/WebApplications/NodeToolbox.js
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/Resources/WindowsResources.py b/Resources/WindowsResources.py
index c56733b..b59e77a 100755
--- a/Resources/WindowsResources.py
+++ b/Resources/WindowsResources.py
@@ -3,6 +3,7 @@
 # Orthanc - A Lightweight, RESTful DICOM Store
 # Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
 # Department, University Hospital of Liege, Belgium
+# Copyright (C) 2017 Osimis, Belgium
 #
 # This program is free software: you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
diff --git a/TODO b/TODO
index 7b2aa1c..55a0c8b 100644
--- a/TODO
+++ b/TODO
@@ -17,6 +17,7 @@ General
   https://groups.google.com/d/msg/orthanc-users/--njEbqcDDI/rBu8XL-Mm-cJ
 * Support partial file retrieval in Orthanc::HttpClient
 * Support retry counter in Orthanc::HttpClient
+* Option to enable DNS lookups in DICOM: https://goo.gl/woa35Z
 
 
 ========
@@ -29,6 +30,13 @@ Short-term
 
 * Create multi-frame images with /tools/create-dicom (by adding a
   "MultiFrame" flag to avoid creating a series)
+* In the POST /instances, add a ?force=true query arguments to force Orthanc to replace 
+  the uploaded file even if it already exists in Orthanc.  This is useful when transcoding
+  an image outside Orthanc and reuploading it.  Since it has the same ids, its Orthanc ID
+  will be the same as the previous one.
+* In the /studies/{id}/anonymize route, add an option to remove secondary captures.
+  They usually contains Patient info in the image.  The SOPClassUID might be used to
+  identify such secondary captures.
 
 ---------
 Long-term
@@ -78,12 +86,18 @@ SDK
 Ideas of plugins
 ----------------
 
+* Complex anonymization, with recursive mapping of UIDs
+  https://bitbucket.org/sjodogne/orthanc/issues/46/
 * DICOM-RT primitives (RT-STRUCT, RT-PLAN, RT-DOSE)
 * Converter to/from NIfTI
 * MySQL database plugin
 * Decode JPEG2k with grok: https://github.com/GrokImageCompression/grok
-* Generate dynamic content using Lua:
+* Generate dynamic HTTP content using Lua:
   https://groups.google.com/d/msg/orthanc-users/KompazkxRSs/5Rh03mzgDAAJ
+* More generally, expose more callbacks of the plugin SDK in Lua:
+  https://groups.google.com/d/msg/orthanc-users/_FbiRHuXPGM/J-OAv7zaCAAJ
+* Authorization plugin for the DICOM protocol:
+  https://groups.google.com/d/msg/orthanc-users/Wv-QEwTE0IA/rvJxoOjcAQAJ
 
 
 ===
@@ -105,8 +119,6 @@ Performance
 Orthanc Book
 ============
 
-* Document Lua C-FIND filters (cf. "IncomingFindRequestFilter()")
-
 
 ================
 Code refactoring
diff --git a/UnitTestsSources/DicomMapTests.cpp b/UnitTestsSources/DicomMapTests.cpp
index 34245a0..2aeb047 100644
--- a/UnitTestsSources/DicomMapTests.cpp
+++ b/UnitTestsSources/DicomMapTests.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/UnitTestsSources/FileStorageTests.cpp b/UnitTestsSources/FileStorageTests.cpp
index cabe267..7a45f7e 100644
--- a/UnitTestsSources/FileStorageTests.cpp
+++ b/UnitTestsSources/FileStorageTests.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/UnitTestsSources/FromDcmtkTests.cpp b/UnitTestsSources/FromDcmtkTests.cpp
index 939e057..57f9aeb 100644
--- a/UnitTestsSources/FromDcmtkTests.cpp
+++ b/UnitTestsSources/FromDcmtkTests.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -76,7 +77,7 @@ TEST(DicomFormat, Tag)
 TEST(DicomModification, Basic)
 {
   DicomModification m;
-  m.SetupAnonymization();
+  m.SetupAnonymization(DicomVersion_2008);
   //m.SetLevel(DicomRootLevel_Study);
   //m.ReplacePlainString(DICOM_TAG_PATIENT_ID, "coucou");
   //m.ReplacePlainString(DICOM_TAG_PATIENT_NAME, "coucou");
@@ -132,7 +133,7 @@ TEST(DicomModification, Anonymization)
   ASSERT_FALSE(Toolbox::IsUuid(s));
 
   DicomModification m;
-  m.SetupAnonymization();
+  m.SetupAnonymization(DicomVersion_2008);
   m.Keep(privateTag);
 
   m.Apply(o);
@@ -142,7 +143,7 @@ TEST(DicomModification, Anonymization)
   ASSERT_TRUE(o.GetTagValue(s, privateTag));
   ASSERT_STREQ("private tag", s.c_str());
   
-  m.SetupAnonymization();
+  m.SetupAnonymization(DicomVersion_2008);
   m.Apply(o);
   ASSERT_FALSE(o.GetTagValue(s, privateTag));
 }
@@ -1216,3 +1217,9 @@ TEST(ParsedDicomFile, ChangeEncoding)
     }
   }
 }
+
+
+TEST(Toolbox, CaseWithAccents)
+{
+  ASSERT_EQ(toUpperResult, Toolbox::ToUpperCaseWithAccents(toUpperSource));
+}
diff --git a/UnitTestsSources/ImageProcessingTests.cpp b/UnitTestsSources/ImageProcessingTests.cpp
index 8714fc1..ad28c8d 100644
--- a/UnitTestsSources/ImageProcessingTests.cpp
+++ b/UnitTestsSources/ImageProcessingTests.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/UnitTestsSources/ImageTests.cpp b/UnitTestsSources/ImageTests.cpp
index 6c7ed55..9c9be56 100644
--- a/UnitTestsSources/ImageTests.cpp
+++ b/UnitTestsSources/ImageTests.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/UnitTestsSources/JpegLosslessTests.cpp b/UnitTestsSources/JpegLosslessTests.cpp
index c52eebe..dc5a98f 100644
--- a/UnitTestsSources/JpegLosslessTests.cpp
+++ b/UnitTestsSources/JpegLosslessTests.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/UnitTestsSources/LuaTests.cpp b/UnitTestsSources/LuaTests.cpp
index 52e9afd..d3beb93 100644
--- a/UnitTestsSources/LuaTests.cpp
+++ b/UnitTestsSources/LuaTests.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/UnitTestsSources/MemoryCacheTests.cpp b/UnitTestsSources/MemoryCacheTests.cpp
index 42129b1..e3df399 100644
--- a/UnitTestsSources/MemoryCacheTests.cpp
+++ b/UnitTestsSources/MemoryCacheTests.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/UnitTestsSources/MultiThreadingTests.cpp b/UnitTestsSources/MultiThreadingTests.cpp
index bc1154f..0b448b4 100644
--- a/UnitTestsSources/MultiThreadingTests.cpp
+++ b/UnitTestsSources/MultiThreadingTests.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -143,7 +144,7 @@ TEST(ReusableDicomUserConnection, DISABLED_Basic)
   }
 
   printf("**\n"); fflush(stdout);
-  Toolbox::USleep(1000000);
+  SystemToolbox::USleep(1000000);
   printf("**\n"); fflush(stdout);
 
   {
@@ -184,7 +185,7 @@ public:
       outputs.push_back(boost::lexical_cast<std::string>(b));
     }
 
-    Toolbox::USleep(30000);
+    SystemToolbox::USleep(30000);
 
     return true;
   }
@@ -203,7 +204,7 @@ static void Tata(ServerScheduler* s, ServerJob* j, bool* done)
     {
       printf(">> %s: %0.1f\n", it->c_str(), 100.0f * s->GetProgress(*it));
     }
-    Toolbox::USleep(3000);
+    SystemToolbox::USleep(3000);
   }
 }
 
@@ -248,7 +249,7 @@ TEST(MultiThreading, ServerScheduler)
   }
 
   //SystemToolbox::ServerBarrier();
-  //Toolbox::USleep(3000000);
+  //SystemToolbox::USleep(3000000);
 
   scheduler.Stop();
 
diff --git a/UnitTestsSources/PluginsTests.cpp b/UnitTestsSources/PluginsTests.cpp
index 4bd0f92..a2ab865 100644
--- a/UnitTestsSources/PluginsTests.cpp
+++ b/UnitTestsSources/PluginsTests.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/UnitTestsSources/PrecompiledHeadersUnitTests.cpp b/UnitTestsSources/PrecompiledHeadersUnitTests.cpp
index 9c1d856..9bda2a2 100644
--- a/UnitTestsSources/PrecompiledHeadersUnitTests.cpp
+++ b/UnitTestsSources/PrecompiledHeadersUnitTests.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/UnitTestsSources/PrecompiledHeadersUnitTests.h b/UnitTestsSources/PrecompiledHeadersUnitTests.h
index 4efcd72..8c3862d 100644
--- a/UnitTestsSources/PrecompiledHeadersUnitTests.h
+++ b/UnitTestsSources/PrecompiledHeadersUnitTests.h
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/UnitTestsSources/RestApiTests.cpp b/UnitTestsSources/RestApiTests.cpp
index 03102a6..7d0b690 100644
--- a/UnitTestsSources/RestApiTests.cpp
+++ b/UnitTestsSources/RestApiTests.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/UnitTestsSources/SQLiteChromiumTests.cpp b/UnitTestsSources/SQLiteChromiumTests.cpp
index 6afddfe..133ead2 100644
--- a/UnitTestsSources/SQLiteChromiumTests.cpp
+++ b/UnitTestsSources/SQLiteChromiumTests.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/UnitTestsSources/SQLiteTests.cpp b/UnitTestsSources/SQLiteTests.cpp
index 9b39ab9..c840724 100644
--- a/UnitTestsSources/SQLiteTests.cpp
+++ b/UnitTestsSources/SQLiteTests.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/UnitTestsSources/ServerIndexTests.cpp b/UnitTestsSources/ServerIndexTests.cpp
index 8fe8094..8ebc754 100644
--- a/UnitTestsSources/ServerIndexTests.cpp
+++ b/UnitTestsSources/ServerIndexTests.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/UnitTestsSources/StreamTests.cpp b/UnitTestsSources/StreamTests.cpp
index bf95796..54a73f4 100644
--- a/UnitTestsSources/StreamTests.cpp
+++ b/UnitTestsSources/StreamTests.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/UnitTestsSources/UnitTestsMain.cpp b/UnitTestsSources/UnitTestsMain.cpp
index 59c7193..775ecc0 100644
--- a/UnitTestsSources/UnitTestsMain.cpp
+++ b/UnitTestsSources/UnitTestsMain.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -526,14 +527,17 @@ TEST(EnumerationDictionary, ServerEnumerations)
   ASSERT_EQ(2047, StringToMetadata("Ceci est un test"));
 
   ASSERT_STREQ("Generic", EnumerationToString(StringToModalityManufacturer("Generic")));
+  ASSERT_STREQ("GenericNoWildcardInDates", EnumerationToString(StringToModalityManufacturer("GenericNoWildcardInDates")));
+  ASSERT_STREQ("GenericNoUniversalWildcard", EnumerationToString(StringToModalityManufacturer("GenericNoUniversalWildcard")));
   ASSERT_STREQ("StoreScp", EnumerationToString(StringToModalityManufacturer("StoreScp")));
   ASSERT_STREQ("ClearCanvas", EnumerationToString(StringToModalityManufacturer("ClearCanvas")));
-  ASSERT_STREQ("MedInria", EnumerationToString(StringToModalityManufacturer("MedInria")));
   ASSERT_STREQ("Dcm4Chee", EnumerationToString(StringToModalityManufacturer("Dcm4Chee")));
-  ASSERT_STREQ("SyngoVia", EnumerationToString(StringToModalityManufacturer("SyngoVia")));
-  ASSERT_STREQ("AgfaImpax", EnumerationToString(StringToModalityManufacturer("AgfaImpax")));
-  ASSERT_STREQ("EFilm2", EnumerationToString(StringToModalityManufacturer("EFilm2")));
   ASSERT_STREQ("Vitrea", EnumerationToString(StringToModalityManufacturer("Vitrea")));
+  // backward compatibility tests (to remove once we make these manufacturer really obsolete)
+  ASSERT_STREQ("Generic", EnumerationToString(StringToModalityManufacturer("MedInria")));
+  ASSERT_STREQ("Generic", EnumerationToString(StringToModalityManufacturer("EFilm2")));
+  ASSERT_STREQ("GenericNoWildcardInDates", EnumerationToString(StringToModalityManufacturer("SyngoVia")));
+  ASSERT_STREQ("GenericNoWildcardInDates", EnumerationToString(StringToModalityManufacturer("AgfaImpax")));
 }
 
 
@@ -630,6 +634,26 @@ TEST(Toolbox, Enumerations)
   ASSERT_EQ(ResourceType_Instance, StringToResourceType(EnumerationToString(ResourceType_Instance)));
 
   ASSERT_EQ(ImageFormat_Png, StringToImageFormat(EnumerationToString(ImageFormat_Png)));
+
+  ASSERT_EQ(PhotometricInterpretation_ARGB, StringToPhotometricInterpretation(EnumerationToString(PhotometricInterpretation_ARGB)));
+  ASSERT_EQ(PhotometricInterpretation_CMYK, StringToPhotometricInterpretation(EnumerationToString(PhotometricInterpretation_CMYK)));
+  ASSERT_EQ(PhotometricInterpretation_HSV, StringToPhotometricInterpretation(EnumerationToString(PhotometricInterpretation_HSV)));
+  ASSERT_EQ(PhotometricInterpretation_Monochrome1, StringToPhotometricInterpretation(EnumerationToString(PhotometricInterpretation_Monochrome1)));
+  ASSERT_EQ(PhotometricInterpretation_Monochrome2, StringToPhotometricInterpretation(EnumerationToString(PhotometricInterpretation_Monochrome2)));
+  ASSERT_EQ(PhotometricInterpretation_Palette, StringToPhotometricInterpretation(EnumerationToString(PhotometricInterpretation_Palette)));
+  ASSERT_EQ(PhotometricInterpretation_RGB, StringToPhotometricInterpretation(EnumerationToString(PhotometricInterpretation_RGB)));
+  ASSERT_EQ(PhotometricInterpretation_YBRFull, StringToPhotometricInterpretation(EnumerationToString(PhotometricInterpretation_YBRFull)));
+  ASSERT_EQ(PhotometricInterpretation_YBRFull422, StringToPhotometricInterpretation(EnumerationToString(PhotometricInterpretation_YBRFull422)));
+  ASSERT_EQ(PhotometricInterpretation_YBRPartial420, StringToPhotometricInterpretation(EnumerationToString(PhotometricInterpretation_YBRPartial420)));
+  ASSERT_EQ(PhotometricInterpretation_YBRPartial422, StringToPhotometricInterpretation(EnumerationToString(PhotometricInterpretation_YBRPartial422)));
+  ASSERT_EQ(PhotometricInterpretation_YBR_ICT, StringToPhotometricInterpretation(EnumerationToString(PhotometricInterpretation_YBR_ICT)));
+  ASSERT_EQ(PhotometricInterpretation_YBR_RCT, StringToPhotometricInterpretation(EnumerationToString(PhotometricInterpretation_YBR_RCT)));
+
+  ASSERT_STREQ("Unknown", EnumerationToString(PhotometricInterpretation_Unknown));
+  ASSERT_THROW(StringToPhotometricInterpretation("Unknown"), OrthancException);
+
+  ASSERT_EQ(DicomVersion_2008, StringToDicomVersion(EnumerationToString(DicomVersion_2008)));
+  ASSERT_EQ(DicomVersion_2017c, StringToDicomVersion(EnumerationToString(DicomVersion_2017c)));
 }
 
 
diff --git a/UnitTestsSources/VersionsTests.cpp b/UnitTestsSources/VersionsTests.cpp
index 193ce72..b649b76 100644
--- a/UnitTestsSources/VersionsTests.cpp
+++ b/UnitTestsSources/VersionsTests.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -102,7 +103,7 @@ TEST(Versions, ZlibStatic)
 
 TEST(Versions, BoostStatic)
 {
-  ASSERT_STREQ("1_60", BOOST_LIB_VERSION);
+  ASSERT_STREQ("1_64", BOOST_LIB_VERSION);
 }
 
 TEST(Versions, CurlStatic)
diff --git a/UnitTestsSources/ZipTests.cpp b/UnitTestsSources/ZipTests.cpp
index 5d0cc1e..ecabf77 100644
--- a/UnitTestsSources/ZipTests.cpp
+++ b/UnitTestsSources/ZipTests.cpp
@@ -2,6 +2,7 @@
  * Orthanc - A Lightweight, RESTful DICOM Store
  * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
  * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017 Osimis, Belgium
  *
  * This program is free software: you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/orthanc.git



More information about the debian-med-commit mailing list