changeset 2315:595919496bb3

integration issue-46-anonymization->mainline
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 12 Jul 2017 22:14:44 +0200
parents 06ff7e86638a (current diff) c54c9523adf8 (diff)
children 8bca2c8eaead
files
diffstat 11 files changed, 875 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Wed Jul 12 09:05:08 2017 +0200
+++ b/NEWS	Wed Jul 12 22:14:44 2017 +0200
@@ -5,6 +5,7 @@
 --------
 
 * Argument "Since" in URI "/tools/find" (related to issue 53)
+* Argument "DicomVersion" in URIs "/{...}/{...}/anonymization"
 
 Plugins
 -------
--- a/OrthancServer/DicomModification.cpp	Wed Jul 12 09:05:08 2017 +0200
+++ b/OrthancServer/DicomModification.cpp	Wed Jul 12 22:14:44 2017 +0200
@@ -41,7 +41,11 @@
 #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
 {
@@ -92,7 +96,8 @@
     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);
@@ -162,6 +167,7 @@
   void DicomModification::Keep(const DicomTag& tag)
   {
     removals_.erase(tag);
+    clearings_.erase(tag);
     RemoveInternal(tag);
 
     if (tag.IsPrivate())
@@ -185,6 +191,17 @@
   void DicomModification::Remove(const DicomTag& tag)
   {
     removals_.insert(tag);
+    clearings_.erase(tag);
+    RemoveInternal(tag);
+    privateTagsToKeep_.erase(tag);
+
+    MarkNotOrthancAnonymization();
+  }
+
+  void DicomModification::Clear(const DicomTag& tag)
+  {
+    removals_.erase(tag);
+    clearings_.insert(tag);
     RemoveInternal(tag);
     privateTagsToKeep_.erase(tag);
 
@@ -196,10 +213,16 @@
     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);
@@ -267,16 +290,12 @@
     }
   }
 
-  void DicomModification::SetupAnonymization()
+
+  void DicomModification::SetupAnonymization2008()
   {
-    removals_.clear();
-    ClearReplacements();
-    removePrivateTags_ = true;
-    level_ = ResourceType_Patient;
-    uidMap_.clear();
-    privateTagsToKeep_.clear();
-
     // 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
@@ -333,7 +352,589 @@
     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");
@@ -461,21 +1062,28 @@
       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))
     {
--- a/OrthancServer/DicomModification.h	Wed Jul 12 09:05:08 2017 +0200
+++ b/OrthancServer/DicomModification.h	Wed Jul 12 22:14:44 2017 +0200
@@ -52,6 +52,7 @@
     typedef std::map< std::pair<ResourceType, std::string>, std::string>  UidMap;
 
     SetOfTags removals_;
+    SetOfTags clearings_;
     Replacements replacements_;
     bool removePrivateTags_;
     ResourceType level_;
@@ -73,6 +74,10 @@
     void ReplaceInternal(const DicomTag& tag,
                          const Json::Value& value);
 
+    void SetupAnonymization2008();
+
+    void SetupAnonymization2017c();
+
   public:
     DicomModification();
 
@@ -82,11 +87,18 @@
 
     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;
 
@@ -108,7 +120,7 @@
       return level_;
     }
 
-    void SetupAnonymization();
+    void SetupAnonymization(DicomVersion version);
 
     void Apply(ParsedDicomFile& toModify);
 
--- a/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp	Wed Jul 12 09:05:08 2017 +0200
+++ b/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp	Wed Jul 12 22:14:44 2017 +0200
@@ -101,7 +101,7 @@
       const Json::Value& value = replacements[name];
 
       DicomTag tag = FromDcmtkBridge::ParseTag(name);
-      target.Replace(tag, value);
+      target.Replace(tag, value, false);
 
       VLOG(1) << "Replace: " << name << " " << tag 
               << " == " << value.toStyledString() << std::endl;
@@ -178,46 +178,60 @@
   {
     // 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 (request.isMember("KeepPrivateTags"))
-      {
-        target.SetRemovePrivateTags(false);
-      }
-
-      if (request.isMember("Remove"))
-      {
-        ParseListOfTags(target, request["Remove"], TagOperation_Remove);
-      }
-
-      if (request.isMember("Replace"))
-      {
-        ParseReplacements(target, request["Replace"]);
-      }
-
-      if (request.isMember("Keep"))
-      {
-        ParseListOfTags(target, request["Keep"], TagOperation_Keep);
-      }
-
-      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;
-    }
-    else
+    if (!call.ParseJsonRequest(request) ||
+        !request.isObject())
     {
       return false;
     }
+
+    // As of Orthanc 1.2.1, 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)
+      {
+        throw OrthancException(ErrorCode_BadFileFormat);
+      }
+      else
+      {
+        version = StringToDicomVersion(request["DicomVersion"].asString());
+      }
+    }
+        
+    target.SetupAnonymization(version);
+    std::string patientName = target.GetReplacementAsString(DICOM_TAG_PATIENT_NAME);
+
+    if (request.isMember("KeepPrivateTags"))
+    {
+      target.SetRemovePrivateTags(false);
+    }
+
+    if (request.isMember("Remove"))
+    {
+      ParseListOfTags(target, request["Remove"], TagOperation_Remove);
+    }
+
+    if (request.isMember("Replace"))
+    {
+      ParseReplacements(target, request["Replace"]);
+    }
+
+    if (request.isMember("Keep"))
+    {
+      ParseListOfTags(target, request["Keep"], TagOperation_Keep);
+    }
+
+    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;
   }
 
 
--- a/OrthancServer/ParsedDicomFile.cpp	Wed Jul 12 09:05:08 2017 +0200
+++ b/OrthancServer/ParsedDicomFile.cpp	Wed Jul 12 22:14:44 2017 +0200
@@ -508,6 +508,28 @@
   }
 
 
+  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)
   {
--- a/OrthancServer/ParsedDicomFile.h	Wed Jul 12 09:05:08 2017 +0200
+++ b/OrthancServer/ParsedDicomFile.h	Wed Jul 12 22:14:44 2017 +0200
@@ -96,6 +96,10 @@
 
     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,
--- a/OrthancServer/ServerEnumerations.cpp	Wed Jul 12 09:05:08 2017 +0200
+++ b/OrthancServer/ServerEnumerations.cpp	Wed Jul 12 22:14:44 2017 +0200
@@ -462,6 +462,41 @@
   }
 
 
+  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 &&
--- a/OrthancServer/ServerEnumerations.h	Wed Jul 12 09:05:08 2017 +0200
+++ b/OrthancServer/ServerEnumerations.h	Wed Jul 12 22:14:44 2017 +0200
@@ -135,6 +135,12 @@
     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
@@ -230,7 +236,11 @@
 
   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);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Resources/GenerateAnonymizationProfile.py	Wed Jul 12 22:14:44 2017 +0200
@@ -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)
--- a/UnitTestsSources/FromDcmtkTests.cpp	Wed Jul 12 09:05:08 2017 +0200
+++ b/UnitTestsSources/FromDcmtkTests.cpp	Wed Jul 12 22:14:44 2017 +0200
@@ -77,7 +77,7 @@
 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");
@@ -133,7 +133,7 @@
   ASSERT_FALSE(Toolbox::IsUuid(s));
 
   DicomModification m;
-  m.SetupAnonymization();
+  m.SetupAnonymization(DicomVersion_2008);
   m.Keep(privateTag);
 
   m.Apply(o);
@@ -143,7 +143,7 @@
   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));
 }
--- a/UnitTestsSources/UnitTestsMain.cpp	Wed Jul 12 09:05:08 2017 +0200
+++ b/UnitTestsSources/UnitTestsMain.cpp	Wed Jul 12 22:14:44 2017 +0200
@@ -648,6 +648,9 @@
 
   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)));
 }