Repository: pydicom/pynetdicom
Pull request #359 (2019-06-08 02:19:21)

[MRG] Add SOP classes and statuses for DIMSE N
* More preparation work for the remaining DIMSE-N classes
* Fix warning about empty transfer syntax

#### Tasks
 - [x] Unit tests added that reproduce issue or prove feature is working
 - [x] Fix or feature added
 - [x] Unit tests passing and coverage at 100% after adding fix/feature



Patch:
diff --git a/pynetdicom/pdu_items.py b/pynetdicom/pdu_items.py
index 73cffcd47..698e24b6c 100644
--- a/pynetdicom/pdu_items.py
+++ b/pynetdicom/pdu_items.py
@@ -856,9 +856,11 @@ class PresentationContextItemAC(PDUItem):
         primitive = PresentationContext()
         primitive.context_id = self.presentation_context_id
         primitive.result = self.result_reason
-        primitive.add_transfer_syntax(
-            self.transfer_syntax_sub_item[0].transfer_syntax_name
-        )
+        # May be `None` if context is rejected
+        if self.transfer_syntax_sub_item[0].transfer_syntax_name:
+            primitive.add_transfer_syntax(
+                self.transfer_syntax_sub_item[0].transfer_syntax_name
+            )
 
         return primitive
 
@@ -1611,7 +1613,7 @@ class TransferSyntaxSubItem(PDUItem):
             LOGGER.error("Transfer Syntax Name is an invalid UID")
             raise ValueError("Transfer Syntax Name is an invalid UID")
 
-        self._transfer_syntax_name = value
+        self._transfer_syntax_name = value or None
 
 
 ## User Information Item sub-items
diff --git a/pynetdicom/pdu_primitives.py b/pynetdicom/pdu_primitives.py
index b67aeb92e..5a919d3e2 100644
--- a/pynetdicom/pdu_primitives.py
+++ b/pynetdicom/pdu_primitives.py
@@ -2167,7 +2167,7 @@ class UserIdentityNegotiation(ServiceParameter):
     server_response : bytes or None
         A-ASSOCIATE-AC only. Shall contain the Kerberos Service ticket or SAML
         response if the `user_identity_type` in the Request was 3 or 4. Shall
-         be None if `user_identity_type` was 1 or 2.
+        be `None` if `user_identity_type` was 1 or 2.
 
     Examples
     --------
diff --git a/pynetdicom/presentation.py b/pynetdicom/presentation.py
index 639d363ab..8b31ca3fe 100644
--- a/pynetdicom/presentation.py
+++ b/pynetdicom/presentation.py
@@ -4,24 +4,30 @@ import logging
 
 from pydicom.uid import UID
 
+from pynetdicom._globals import DEFAULT_TRANSFER_SYNTAXES
 from pynetdicom.sop_class import (
-    _VERIFICATION_CLASSES,
-    _STORAGE_CLASSES,
-    _QR_CLASSES,
+    _APPLICATION_EVENT_CLASSES,
     _BASIC_WORKLIST_CLASSES,
-    _RELEVANT_PATIENT_QUERY_CLASSES,
-    _SUBSTANCE_ADMINISTRATION_CLASSES,
-    _NON_PATIENT_OBJECT_CLASSES,
-    _HANGING_PROTOCOL_CLASSES,
-    _DEFINED_PROCEDURE_CLASSES,
     _COLOR_PALETTE_CLASSES,
+    _DEFINED_PROCEDURE_CLASSES,
+    _DISPLAY_SYSTEM_CLASSES,
+    _HANGING_PROTOCOL_CLASSES,
     _IMPLANT_TEMPLATE_CLASSES,
-    #_PRINT_MANAGEMENT_CLASSES,
+    _INSTANCE_AVAILABILITY_CLASSES,
+    _MEDIA_CREATION_CLASSES,
+    _MEDIA_STORAGE_CLASSES,
+    _NON_PATIENT_OBJECT_CLASSES,
+    _PRINT_MANAGEMENT_CLASSES,
     _PROCEDURE_STEP_CLASSES,
-    _DISPLAY_SYSTEM_CLASSES,
-    #_MEDIA_STORAGE_CLASSES,
-    #_UNIFIED_PROCEDURE_STEP_CLASSES,
-    #_RT_MACHINE_VERIFICATION_CLASSES,
+    _PROTOCOL_APPROVAL_CLASSES,
+    _QR_CLASSES,
+    _RELEVANT_PATIENT_QUERY_CLASSES,
+    _RT_MACHINE_VERIFICATION_CLASSES,
+    _STORAGE_CLASSES,
+    _STORAGE_COMMITMENT_CLASSES,
+    _SUBSTANCE_ADMINISTRATION_CLASSES,
+    _UNIFIED_PROCEDURE_STEP_CLASSES,
+    _VERIFICATION_CLASSES,
 )
 from pynetdicom._globals import DEFAULT_TRANSFER_SYNTAXES
 from pynetdicom.utils import validate_uid
@@ -30,11 +36,11 @@ from pynetdicom.utils import validate_uid
 LOGGER = logging.getLogger('pynetdicom.presentation')
 
 
-# Used with the on_c_* callbacks to give the users access to the context
-PresentationContextTuple = namedtuple('PresentationContextTuple',
-                                      ['context_id',
-                                       'abstract_syntax',
-                                       'transfer_syntax'])
+# Used with the event handlers to give the users access to the context
+PresentationContextTuple = namedtuple(
+    'PresentationContextTuple',
+    ['context_id', 'abstract_syntax', 'transfer_syntax']
+)
 
 
 DEFAULT_ROLE = (True, False, False, True)
@@ -42,7 +48,7 @@ BOTH_SCU_SCP_ROLE = (True, True, True, True)
 CONTEXT_REJECTED = (False, False, False, False)
 INVERTED_ROLE = (False, True, True, False)
 SCP_SCU_ROLES = {
-    # Req role, ac role, Outcome
+    # (Requestor role, Acceptor role) : Outcome
     # No SCP/SCU Role Selection proposed
     (None, None) : {
         (None, None) : DEFAULT_ROLE,
@@ -600,7 +606,7 @@ def negotiate_as_acceptor(rq_contexts, ac_contexts, roles=None):
                     # Default roles
                     context._as_scu = False
                     context._as_scp = True
-                    # If either aq.scu_role or ac.scp_role is None then
+                    # If either ac.scu_role or ac.scp_role is None then
                     #   don't send an SCP/SCU negotiation reply
                     has_role = False
                 else:
@@ -860,54 +866,72 @@ def build_role(uid, scu_role=False, scp_role=False):
 
 # Service specific pre-generated Presentation Contexts
 # pylint: disable=line-too-long,invalid-name
-VerificationPresentationContexts = [
-    build_context(uid) for uid in sorted(_VERIFICATION_CLASSES.values())
+ApplicationEventLoggingPresentationContexts = [
+    build_context(uid) for uid in sorted(_APPLICATION_EVENT_CLASSES.values())
 ]
-
-StoragePresentationContexts = [
-    build_context(uid) for uid in sorted(_STORAGE_CLASSES.values())[:128]
-]
-
-QueryRetrievePresentationContexts = [
-    build_context(uid) for uid in sorted(_QR_CLASSES.values())
-]
-
 BasicWorklistManagementPresentationContexts = [
     build_context(uid) for uid in sorted(_BASIC_WORKLIST_CLASSES.values())
 ]
-
-RelevantPatientInformationPresentationContexts = [
-    build_context(uid) for uid in sorted(_RELEVANT_PATIENT_QUERY_CLASSES.values())
+ColorPalettePresentationContexts = [
+    build_context(uid) for uid in sorted(_COLOR_PALETTE_CLASSES.values())
 ]
-
-SubstanceAdministrationPresentationContexts = [
-    build_context(uid) for uid in sorted(_SUBSTANCE_ADMINISTRATION_CLASSES.values())
+DefinedProcedureProtocolPresentationContexts = [
+    build_context(uid) for uid in sorted(_DEFINED_PROCEDURE_CLASSES.values())
 ]
-
-NonPatientObjectPresentationContexts = [
-    build_context(uid) for uid in sorted(_NON_PATIENT_OBJECT_CLASSES.values())
+DisplaySystemPresentationContexts = [
+    build_context(uid) for uid in sorted(_DISPLAY_SYSTEM_CLASSES.values())
 ]
-
 HangingProtocolPresentationContexts = [
     build_context(uid) for uid in sorted(_HANGING_PROTOCOL_CLASSES.values())
 ]
-
-DefinedProcedureProtocolPresentationContexts = [
-    build_context(uid) for uid in sorted(_DEFINED_PROCEDURE_CLASSES.values())
-]
-
-ColorPalettePresentationContexts = [
-    build_context(uid) for uid in sorted(_COLOR_PALETTE_CLASSES.values())
-]
-
 ImplantTemplatePresentationContexts = [
     build_context(uid) for uid in sorted(_IMPLANT_TEMPLATE_CLASSES.values())
 ]
-
-DisplaySystemPresentationContexts = [
-    build_context(uid) for uid in sorted(_DISPLAY_SYSTEM_CLASSES.values())
+InstanceAvailabilityPresentationContexts = [
+    build_context(uid) for uid in sorted(_INSTANCE_AVAILABILITY_CLASSES.values())
+]
+MediaCreationManagementPresentationContexts = [
+    build_context(uid) for uid in sorted(_MEDIA_CREATION_CLASSES.values())
+]
+MediaStoragePresentationContexts = [
+    build_context(uid) for uid in sorted(_MEDIA_STORAGE_CLASSES.values())
 ]
-
 ModalityPerformedPresentationContexts = [
     build_context(uid) for uid in sorted(_PROCEDURE_STEP_CLASSES.values())
 ]
+NonPatientObjectPresentationContexts = [
+    build_context(uid) for uid in sorted(_NON_PATIENT_OBJECT_CLASSES.values())
+]
+PrintManagementPresentationContexts = [
+    build_context(uid) for uid in sorted(_PRINT_MANAGEMENT_CLASSES.values())
+]
+ProcedureStepPresentationContexts = [
+    build_context(uid) for uid in sorted(_PROCEDURE_STEP_CLASSES.values())
+]
+ProtocolApprovalPresentationContexts = [
+    build_context(uid) for uid in sorted(_PROTOCOL_APPROVAL_CLASSES.values())
+]
+QueryRetrievePresentationContexts = [
+    build_context(uid) for uid in sorted(_QR_CLASSES.values())
+]
+RelevantPatientInformationPresentationContexts = [
+    build_context(uid) for uid in sorted(_RELEVANT_PATIENT_QUERY_CLASSES.values())
+]
+RTMachineVerificationPresentationContexts = [
+    build_context(uid) for uid in sorted(_RT_MACHINE_VERIFICATION_CLASSES.values())
+]
+StoragePresentationContexts = [
+    build_context(uid) for uid in sorted(_STORAGE_CLASSES.values())[:128]
+]
+StorageCommitmentPresentationContexts = [
+    build_context(uid) for uid in sorted(_STORAGE_COMMITMENT_CLASSES.values())
+]
+SubstanceAdministrationPresentationContexts = [
+    build_context(uid) for uid in sorted(_SUBSTANCE_ADMINISTRATION_CLASSES.values())
+]
+UnifiedProcedurePresentationContexts = [
+    build_context(uid) for uid in sorted(_UNIFIED_PROCEDURE_STEP_CLASSES.values())
+]
+VerificationPresentationContexts = [
+    build_context(uid) for uid in sorted(_VERIFICATION_CLASSES.values())
+]
diff --git a/pynetdicom/service_class_n.py b/pynetdicom/service_class_n.py
index 8bbf3ec09..23b1c9105 100644
--- a/pynetdicom/service_class_n.py
+++ b/pynetdicom/service_class_n.py
@@ -10,7 +10,7 @@ from pynetdicom.dimse_primitives import (
 )
 from pynetdicom.service_class import ServiceClass
 from pynetdicom.status import (
-    GENERAL_STATUS, code_to_category, _PROCEDURE_STEP_STATUS
+    GENERAL_STATUS, code_to_category, PROCEDURE_STEP_STATUS
 )
 from pynetdicom._globals import (
     STATUS_FAILURE,
@@ -125,7 +125,7 @@ class DisplaySystemManagementServiceClass(ServiceClass):
 
 class ModalityPerformedProcedureStepServiceClass(ServiceClass):
     """Implementation of the Modality Performed Procedure Step Service Class"""
-    statuses = _PROCEDURE_STEP_STATUS
+    statuses = PROCEDURE_STEP_STATUS
 
     def SCP(self, req, context):
         """
diff --git a/pynetdicom/sop_class.py b/pynetdicom/sop_class.py
index 667ce0a87..75db4df3b 100644
--- a/pynetdicom/sop_class.py
+++ b/pynetdicom/sop_class.py
@@ -7,19 +7,19 @@ import sys
 from pydicom.uid import UID
 
 from pynetdicom.service_class import (
-    ServiceClass,
-    VerificationServiceClass,
-    StorageServiceClass,
-    QueryRetrieveServiceClass,
     BasicWorklistManagementServiceClass,
-    RelevantPatientInformationQueryServiceClass,
-    SubstanceAdministrationQueryServiceClass,
-    NonPatientObjectStorageServiceClass,
-    HangingProtocolQueryRetrieveServiceClass,
-    DefinedProcedureProtocolQueryRetrieveServiceClass,
     ColorPaletteQueryRetrieveServiceClass,
+    DefinedProcedureProtocolQueryRetrieveServiceClass,
+    HangingProtocolQueryRetrieveServiceClass,
     ImplantTemplateQueryRetrieveServiceClass,
+    NonPatientObjectStorageServiceClass,
     ProtocolApprovalQueryRetrieveServiceClass,
+    QueryRetrieveServiceClass,
+    RelevantPatientInformationQueryServiceClass,
+    ServiceClass,
+    StorageServiceClass,
+    SubstanceAdministrationQueryServiceClass,
+    VerificationServiceClass,
 )
 from pynetdicom.service_class_n import (
     DisplaySystemManagementServiceClass,
@@ -47,42 +47,50 @@ def uid_to_service_class(uid):
     """
     if uid in _SERVICE_CLASSES:
         return _SERVICE_CLASSES[uid]
-    elif uid in _VERIFICATION_CLASSES.values():
-        return VerificationServiceClass
-    elif uid in _STORAGE_CLASSES.values():
-        return StorageServiceClass
-    elif uid in _QR_CLASSES.values():
-        return QueryRetrieveServiceClass
+    elif uid in _APPLICATION_EVENT_CLASSES.values():
+        return ServiceClass  # Not yet implemented
     elif uid in _BASIC_WORKLIST_CLASSES.values():
         return BasicWorklistManagementServiceClass
-    elif uid in _RELEVANT_PATIENT_QUERY_CLASSES.values():
-        return RelevantPatientInformationQueryServiceClass
-    elif uid in _SUBSTANCE_ADMINISTRATION_CLASSES.values():
-        return SubstanceAdministrationQueryServiceClass
-    elif uid in _NON_PATIENT_OBJECT_CLASSES.values():
-        return NonPatientObjectStorageServiceClass
-    elif uid in _HANGING_PROTOCOL_CLASSES.values():
-        return HangingProtocolQueryRetrieveServiceClass
-    elif uid in _DEFINED_PROCEDURE_CLASSES.values():
-        return DefinedProcedureProtocolQueryRetrieveServiceClass
     elif uid in _COLOR_PALETTE_CLASSES.values():
         return ColorPaletteQueryRetrieveServiceClass
-    elif uid in _IMPLANT_TEMPLATE_CLASSES.values():
-        return ImplantTemplateQueryRetrieveServiceClass
+    elif uid in _DEFINED_PROCEDURE_CLASSES.values():
+        return DefinedProcedureProtocolQueryRetrieveServiceClass
     elif uid in _DISPLAY_SYSTEM_CLASSES.values():
         return DisplaySystemManagementServiceClass
+    elif uid in _HANGING_PROTOCOL_CLASSES.values():
+        return HangingProtocolQueryRetrieveServiceClass
+    elif uid in _IMPLANT_TEMPLATE_CLASSES.values():
+        return ImplantTemplateQueryRetrieveServiceClass
+    elif uid in _INSTANCE_AVAILABILITY_CLASSES.values():
+        return ServiceClass  # Not yet implemented
+    elif uid in _MEDIA_CREATION_CLASSES.values():
+        return ServiceClass  # Not yet implemented
+    elif uid in _MEDIA_STORAGE_CLASSES.values():
+        return ServiceClass  # Not yet implemented
+    elif uid in _NON_PATIENT_OBJECT_CLASSES.values():
+        return NonPatientObjectStorageServiceClass
     elif uid in _PRINT_MANAGEMENT_CLASSES.values():
         return ServiceClass  # Not yet implemented
     elif uid in _PROCEDURE_STEP_CLASSES.values():
         return ModalityPerformedProcedureStepServiceClass
-    elif uid in _MEDIA_STORAGE_CLASSES.values():
+    elif uid in _PROTOCOL_APPROVAL_CLASSES.values():
+        return ProtocolApprovalQueryRetrieveServiceClass
+    elif uid in _QR_CLASSES.values():
+        return QueryRetrieveServiceClass
+    elif uid in _RELEVANT_PATIENT_QUERY_CLASSES.values():
+        return RelevantPatientInformationQueryServiceClass
+    elif uid in _RT_MACHINE_VERIFICATION_CLASSES.values():
         return ServiceClass  # Not yet implemented
-    elif uid in _UNIFIED_PROCEDURE_STEP_CLASSES.values():
+    elif uid in _STORAGE_CLASSES.values():
+        return StorageServiceClass
+    elif uid in _STORAGE_COMMITMENT_CLASSES.values():
         return ServiceClass  # Not yet implemented
-    elif uid in _RT_MACHINE_VERIFICATION_CLASSES.values():
+    elif uid in _SUBSTANCE_ADMINISTRATION_CLASSES.values():
+        return SubstanceAdministrationQueryServiceClass
+    elif uid in _UNIFIED_PROCEDURE_STEP_CLASSES.values():
         return ServiceClass  # Not yet implemented
-    elif uid in _PROTOCOL_APPROVAL_SOP_CLASSES.values():
-        return ProtocolApprovalQueryRetrieveServiceClass
+    elif uid in _VERIFICATION_CLASSES.values():
+        return VerificationServiceClass
 
     # No SCP implemented
     return ServiceClass
@@ -118,15 +126,114 @@ def _generate_sop_classes(sop_class_dict):
 # Table of service classes with assigned UIDs
 _SERVICE_CLASSES = {
     '1.2.840.10008.4.2' : StorageServiceClass,
-    #'1.2.840.10008.5.1.4.34.6', UnifiedProcedureStepServiceClass,
+    #'1.2.840.10008.5.1.4.34.6' : UnifiedProcedureStepServiceClass,
 }
 
 # Generate the various SOP classes
-_VERIFICATION_CLASSES = {
-    'VerificationSOPClass' : '1.2.840.10008.1.1',
-}
-
 # pylint: disable=line-too-long
+_APPLICATION_EVENT_CLASSES = {
+    'ProceduralEventLoggingSOPClass' : '1.2.840.10008.1.40',
+    'SubstanceAdministrationLoggingSOPClass' : '1.2.840.10008.1.42',
+}
+_BASIC_WORKLIST_CLASSES = {
+    'ModalityWorklistInformationFind' : '1.2.840.10008.5.1.4.31',
+}
+_COLOR_PALETTE_CLASSES = {
+    'ColorPaletteInformationModelFind' : '1.2.840.10008.5.1.4.39.2',
+    'ColorPaletteInformationModelMove' : '1.2.840.10008.5.1.4.39.3',
+    'ColorPaletteInformationModelGet' : '1.2.840.10008.5.1.4.39.4',
+}
+_DEFINED_PROCEDURE_CLASSES = {
+    'DefinedProcedureProtocolInformationModelFind' : '1.2.840.10008.5.1.4.20.1',
+    'DefinedProcedureProtocolInformationModelMove' : '1.2.840.10008.5.1.4.20.2',
+    'DefinedProcedureProtocolInformationModelGet' : '1.2.840.10008.5.1.4.20.3',
+}
+_DISPLAY_SYSTEM_CLASSES = {
+    'DisplaySystemSOPClass' : '1.2.840.10008.5.1.1.40',
+}
+_HANGING_PROTOCOL_CLASSES = {
+    'HangingProtocolInformationModelFind' : '1.2.840.10008.5.1.4.38.2',
+    'HangingProtocolInformationModelMove' : '1.2.840.10008.5.1.4.38.3',
+    'HangingProtocolInformationModelGet' : '1.2.840.10008.5.1.4.38.4',
+}
+_IMPLANT_TEMPLATE_CLASSES = {
+    'GenericImplantTemplateInformationModelFind' : '1.2.840.10008.5.1.4.43.2',
+    'GenericImplantTemplateInformationModelMove' : '1.2.840.10008.5.1.4.43.3',
+    'GenericImplantTemplateInformationModelGet' : '1.2.840.10008.5.1.4.43.4',
+    'ImplantAssemblyTemplateInformationModelFind' : '1.2.840.10008.5.1.4.44.2',
+    'ImplantAssemblyTemplateInformationModelMove' : '1.2.840.10008.5.1.4.44.3',
+    'ImplantAssemblyTemplateInformationModelGet' : '1.2.840.10008.5.1.4.44.4',
+    'ImplantTemplateGroupInformationModelFind' : '1.2.840.10008.5.1.4.45.2',
+    'ImplantTemplateGroupInformationModelMove' : '1.2.840.10008.5.1.4.45.3',
+    'ImplantTemplateGroupInformationModelGet' : '1.2.840.10008.5.1.4.45.4',
+}
+_INSTANCE_AVAILABILITY_CLASSES = {
+    'InstanceAvailabilityNotificationSOPClass' : '1.2.840.10008.5.1.4.33',
+}
+_MEDIA_CREATION_CLASSES = {
+    'MediaCreationManagementSOPClass' : '1.2.840.10008.5.1.1.33',
+}
+_MEDIA_STORAGE_CLASSES = {
+    'MediaStorageDirectoryStorage' : '1.2.840.10008.1.3.10',
+}
+_NON_PATIENT_OBJECT_CLASSES = {
+    'HangingProtocolStorage' : '1.2.840.10008.5.1.4.38.1',
+    'ColorPaletteStorage' : '1.2.840.10008.5.1.4.39.1',
+    'GenericImplantTemplateStorage' : '1.2.840.10008.5.1.4.43.1',
+    'ImplantAssemblyTemplateStorage' : '1.2.840.10008.5.1.4.44.1',
+    'ImplantTemplateGroupStorage' : '1.2.840.10008.5.1.4.45.1',
+    'CTDefinedProcedureProtocolStorage' : '1.2.840.10008.5.1.4.1.1.200.1',
+    'ProtocolApprovalStorage' : '1.2.840.10008.5.1.4.1.1.200.3',
+}
+_PRINT_MANAGEMENT_CLASSES = {
+    'BasicFilmSessionSOPClass' : '1.2.840.10008.5.1.1.1',
+    'BasicFilmBoxSOPClass' : '1.2.840.10008.5.1.1.2',
+    'BasicGrayscaleImageBoxSOPClass' : '1.2.840.10008.5.1.1.4',
+    'BasicColourImageBoxSOPClass' : '1.2.840.10008.5.1.1.4.1',
+    'PrintJobSOPClass' : '1.2.840.10008.5.1.1.14',
+    'BasicAnnotationBoxSOPClass' : '1.2.840.10008.5.1.1.15',
+    'PrinterSOPClass' : '1.2.840.10008.5.1.1.16',
+    'PrinterConfigurationRetrievalSOPClass' : '1.2.840.10008.5.1.1.16.376',
+    'PresentationLUTSOPClass' : '1.2.840.10008.5.1.1.23',
+    # Print Management Meta SOP Classes
+    # Basic Film Session, Basic Film Box, Basic Grayscale, Printer
+    'BasicGrayscalePrintManagementMetaSOPClass' : '1.2.840.10008.5.1.1.9',
+    # Basic Film Session, Basic Film Box, Basic Color, Printer
+    'BasicColorPrintManagementMetaSOPClass' : '1.2.840.10008.5.1.1.18',
+}
+_PROCEDURE_STEP_CLASSES = {
+    'ModalityPerformedProcedureStepSOPClass' : '1.2.840.10008.3.1.2.3.3',
+    'ModalityPerformedProcedureStepRetrieveSOPClass' : '1.2.840.10008.3.1.2.3.4',
+    'ModalityPerformedProcedureStepNotificationSOPClass' : '1.2.840.10008.3.1.2.3.5',
+}
+_PROTOCOL_APPROVAL_CLASSES = {
+    'ProtocolApprovalInformationModelFind' : '1.2.840.10008.5.1.4.1.1.200.4',
+    'ProtocolApprovalInformationModelMove' : '1.2.840.10008.5.1.4.1.1.200.5',
+    'ProtocolApprovalInformationModelGet' : '1.2.840.10008.5.1.4.1.1.200.6'
+}
+_QR_CLASSES = {
+    'PatientRootQueryRetrieveInformationModelFind' : '1.2.840.10008.5.1.4.1.2.1.1',
+    'PatientRootQueryRetrieveInformationModelMove' : '1.2.840.10008.5.1.4.1.2.1.2',
+    'PatientRootQueryRetrieveInformationModelGet' : '1.2.840.10008.5.1.4.1.2.1.3',
+    'StudyRootQueryRetrieveInformationModelFind' : '1.2.840.10008.5.1.4.1.2.2.1',
+    'StudyRootQueryRetrieveInformationModelMove' : '1.2.840.10008.5.1.4.1.2.2.2',
+    'StudyRootQueryRetrieveInformationModelGet' : '1.2.840.10008.5.1.4.1.2.2.3',
+    'PatientStudyOnlyQueryRetrieveInformationModelFind' : '1.2.840.10008.5.1.4.1.2.3.1',
+    'PatientStudyOnlyQueryRetrieveInformationModelMove' : '1.2.840.10008.5.1.4.1.2.3.2',
+    'PatientStudyOnlyQueryRetrieveInformationModelGet' : '1.2.840.10008.5.1.4.1.2.3.3',
+    'CompositeInstanceRootRetrieveMove' : '1.2.840.10008.5.1.4.1.2.4.2',
+    'CompositeInstanceRootRetrieveGet' : '1.2.840.10008.5.1.4.1.2.4.3',
+    'CompositeInstanceRetrieveWithoutBulkDataGet' : '1.2.840.10008.5.1.4.1.2.5.3',
+}
+_RELEVANT_PATIENT_QUERY_CLASSES = {
+    'GeneralRelevantPatientInformationQuery' : '1.2.840.10008.5.1.4.37.1',
+    'BreastImagingRelevantPatientInformationQuery' : '1.2.840.10008.5.1.4.37.2',
+    'CardiacRelevantPatientInformationQuery' : '1.2.840.10008.5.1.4.37.3',
+}
+_RT_MACHINE_VERIFICATION_CLASSES = {
+    'RTConventionalMachineVerification' : '1.2.840.10008.5.1.4.34.8',
+    'RTIonMachineVerification' : '1.2.840.10008.5.1.4.34.9',
+}
 _STORAGE_CLASSES = {
     'ComputedRadiographyImageStorage' : '1.2.840.10008.5.1.4.1.1.1',  # A.2
     'DigitalXRayImagePresentationStorage' : '1.2.840.10008.5.1.4.1.1.1.1',  # A.26
@@ -259,142 +366,46 @@ _STORAGE_CLASSES = {
     'RTBeamsDeliveryInstructionStorage' : '1.2.840.10008.5.1.4.34.7',  # A.64
     'RTBrachyApplicationSetupDeliveryInstructionsStorage' : '1.2.840.10008.5.1.4.34.10',  # A.79
 }
-
-_QR_CLASSES = {
-    'PatientRootQueryRetrieveInformationModelFind' : '1.2.840.10008.5.1.4.1.2.1.1',
-    'PatientRootQueryRetrieveInformationModelMove' : '1.2.840.10008.5.1.4.1.2.1.2',
-    'PatientRootQueryRetrieveInformationModelGet' : '1.2.840.10008.5.1.4.1.2.1.3',
-    'StudyRootQueryRetrieveInformationModelFind' : '1.2.840.10008.5.1.4.1.2.2.1',
-    'StudyRootQueryRetrieveInformationModelMove' : '1.2.840.10008.5.1.4.1.2.2.2',
-    'StudyRootQueryRetrieveInformationModelGet' : '1.2.840.10008.5.1.4.1.2.2.3',
-    'PatientStudyOnlyQueryRetrieveInformationModelFind' : '1.2.840.10008.5.1.4.1.2.3.1',
-    'PatientStudyOnlyQueryRetrieveInformationModelMove' : '1.2.840.10008.5.1.4.1.2.3.2',
-    'PatientStudyOnlyQueryRetrieveInformationModelGet' : '1.2.840.10008.5.1.4.1.2.3.3',
-    'CompositeInstanceRootRetrieveMove' : '1.2.840.10008.5.1.4.1.2.4.2',
-    'CompositeInstanceRootRetrieveGet' : '1.2.840.10008.5.1.4.1.2.4.3',
-    'CompositeInstanceRetrieveWithoutBulkDataGet' : '1.2.840.10008.5.1.4.1.2.5.3',
-}
-
-_BASIC_WORKLIST_CLASSES = {
-    'ModalityWorklistInformationFind' : '1.2.840.10008.5.1.4.31',
-}
-
-_RELEVANT_PATIENT_QUERY_CLASSES = {
-    'GeneralRelevantPatientInformationQuery' : '1.2.840.10008.5.1.4.37.1',
-    'BreastImagingRelevantPatientInformationQuery' : '1.2.840.10008.5.1.4.37.2',
-    'CardiacRelevantPatientInformationQuery' : '1.2.840.10008.5.1.4.37.3',
+_STORAGE_COMMITMENT_CLASSES = {
+    'StorageCommitmentPushModelSOPClass' : '1.2.840.10008.1.20.1',
 }
-
 _SUBSTANCE_ADMINISTRATION_CLASSES = {
     'ProductCharacteristicsQueryInformationModelFind' : '1.2.840.10008.5.1.4.41',
     'SubstanceApprovalQueryInformationModelFind' : '1.2.840.10008.5.1.4.42'
 }
-
-_NON_PATIENT_OBJECT_CLASSES = {
-    'HangingProtocolStorage' : '1.2.840.10008.5.1.4.38.1',
-    'ColorPaletteStorage' : '1.2.840.10008.5.1.4.39.1',
-    'GenericImplantTemplateStorage' : '1.2.840.10008.5.1.4.43.1',
-    'ImplantAssemblyTemplateStorage' : '1.2.840.10008.5.1.4.44.1',
-    'ImplantTemplateGroupStorage' : '1.2.840.10008.5.1.4.45.1',
-    'CTDefinedProcedureProtocolStorage' : '1.2.840.10008.5.1.4.1.1.200.1',
-    'ProtocolApprovalStorage' : '1.2.840.10008.5.1.4.1.1.200.3',
-}
-
-_HANGING_PROTOCOL_CLASSES = {
-    'HangingProtocolInformationModelFind' : '1.2.840.10008.5.1.4.38.2',
-    'HangingProtocolInformationModelMove' : '1.2.840.10008.5.1.4.38.3',
-    'HangingProtocolInformationModelGet' : '1.2.840.10008.5.1.4.38.4',
-}
-
-_DEFINED_PROCEDURE_CLASSES = {
-    'DefinedProcedureProtocolInformationModelFind' : '1.2.840.10008.5.1.4.20.1',
-    'DefinedProcedureProtocolInformationModelMove' : '1.2.840.10008.5.1.4.20.2',
-    'DefinedProcedureProtocolInformationModelGet' : '1.2.840.10008.5.1.4.20.3',
-}
-
-_COLOR_PALETTE_CLASSES = {
-    'ColorPaletteInformationModelFind' : '1.2.840.10008.5.1.4.39.2',
-    'ColorPaletteInformationModelMove' : '1.2.840.10008.5.1.4.39.3',
-    'ColorPaletteInformationModelGet' : '1.2.840.10008.5.1.4.39.4',
-}
-
-_IMPLANT_TEMPLATE_CLASSES = {
-    'GenericImplantTemplateInformationModelFind' : '1.2.840.10008.5.1.4.43.2',
-    'GenericImplantTemplateInformationModelMove' : '1.2.840.10008.5.1.4.43.3',
-    'GenericImplantTemplateInformationModelGet' : '1.2.840.10008.5.1.4.43.4',
-    'ImplantAssemblyTemplateInformationModelFind' : '1.2.840.10008.5.1.4.44.2',
-    'ImplantAssemblyTemplateInformationModelMove' : '1.2.840.10008.5.1.4.44.3',
-    'ImplantAssemblyTemplateInformationModelGet' : '1.2.840.10008.5.1.4.44.4',
-    'ImplantTemplateGroupInformationModelFind' : '1.2.840.10008.5.1.4.45.2',
-    'ImplantTemplateGroupInformationModelMove' : '1.2.840.10008.5.1.4.45.3',
-    'ImplantTemplateGroupInformationModelGet' : '1.2.840.10008.5.1.4.45.4',
-}
-
-_DISPLAY_SYSTEM_CLASSES = {
-    'DisplaySystemSOPClass' : '1.2.840.10008.5.1.1.40',
-}
-
-_PRINT_MANAGEMENT_CLASSES = {
-    'BasicFilmSessionSOPClass' : '1.2.840.10008.5.1.1.1',
-    'BasicFilmBoxSOPClass' : '1.2.840.10008.5.1.1.2',
-    'BasicGrayscaleImageBoxSOPClass' : '1.2.840.10008.5.1.1.4',
-    'BasicColourImageBoxSOPClass' : '1.2.840.10008.5.1.1.4.1',
-    'BasicGrayscalePrintManagementMetaSOPClass' : '1.2.840.10008.5.1.1.9',
-    'PrintJobSOPClass' : '1.2.840.10008.5.1.1.14',
-    'BasicAnnotationBoxSOPClass' : '1.2.840.10008.5.1.1.15',
-    'PrinterSOPClass' : '1.2.840.10008.5.1.1.16',
-    'PrinterConfigurationRetrievalSOPClass' : '1.2.840.10008.5.1.1.16.376',
-    'BasicColorPrintManagementMetaSOPClass' : '1.2.840.10008.5.1.1.18',
-    'PresentationLUTSOPClass' : '1.2.840.10008.5.1.1.23',
-}
-
-_PROCEDURE_STEP_CLASSES = {
-    'ModalityPerformedProcedureStepSOPClass' : '1.2.840.10008.3.1.2.3.3',
-    'ModalityPerformedProcedureStepRetrieveSOPClass' : '1.2.840.10008.3.1.2.3.4',
-    'ModalityPerformedProcedureStepNotificationSOPClass' : '1.2.840.10008.3.1.2.3.5',
-}
-
-_MEDIA_STORAGE_CLASSES = {
-    'MediaStorageDirectoryStorage' : '1.2.840.10008.1.3.10',
-}
-
 _UNIFIED_PROCEDURE_STEP_CLASSES = {
-    'UnifiedProcedureStepPush' : '1.2.840.10008.5.1.4.34.6.1',
-    'UnifiedProcedureStepWatch' : '1.2.840.10008.5.1.4.34.6.2',
-    'UnifiedProcedureStepPull' : '1.2.840.10008.5.1.4.34.6.3',
-    'UnifiedProcedureStepEvent' : '1.2.840.10008.5.1.4.34.6.4',
+    'UnifiedProcedureStepPushSOPClass' : '1.2.840.10008.5.1.4.34.6.1',
+    'UnifiedProcedureStepWatchSOPClass' : '1.2.840.10008.5.1.4.34.6.2',
+    'UnifiedProcedureStepPullSOPClass' : '1.2.840.10008.5.1.4.34.6.3',
+    'UnifiedProcedureStepEventSOPClass' : '1.2.840.10008.5.1.4.34.6.4',
 }
-
-_RT_MACHINE_VERIFICATION_CLASSES = {
-    'RTConventionalMachineVerification' : '1.2.840.10008.5.1.4.34.8',
-    'RTIonMachineVerification' : '1.2.840.10008.5.1.4.34.9',
-}
-
-_PROTOCOL_APPROVAL_SOP_CLASSES = {
-    'ProtocolApprovalInformationModelFind' : '1.2.840.10008.5.1.4.1.1.200.4',
-    'ProtocolApprovalInformationModelMove' : '1.2.840.10008.5.1.4.1.1.200.5',
-    'ProtocolApprovalInformationModelGet' : '1.2.840.10008.5.1.4.1.1.200.6'
+_VERIFICATION_CLASSES = {
+    'VerificationSOPClass' : '1.2.840.10008.1.1',
 }
 
 # pylint: enable=line-too-long
-_generate_sop_classes(_VERIFICATION_CLASSES)
-_generate_sop_classes(_STORAGE_CLASSES)
-_generate_sop_classes(_QR_CLASSES)
+_generate_sop_classes(_APPLICATION_EVENT_CLASSES)
 _generate_sop_classes(_BASIC_WORKLIST_CLASSES)
-_generate_sop_classes(_RELEVANT_PATIENT_QUERY_CLASSES)
-_generate_sop_classes(_SUBSTANCE_ADMINISTRATION_CLASSES)
-_generate_sop_classes(_NON_PATIENT_OBJECT_CLASSES)
-_generate_sop_classes(_HANGING_PROTOCOL_CLASSES)
-_generate_sop_classes(_DEFINED_PROCEDURE_CLASSES)
 _generate_sop_classes(_COLOR_PALETTE_CLASSES)
-_generate_sop_classes(_IMPLANT_TEMPLATE_CLASSES)
+_generate_sop_classes(_DEFINED_PROCEDURE_CLASSES)
 _generate_sop_classes(_DISPLAY_SYSTEM_CLASSES)
+_generate_sop_classes(_HANGING_PROTOCOL_CLASSES)
+_generate_sop_classes(_IMPLANT_TEMPLATE_CLASSES)
+_generate_sop_classes(_INSTANCE_AVAILABILITY_CLASSES)
+_generate_sop_classes(_MEDIA_CREATION_CLASSES)
+_generate_sop_classes(_MEDIA_STORAGE_CLASSES)
+_generate_sop_classes(_NON_PATIENT_OBJECT_CLASSES)
 _generate_sop_classes(_PRINT_MANAGEMENT_CLASSES)
 _generate_sop_classes(_PROCEDURE_STEP_CLASSES)
-_generate_sop_classes(_MEDIA_STORAGE_CLASSES)
-_generate_sop_classes(_UNIFIED_PROCEDURE_STEP_CLASSES)
+_generate_sop_classes(_PROTOCOL_APPROVAL_CLASSES)
+_generate_sop_classes(_QR_CLASSES)
+_generate_sop_classes(_RELEVANT_PATIENT_QUERY_CLASSES)
 _generate_sop_classes(_RT_MACHINE_VERIFICATION_CLASSES)
-_generate_sop_classes(_PROTOCOL_APPROVAL_SOP_CLASSES)
+_generate_sop_classes(_STORAGE_CLASSES)
+_generate_sop_classes(_STORAGE_COMMITMENT_CLASSES)
+_generate_sop_classes(_SUBSTANCE_ADMINISTRATION_CLASSES)
+_generate_sop_classes(_UNIFIED_PROCEDURE_STEP_CLASSES)
+_generate_sop_classes(_VERIFICATION_CLASSES)
 
 
 def uid_to_sop_class(uid):
diff --git a/pynetdicom/status.py b/pynetdicom/status.py
index a16020633..34660da9d 100644
--- a/pynetdicom/status.py
+++ b/pynetdicom/status.py
@@ -240,20 +240,18 @@ NON_PATIENT_SERVICE_CLASS_STATUS = {
 NON_PATIENT_SERVICE_CLASS_STATUS.update(GENERAL_STATUS)
 
 
-# Procedure Step SOP Class specific status code values - WIP
-#   PS3.4 Annex F
-_PROCEDURE_STEP_STATUS = {
+# Procedure Step SOP Class specific status code values
+PROCEDURE_STEP_STATUS = {
     0x0001 : (STATUS_WARNING,
               "Requested optional attributes are not supported"),
     0x0110 : (STATUS_FAILURE,
               "Performed Procedure Step object may no longer be updated"),
 }
-_PROCEDURE_STEP_STATUS.update(GENERAL_STATUS)
+PROCEDURE_STEP_STATUS.update(GENERAL_STATUS)
 
 
-# Print Job Management Service Class specific status code values - WIP
-#   PS3.4 Annex H
-_PRINT_JOB_MANAGEMENT_SERVICE_CLASS_STATUS = {
+# Print Job Management Service Class specific status code values
+PRINT_JOB_MANAGEMENT_SERVICE_CLASS_STATUS = {
     0xB600 : (STATUS_WARNING, "Memory allocation not supported"),
     0xB601 : (STATUS_WARNING,
               "Film session printing (collation) is not supported"),
@@ -295,17 +293,15 @@ _PRINT_JOB_MANAGEMENT_SERVICE_CLASS_STATUS = {
               "film box will not be created when a previous film box has not "
               "been printed"),
 }
-_PRINT_JOB_MANAGEMENT_SERVICE_CLASS_STATUS.update(GENERAL_STATUS)
+PRINT_JOB_MANAGEMENT_SERVICE_CLASS_STATUS.update(GENERAL_STATUS)
 
 
-# Storage Commitment Service Class specific status code values - WIP
-#   PS3.4 Annex J
-_STORAGE_COMMITMENT_SERVICE_CLASS_STATUS = GENERAL_STATUS
+# Storage Commitment Service Class specific status code values
+STORAGE_COMMITMENT_SERVICE_CLASS_STATUS = GENERAL_STATUS
 
 
-# Application Event Logging Service Class specific status code values - WIP
-#   PS3.4 Annex N
-_APPLICATION_EVENT_LOGGING_SERVICE_CLASS_STATUS = {
+# Application Event Logging Service Class specific status code values
+APPLICATION_EVENT_LOGGING_SERVICE_CLASS_STATUS = {
     0xB101 : (STATUS_WARNING,
               "Specified Synchronisation Frame of Reference UID doesn't "
               "match SCP Synchronization Frame of Reference"),
@@ -331,11 +327,11 @@ _APPLICATION_EVENT_LOGGING_SERVICE_CLASS_STATUS = {
     0xC111 : (STATUS_FAILURE,
               "Update of Medication Administration Record failed"),
 }
-_APPLICATION_EVENT_LOGGING_SERVICE_CLASS_STATUS.update(GENERAL_STATUS)
+APPLICATION_EVENT_LOGGING_SERVICE_CLASS_STATUS.update(GENERAL_STATUS)
 
 
-# Media Creation Management Service Class specific status code values - WIP
-_MEDIA_CREATION_MANAGEMENT_SERVICE_CLASS_STATUS = {
+# Media Creation Management Service Class specific status code values
+MEDIA_CREATION_MANAGEMENT_SERVICE_CLASS_STATUS = {
     0x0001 : (STATUS_WARNING,
               "Requested optional attributes are not supported"),
     0xA510 : (STATUS_FAILURE,
@@ -347,16 +343,17 @@ _MEDIA_CREATION_MANAGEMENT_SERVICE_CLASS_STATUS = {
               "interrupted"),
     0xC203 : (STATUS_FAILURE, "Cancellation denied for unspecified reason"),
 }
-_MEDIA_CREATION_MANAGEMENT_SERVICE_CLASS_STATUS.update(GENERAL_STATUS)
+MEDIA_CREATION_MANAGEMENT_SERVICE_CLASS_STATUS.update(GENERAL_STATUS)
 
 
-# Unified Procedure Step Service specific status code values - WIP
-_UNIFIED_PROCEDURE_STEP_SERVICE_CLASS_STATUS = {
+# Unified Procedure Step Service specific status code values
+UNIFIED_PROCEDURE_STEP_SERVICE_CLASS_STATUS = {
     0x0001 : (STATUS_WARNING,
               "Requested optional attributes are not supported"),
     0xA700 : (STATUS_FAILURE, "Out of resources"),
     0xA900 : (STATUS_FAILURE, "Identifier doesn't match SOP Class"),
     0xB300 : (STATUS_WARNING, "The UPS was created with modifications"),
+    0xB301 : (STATUS_WARNING, "Deletion lock not granted"),
     0xB304 : (STATUS_WARNING,
               "The UPS is already in the requested state of CANCELED"),
     0xB305 : (STATUS_WARNING, "Coerced invalid values to valid values"),
@@ -396,15 +393,15 @@ _UNIFIED_PROCEDURE_STEP_SERVICE_CLASS_STATUS = {
 
 # Ranged values
 for _code in range(0xC000, 0xCFFF + 1):
-    _UNIFIED_PROCEDURE_STEP_SERVICE_CLASS_STATUS[_code] = (
+    UNIFIED_PROCEDURE_STEP_SERVICE_CLASS_STATUS[_code] = (
         STATUS_FAILURE, 'Unable to Process'
     )
 
-_UNIFIED_PROCEDURE_STEP_SERVICE_CLASS_STATUS.update(GENERAL_STATUS)
+UNIFIED_PROCEDURE_STEP_SERVICE_CLASS_STATUS.update(GENERAL_STATUS)
 
 
-# RT Machine Verification Service Class specific status code values - WIP
-_RT_MACHINE_VERIFICATION_SERVICE_CLASS_STATUS = {
+# RT Machine Verification Service Class specific status code values
+RT_MACHINE_VERIFICATION_SERVICE_CLASS_STATUS = {
     0xC112 : (STATUS_FAILURE,
               "No such object instance - applicable Machine Verification "
               "instance not found"),
@@ -427,7 +424,7 @@ _RT_MACHINE_VERIFICATION_SERVICE_CLASS_STATUS = {
     0xC227 : (STATUS_FAILURE,
               "No such object instance - Referenced RT Plan not found"),
 }
-_RT_MACHINE_VERIFICATION_SERVICE_CLASS_STATUS.update(GENERAL_STATUS)
+RT_MACHINE_VERIFICATION_SERVICE_CLASS_STATUS.update(GENERAL_STATUS)
 
 
 def code_to_status(code):


Test patch:
diff --git a/pynetdicom/tests/test_dsutils.py b/pynetdicom/tests/test_dsutils.py
index 5a51f3f96..ec8cb356c 100644
--- a/pynetdicom/tests/test_dsutils.py
+++ b/pynetdicom/tests/test_dsutils.py
@@ -62,6 +62,16 @@ class TestEncode(object):
         ds_enc = encode(ds, False, False)
         assert ds_enc is None
 
+    def test_encode_none(self):
+        """Test encoding None."""
+        out = encode(None, True, True)
+        assert out is None
+
+    def test_encode_empty(self):
+        """Test encoding an empty dataset."""
+        out = encode(Dataset(), True, True)
+        assert out == b''
+
 
 class TestDecode(object):
     """Test dsutils.decode(bytes, is_implicit_vr, is_little_endian)."""
diff --git a/pynetdicom/tests/test_presentation.py b/pynetdicom/tests/test_presentation.py
index a17f81798..482d03bc1 100644
--- a/pynetdicom/tests/test_presentation.py
+++ b/pynetdicom/tests/test_presentation.py
@@ -7,27 +7,37 @@ import pytest
 from pydicom._uid_dict import UID_dictionary
 from pydicom.uid import UID
 
-from pynetdicom import StoragePresentationContexts, AE, _config
+from pynetdicom import AE, _config
 from pynetdicom.pdu_primitives import SCP_SCU_RoleSelectionNegotiation
 from pynetdicom.presentation import (
+    build_context,
+    build_role,
     PresentationContext,
     negotiate_as_acceptor,
     negotiate_as_requestor,
     DEFAULT_TRANSFER_SYNTAXES,
-    VerificationPresentationContexts,
-    StoragePresentationContexts,
-    QueryRetrievePresentationContexts,
+    ApplicationEventLoggingPresentationContexts,
     BasicWorklistManagementPresentationContexts,
-    RelevantPatientInformationPresentationContexts,
-    SubstanceAdministrationPresentationContexts,
-    NonPatientObjectPresentationContexts,
-    HangingProtocolPresentationContexts,
-    DefinedProcedureProtocolPresentationContexts,
     ColorPalettePresentationContexts,
-    ImplantTemplatePresentationContexts,
+    DefinedProcedureProtocolPresentationContexts,
     DisplaySystemPresentationContexts,
-    build_context,
-    build_role,
+    HangingProtocolPresentationContexts,
+    ImplantTemplatePresentationContexts,
+    InstanceAvailabilityPresentationContexts,
+    MediaCreationManagementPresentationContexts,
+    MediaStoragePresentationContexts,
+    NonPatientObjectPresentationContexts,
+    PrintManagementPresentationContexts,
+    ProcedureStepPresentationContexts,
+    ProtocolApprovalPresentationContexts,
+    QueryRetrievePresentationContexts,
+    RelevantPatientInformationPresentationContexts,
+    RTMachineVerificationPresentationContexts,
+    StoragePresentationContexts,
+    StorageCommitmentPresentationContexts,
+    SubstanceAdministrationPresentationContexts,
+    UnifiedProcedurePresentationContexts,
+    VerificationPresentationContexts,
 )
 from pynetdicom.sop_class import (
     VerificationSOPClass,
@@ -1611,73 +1621,128 @@ def test_build_context():
 
 
 class TestServiceContexts(object):
-    def test_verification(self):
-        """Test the verification service presentation contexts."""
-        contexts = VerificationPresentationContexts
+    def test_application_event(self):
+        """Tests with application event logging presentation contexts"""
+        contexts = ApplicationEventLoggingPresentationContexts
+        assert len(contexts) == 2
+
+        for context in contexts:
+            assert context.transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
+            assert context.context_id is None
+
+        assert contexts[0].abstract_syntax == '1.2.840.10008.1.40'
+        assert contexts[1].abstract_syntax == '1.2.840.10008.1.42'
+
+    def test_basic_worklist(self):
+        """Test the basic worklist service presentation contexts."""
+        contexts = BasicWorklistManagementPresentationContexts
         assert len(contexts) == 1
-        assert contexts[0].abstract_syntax == '1.2.840.10008.1.1'
+
         assert contexts[0].transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
         assert contexts[0].context_id is None
+        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.4.31'
 
-    def test_storage(self):
-        """Test the storage service presentation contexts"""
-        contexts = StoragePresentationContexts
-        assert len(contexts) == 128
+    def test_color_palette(self):
+        """Tests with color palette presentation contexts"""
+        contexts = ColorPalettePresentationContexts
+        assert len(contexts) == 3
 
         for context in contexts:
             assert context.transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
             assert context.context_id is None
 
-        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.4.1.1.1'
-        assert contexts[80].abstract_syntax == '1.2.840.10008.5.1.4.1.1.77.1.4.1'
-        assert contexts[-1].abstract_syntax == '1.2.840.10008.5.1.4.1.1.90.1'
+        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.4.39.2'
+        assert contexts[1].abstract_syntax == '1.2.840.10008.5.1.4.39.3'
+        assert contexts[2].abstract_syntax == '1.2.840.10008.5.1.4.39.4'
 
-    def test_qr(self):
-        """Test the query/retrieve service presentation contexts."""
-        contexts = QueryRetrievePresentationContexts
-        assert len(contexts) == 12
+    def test_defined_procedure(self):
+        """Tests with defined procedure protocol presentation contexts"""
+        contexts = DefinedProcedureProtocolPresentationContexts
+        assert len(contexts) == 3
 
         for context in contexts:
             assert context.transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
             assert context.context_id is None
 
-        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.4.1.2.1.1'
-        assert contexts[4].abstract_syntax == '1.2.840.10008.5.1.4.1.2.2.2'
-        assert contexts[-1].abstract_syntax == '1.2.840.10008.5.1.4.1.2.5.3'
+        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.4.20.1'
+        assert contexts[1].abstract_syntax == '1.2.840.10008.5.1.4.20.2'
+        assert contexts[2].abstract_syntax == '1.2.840.10008.5.1.4.20.3'
 
-    def test_worklist(self):
-        """Test the basic worklist service presentation contexts."""
-        contexts = BasicWorklistManagementPresentationContexts
+    def test_display_system(self):
+        """Tests with display system presentation contexts"""
+        contexts = DisplaySystemPresentationContexts
         assert len(contexts) == 1
 
-        assert contexts[0].transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
-        assert contexts[0].context_id is None
-        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.4.31'
+        for context in contexts:
+            assert context.transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
+            assert context.context_id is None
 
-    def test_relevant_patient(self):
-        """Tests with relevant patient info presentation contexts"""
-        contexts = RelevantPatientInformationPresentationContexts
+        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.1.40'
+
+    def test_hanging_protocol(self):
+        """Tests with hanging protocol presentation contexts"""
+        contexts = HangingProtocolPresentationContexts
         assert len(contexts) == 3
 
         for context in contexts:
             assert context.transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
             assert context.context_id is None
 
-        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.4.37.1'
-        assert contexts[1].abstract_syntax == '1.2.840.10008.5.1.4.37.2'
-        assert contexts[2].abstract_syntax == '1.2.840.10008.5.1.4.37.3'
+        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.4.38.2'
+        assert contexts[1].abstract_syntax == '1.2.840.10008.5.1.4.38.3'
+        assert contexts[2].abstract_syntax == '1.2.840.10008.5.1.4.38.4'
 
-    def test_substance_admin(self):
-        """Tests with substance administration presentation contexts"""
-        contexts = SubstanceAdministrationPresentationContexts
-        assert len(contexts) == 2
+    def test_implant_template(self):
+        """Tests with implant template presentation contexts"""
+        contexts = ImplantTemplatePresentationContexts
+        assert len(contexts) == 9
 
         for context in contexts:
             assert context.transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
             assert context.context_id is None
 
-        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.4.41'
-        assert contexts[1].abstract_syntax == '1.2.840.10008.5.1.4.42'
+        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.4.43.2'
+        assert contexts[1].abstract_syntax == '1.2.840.10008.5.1.4.43.3'
+        assert contexts[2].abstract_syntax == '1.2.840.10008.5.1.4.43.4'
+        assert contexts[3].abstract_syntax == '1.2.840.10008.5.1.4.44.2'
+        assert contexts[4].abstract_syntax == '1.2.840.10008.5.1.4.44.3'
+        assert contexts[5].abstract_syntax == '1.2.840.10008.5.1.4.44.4'
+        assert contexts[6].abstract_syntax == '1.2.840.10008.5.1.4.45.2'
+        assert contexts[7].abstract_syntax == '1.2.840.10008.5.1.4.45.3'
+        assert contexts[8].abstract_syntax == '1.2.840.10008.5.1.4.45.4'
+
+    def test_instance_availability(self):
+        """Tests with instance availability presentation contexts"""
+        contexts = InstanceAvailabilityPresentationContexts
+        assert len(contexts) == 1
+
+        for context in contexts:
+            assert context.transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
+            assert context.context_id is None
+
+        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.4.33'
+
+    def test_media_creation(self):
+        """Tests with media creation presentation contexts"""
+        contexts = MediaCreationManagementPresentationContexts
+        assert len(contexts) == 1
+
+        for context in contexts:
+            assert context.transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
+            assert context.context_id is None
+
+        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.1.33'
+
+    def test_media_storage(self):
+        """Tests with media storage presentation contexts"""
+        contexts = MediaStoragePresentationContexts
+        assert len(contexts) == 1
+
+        for context in contexts:
+            assert context.transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
+            assert context.context_id is None
+
+        assert contexts[0].abstract_syntax == '1.2.840.10008.1.3.10'
 
     def test_non_patient(self):
         """Tests with non patient object presentation contexts"""
@@ -1696,74 +1761,148 @@ class TestServiceContexts(object):
         assert contexts[5].abstract_syntax == '1.2.840.10008.5.1.4.44.1'
         assert contexts[6].abstract_syntax == '1.2.840.10008.5.1.4.45.1'
 
-    def test_hanging_protocol(self):
-        """Tests with hanging protocol presentation contexts"""
-        contexts = HangingProtocolPresentationContexts
+    def test_print_management(self):
+        """Tests with print management presentation contexts"""
+        contexts = PrintManagementPresentationContexts
+        assert len(contexts) == 11
+
+        for context in contexts:
+            assert context.transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
+            assert context.context_id is None
+
+        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.1.1'
+        assert contexts[1].abstract_syntax == '1.2.840.10008.5.1.1.14'
+        assert contexts[2].abstract_syntax == '1.2.840.10008.5.1.1.15'
+        assert contexts[3].abstract_syntax == '1.2.840.10008.5.1.1.16'
+        assert contexts[4].abstract_syntax == '1.2.840.10008.5.1.1.16.376'
+        assert contexts[5].abstract_syntax == '1.2.840.10008.5.1.1.18'
+        assert contexts[6].abstract_syntax == '1.2.840.10008.5.1.1.2'
+        assert contexts[7].abstract_syntax == '1.2.840.10008.5.1.1.23'
+        assert contexts[8].abstract_syntax == '1.2.840.10008.5.1.1.4'
+        assert contexts[9].abstract_syntax == '1.2.840.10008.5.1.1.4.1'
+        assert contexts[10].abstract_syntax == '1.2.840.10008.5.1.1.9'
+
+    def test_procedure_step(self):
+        """Tests with procedure step presentation contexts"""
+        contexts = ProcedureStepPresentationContexts
         assert len(contexts) == 3
 
         for context in contexts:
             assert context.transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
             assert context.context_id is None
 
-        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.4.38.2'
-        assert contexts[1].abstract_syntax == '1.2.840.10008.5.1.4.38.3'
-        assert contexts[2].abstract_syntax == '1.2.840.10008.5.1.4.38.4'
+        assert contexts[0].abstract_syntax == '1.2.840.10008.3.1.2.3.3'
+        assert contexts[1].abstract_syntax == '1.2.840.10008.3.1.2.3.4'
+        assert contexts[2].abstract_syntax == '1.2.840.10008.3.1.2.3.5'
 
-    def test_defined_procedure(self):
-        """Tests with defined procedure protocol presentation contexts"""
-        contexts = DefinedProcedureProtocolPresentationContexts
+    def test_protocol_approval(self):
+        """Tests with protocol approval presentation contexts"""
+        contexts = ProtocolApprovalPresentationContexts
         assert len(contexts) == 3
 
         for context in contexts:
             assert context.transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
             assert context.context_id is None
 
-        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.4.20.1'
-        assert contexts[1].abstract_syntax == '1.2.840.10008.5.1.4.20.2'
-        assert contexts[2].abstract_syntax == '1.2.840.10008.5.1.4.20.3'
+        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.4.1.1.200.4'
+        assert contexts[1].abstract_syntax == '1.2.840.10008.5.1.4.1.1.200.5'
+        assert contexts[2].abstract_syntax == '1.2.840.10008.5.1.4.1.1.200.6'
 
-    def test_color_palette(self):
-        """Tests with color palette presentation contexts"""
-        contexts = ColorPalettePresentationContexts
+    def test_qr(self):
+        """Test the query/retrieve service presentation contexts."""
+        contexts = QueryRetrievePresentationContexts
+        assert len(contexts) == 12
+
+        for context in contexts:
+            assert context.transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
+            assert context.context_id is None
+
+        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.4.1.2.1.1'
+        assert contexts[4].abstract_syntax == '1.2.840.10008.5.1.4.1.2.2.2'
+        assert contexts[-1].abstract_syntax == '1.2.840.10008.5.1.4.1.2.5.3'
+
+    def test_relevant_patient(self):
+        """Tests with relevant patient info presentation contexts"""
+        contexts = RelevantPatientInformationPresentationContexts
         assert len(contexts) == 3
 
         for context in contexts:
             assert context.transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
             assert context.context_id is None
 
-        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.4.39.2'
-        assert contexts[1].abstract_syntax == '1.2.840.10008.5.1.4.39.3'
-        assert contexts[2].abstract_syntax == '1.2.840.10008.5.1.4.39.4'
+        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.4.37.1'
+        assert contexts[1].abstract_syntax == '1.2.840.10008.5.1.4.37.2'
+        assert contexts[2].abstract_syntax == '1.2.840.10008.5.1.4.37.3'
 
-    def test_implant_template(self):
-        """Tests with implant template presentation contexts"""
-        contexts = ImplantTemplatePresentationContexts
-        assert len(contexts) == 9
+    def test_rt_machine(self):
+        """Tests with RT machine verification presentation contexts"""
+        contexts = RTMachineVerificationPresentationContexts
+        assert len(contexts) == 2
 
         for context in contexts:
             assert context.transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
             assert context.context_id is None
 
-        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.4.43.2'
-        assert contexts[1].abstract_syntax == '1.2.840.10008.5.1.4.43.3'
-        assert contexts[2].abstract_syntax == '1.2.840.10008.5.1.4.43.4'
-        assert contexts[3].abstract_syntax == '1.2.840.10008.5.1.4.44.2'
-        assert contexts[4].abstract_syntax == '1.2.840.10008.5.1.4.44.3'
-        assert contexts[5].abstract_syntax == '1.2.840.10008.5.1.4.44.4'
-        assert contexts[6].abstract_syntax == '1.2.840.10008.5.1.4.45.2'
-        assert contexts[7].abstract_syntax == '1.2.840.10008.5.1.4.45.3'
-        assert contexts[8].abstract_syntax == '1.2.840.10008.5.1.4.45.4'
+        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.4.34.8'
+        assert contexts[1].abstract_syntax == '1.2.840.10008.5.1.4.34.9'
 
-    def test_display_system(self):
-        """Tests with display system presentation contexts"""
-        contexts = DisplaySystemPresentationContexts
+    def test_storage(self):
+        """Test the storage service presentation contexts"""
+        contexts = StoragePresentationContexts
+        assert len(contexts) == 128
+
+        for context in contexts:
+            assert context.transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
+            assert context.context_id is None
+
+        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.4.1.1.1'
+        assert contexts[80].abstract_syntax == '1.2.840.10008.5.1.4.1.1.77.1.4.1'
+        assert contexts[-1].abstract_syntax == '1.2.840.10008.5.1.4.1.1.90.1'
+
+    def test_storage_commitement(self):
+        """Tests with storage commitment presentation contexts"""
+        contexts = StorageCommitmentPresentationContexts
         assert len(contexts) == 1
 
         for context in contexts:
             assert context.transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
             assert context.context_id is None
 
-        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.1.40'
+        assert contexts[0].abstract_syntax == '1.2.840.10008.1.20.1'
+
+    def test_substance_admin(self):
+        """Tests with substance administration presentation contexts"""
+        contexts = SubstanceAdministrationPresentationContexts
+        assert len(contexts) == 2
+
+        for context in contexts:
+            assert context.transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
+            assert context.context_id is None
+
+        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.4.41'
+        assert contexts[1].abstract_syntax == '1.2.840.10008.5.1.4.42'
+
+    def test_unified_procedure(self):
+        """Tests with unified procedure presentation contexts"""
+        contexts = UnifiedProcedurePresentationContexts
+        assert len(contexts) == 4
+
+        for context in contexts:
+            assert context.transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
+            assert context.context_id is None
+
+        assert contexts[0].abstract_syntax == '1.2.840.10008.5.1.4.34.6.1'
+        assert contexts[1].abstract_syntax == '1.2.840.10008.5.1.4.34.6.2'
+        assert contexts[2].abstract_syntax == '1.2.840.10008.5.1.4.34.6.3'
+        assert contexts[3].abstract_syntax == '1.2.840.10008.5.1.4.34.6.4'
+
+    def test_verification(self):
+        """Test the verification service presentation contexts."""
+        contexts = VerificationPresentationContexts
+        assert len(contexts) == 1
+        assert contexts[0].abstract_syntax == '1.2.840.10008.1.1'
+        assert contexts[0].transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
+        assert contexts[0].context_id is None
 
 
 class TestBuildRole(object):
diff --git a/pynetdicom/tests/test_sop.py b/pynetdicom/tests/test_sop.py
index 822ccdd92..801957ef6 100644
--- a/pynetdicom/tests/test_sop.py
+++ b/pynetdicom/tests/test_sop.py
@@ -9,49 +9,67 @@ from pynetdicom.sop_class import (
     uid_to_service_class,
     SOPClass,
     _SERVICE_CLASSES,
-    _VERIFICATION_CLASSES,
-    _STORAGE_CLASSES,
-    _QR_CLASSES,
+    _APPLICATION_EVENT_CLASSES,
+    ProceduralEventLoggingSOPClass,
     _BASIC_WORKLIST_CLASSES,
-    _RELEVANT_PATIENT_QUERY_CLASSES,
-    _SUBSTANCE_ADMINISTRATION_CLASSES,
-    _NON_PATIENT_OBJECT_CLASSES,
-    _PRINT_MANAGEMENT_CLASSES,
-    _PROCEDURE_STEP_CLASSES,
-    _DISPLAY_SYSTEM_CLASSES,
-    _MEDIA_STORAGE_CLASSES,
-    _UNIFIED_PROCEDURE_STEP_CLASSES,
-    _RT_MACHINE_VERIFICATION_CLASSES,
-    _PROTOCOL_APPROVAL_SOP_CLASSES,
-    VerificationSOPClass,
-    CTImageStorage,
-    StudyRootQueryRetrieveInformationModelFind,
     ModalityWorklistInformationFind,
-    GeneralRelevantPatientInformationQuery,
-    ProductCharacteristicsQueryInformationModelFind,
-    HangingProtocolStorage,
-    HangingProtocolInformationModelGet,
-    DefinedProcedureProtocolInformationModelFind,
+    _COLOR_PALETTE_CLASSES,
     ColorPaletteInformationModelMove,
+    _DEFINED_PROCEDURE_CLASSES,
+    DefinedProcedureProtocolInformationModelFind,
+    _DISPLAY_SYSTEM_CLASSES,
+    DisplaySystemSOPClass,
+    _HANGING_PROTOCOL_CLASSES,
+    HangingProtocolInformationModelGet,
+    _IMPLANT_TEMPLATE_CLASSES,
     ImplantTemplateGroupInformationModelFind,
+    _INSTANCE_AVAILABILITY_CLASSES,
+    InstanceAvailabilityNotificationSOPClass,
+    _MEDIA_CREATION_CLASSES,
+    MediaCreationManagementSOPClass,
+    _MEDIA_STORAGE_CLASSES,
+    MediaStorageDirectoryStorage,
+    _NON_PATIENT_OBJECT_CLASSES,
+    HangingProtocolStorage,
+    _PRINT_MANAGEMENT_CLASSES,
+    PrintJobSOPClass,
+    _PROCEDURE_STEP_CLASSES,
+    ModalityPerformedProcedureStepSOPClass,
+    _PROTOCOL_APPROVAL_CLASSES,
     ProtocolApprovalInformationModelFind,
     ProtocolApprovalInformationModelMove,
     ProtocolApprovalInformationModelGet,
+    _QR_CLASSES,
+    StudyRootQueryRetrieveInformationModelFind,
+    _RELEVANT_PATIENT_QUERY_CLASSES,
+    GeneralRelevantPatientInformationQuery,
+    _RT_MACHINE_VERIFICATION_CLASSES,
+    RTConventionalMachineVerification,
+    _STORAGE_CLASSES,
+    CTImageStorage,
+    _STORAGE_COMMITMENT_CLASSES,
+    StorageCommitmentPushModelSOPClass,
+    _SUBSTANCE_ADMINISTRATION_CLASSES,
+    ProductCharacteristicsQueryInformationModelFind,
+    _UNIFIED_PROCEDURE_STEP_CLASSES,
+    UnifiedProcedureStepPullSOPClass,
+    _VERIFICATION_CLASSES,
+    VerificationSOPClass,
 )
 from pynetdicom.service_class import (
     ServiceClass,
-    VerificationServiceClass,
-    StorageServiceClass,
-    QueryRetrieveServiceClass,
     BasicWorklistManagementServiceClass,
-    RelevantPatientInformationQueryServiceClass,
-    SubstanceAdministrationQueryServiceClass,
-    NonPatientObjectStorageServiceClass,
-    HangingProtocolQueryRetrieveServiceClass,
-    DefinedProcedureProtocolQueryRetrieveServiceClass,
     ColorPaletteQueryRetrieveServiceClass,
+    DefinedProcedureProtocolQueryRetrieveServiceClass,
+    HangingProtocolQueryRetrieveServiceClass,
     ImplantTemplateQueryRetrieveServiceClass,
+    NonPatientObjectStorageServiceClass,
     ProtocolApprovalQueryRetrieveServiceClass,
+    QueryRetrieveServiceClass,
+    RelevantPatientInformationQueryServiceClass,
+    StorageServiceClass,
+    SubstanceAdministrationQueryServiceClass,
+    VerificationServiceClass,
 )
 from pynetdicom.service_class_n import (
     DisplaySystemManagementServiceClass,
@@ -61,17 +79,25 @@ from pynetdicom.service_class_n import (
 
 def test_all_sop_classes():
     """Test that all the SOP Class UIDs are correct."""
-    for uid in _VERIFICATION_CLASSES.values():
+    for uid in _APPLICATION_EVENT_CLASSES.values():
         assert uid in UID_dictionary
-    for uid in _STORAGE_CLASSES.values():
+    for uid in _BASIC_WORKLIST_CLASSES.values():
         assert uid in UID_dictionary
-    for uid in _QR_CLASSES.values():
+    for uid in _COLOR_PALETTE_CLASSES.values():
         assert uid in UID_dictionary
-    for uid in _BASIC_WORKLIST_CLASSES.values():
+    for uid in _DEFINED_PROCEDURE_CLASSES.values():
         assert uid in UID_dictionary
-    for uid in _RELEVANT_PATIENT_QUERY_CLASSES.values():
+    for uid in _DISPLAY_SYSTEM_CLASSES.values():
         assert uid in UID_dictionary
-    for uid in _SUBSTANCE_ADMINISTRATION_CLASSES.values():
+    for uid in _HANGING_PROTOCOL_CLASSES.values():
+        assert uid in UID_dictionary
+    for uid in _IMPLANT_TEMPLATE_CLASSES.values():
+        assert uid in UID_dictionary
+    for uid in _INSTANCE_AVAILABILITY_CLASSES.values():
+        assert uid in UID_dictionary
+    for uid in _MEDIA_CREATION_CLASSES.values():
+        assert uid in UID_dictionary
+    for uid in _MEDIA_STORAGE_CLASSES.values():
         assert uid in UID_dictionary
     for uid in _NON_PATIENT_OBJECT_CLASSES.values():
         assert uid in UID_dictionary
@@ -79,15 +105,23 @@ def test_all_sop_classes():
         assert uid in UID_dictionary
     for uid in _PROCEDURE_STEP_CLASSES.values():
         assert uid in UID_dictionary
-    for uid in _DISPLAY_SYSTEM_CLASSES.values():
+    for uid in _PROTOCOL_APPROVAL_CLASSES.values():
         assert uid in UID_dictionary
-    for uid in _MEDIA_STORAGE_CLASSES.values():
+    for uid in _QR_CLASSES.values():
         assert uid in UID_dictionary
-    for uid in _UNIFIED_PROCEDURE_STEP_CLASSES.values():
+    for uid in _RELEVANT_PATIENT_QUERY_CLASSES.values():
         assert uid in UID_dictionary
     for uid in _RT_MACHINE_VERIFICATION_CLASSES.values():
         assert uid in UID_dictionary
-    for uid in _PROTOCOL_APPROVAL_SOP_CLASSES.values():
+    for uid in _STORAGE_CLASSES.values():
+        assert uid in UID_dictionary
+    for uid in _STORAGE_COMMITMENT_CLASSES.values():
+        assert uid in UID_dictionary
+    for uid in _SUBSTANCE_ADMINISTRATION_CLASSES.values():
+        assert uid in UID_dictionary
+    for uid in _UNIFIED_PROCEDURE_STEP_CLASSES.values():
+        assert uid in UID_dictionary
+    for uid in _VERIFICATION_CLASSES.values():
         assert uid in UID_dictionary
 
 def test_all_service_classes():
@@ -121,35 +155,55 @@ class TestUIDToServiceClass(object):
         uid = '1.2.840.10008.4.2'
         assert uid_to_service_class(uid) == StorageServiceClass
 
-    def test_verification_uids(self):
-        """Test that the Verification SOP Class UIDs work correctly."""
-        for uid in _VERIFICATION_CLASSES.values():
-            assert uid_to_service_class(uid) == VerificationServiceClass
-
-    def test_storage_uids(self):
-        """Test that the Storage SOP Class UIDs work correctly."""
-        for uid in _STORAGE_CLASSES.values():
-            assert uid_to_service_class(uid) == StorageServiceClass
-
-    def test_qr_uids(self):
-        """Test that the QR SOP Class UIDs work correctly."""
-        for uid in _QR_CLASSES.values():
-            assert uid_to_service_class(uid) == QueryRetrieveServiceClass
+    def test_app_logging_uids(self):
+        """Test that the Application Event SOP Class UIDs work correctly."""
+        for uid in _APPLICATION_EVENT_CLASSES.values():
+            assert uid_to_service_class(uid) == ServiceClass
 
     def test_basic_worklist_uids(self):
         """Test that the Basic Worklist SOP Class UIDs work correctly."""
         for uid in _BASIC_WORKLIST_CLASSES.values():
             assert uid_to_service_class(uid) == BasicWorklistManagementServiceClass
 
-    def test_relevant_patient_uids(self):
-        """Test that the Relevant Patient SOP Class UIDs work correctly."""
-        for uid in _RELEVANT_PATIENT_QUERY_CLASSES.values():
-            assert uid_to_service_class(uid) == RelevantPatientInformationQueryServiceClass
+    def test_color_palette_uids(self):
+        """Test that the Color Paletter SOP Class UIDs work correctly."""
+        for uid in _COLOR_PALETTE_CLASSES.values():
+            assert uid_to_service_class(uid) == ColorPaletteQueryRetrieveServiceClass
 
-    def test_substance_admin_uids(self):
-        """Test that the Substance Administration SOP Class UIDs work correctly."""
-        for uid in _SUBSTANCE_ADMINISTRATION_CLASSES.values():
-            assert uid_to_service_class(uid) == SubstanceAdministrationQueryServiceClass
+    def test_defined_procedure_uids(self):
+        """Test that the Defined Procedure SOP Class UIDs work correctly."""
+        for uid in _DEFINED_PROCEDURE_CLASSES.values():
+            assert uid_to_service_class(uid) == DefinedProcedureProtocolQueryRetrieveServiceClass
+
+    def test_display_system_uids(self):
+        """Test that Display System SOP Class UIDs work correctly."""
+        for uid in _DISPLAY_SYSTEM_CLASSES.values():
+            assert uid_to_service_class(uid) == DisplaySystemManagementServiceClass
+
+    def test_hanging_protocol_uids(self):
+        """Test that the Hanging Protocol SOP Class UIDs work correctly."""
+        for uid in _HANGING_PROTOCOL_CLASSES.values():
+            assert uid_to_service_class(uid) == HangingProtocolQueryRetrieveServiceClass
+
+    def test_implant_template_uids(self):
+        """Test that the Implant Template SOP Class UIDs work correctly."""
+        for uid in _IMPLANT_TEMPLATE_CLASSES.values():
+            assert uid_to_service_class(uid) == ImplantTemplateQueryRetrieveServiceClass
+
+    def test_instance_uids(self):
+        """Test that the Instance Availability SOP Class UIDs work correctly."""
+        for uid in _INSTANCE_AVAILABILITY_CLASSES.values():
+            assert uid_to_service_class(uid) == ServiceClass
+
+    def test_media_creation_uids(self):
+        """Test that the Media Creation SOP Class UIDs work correctly."""
+        for uid in _MEDIA_CREATION_CLASSES.values():
+            assert uid_to_service_class(uid) == ServiceClass
+
+    def test_media_storage_uids(self):
+        """Test that the Media Storage SOP Class UIDs work correctly."""
+        for uid in _MEDIA_STORAGE_CLASSES.values():
+            assert uid_to_service_class(uid) == ServiceClass
 
     def test_non_patient_uids(self):
         """Test that the Non-Patient Object SOP Class UIDs work correctly."""
@@ -161,35 +215,55 @@ class TestUIDToServiceClass(object):
         for uid in _PRINT_MANAGEMENT_CLASSES.values():
             assert uid_to_service_class(uid) == ServiceClass
 
-    def test_procedure_uids(self):
+    def test_procedure_step_uids(self):
         """Test that the Procedure SOP Class UIDs work correctly."""
         for uid in _PROCEDURE_STEP_CLASSES.values():
             assert uid_to_service_class(uid) == ModalityPerformedProcedureStepServiceClass
 
-    def test_media_uids(self):
-        """Test that the Media Storage SOP Class UIDs work correctly."""
-        for uid in _MEDIA_STORAGE_CLASSES.values():
-            assert uid_to_service_class(uid) == ServiceClass
+    def test_protocol_approval_uids(self):
+        """Test that Protocol Approval SOP Class UIDs work correctly."""
+        for uid in _PROTOCOL_APPROVAL_CLASSES.values():
+            assert uid_to_service_class(uid) == ProtocolApprovalQueryRetrieveServiceClass
 
-    def test_ups_uids(self):
-        """Test that the UPS SOP Class UIDs work correctly."""
-        for uid in _UNIFIED_PROCEDURE_STEP_CLASSES.values():
-            assert uid_to_service_class(uid) == ServiceClass
+    def test_qr_uids(self):
+        """Test that the QR SOP Class UIDs work correctly."""
+        for uid in _QR_CLASSES.values():
+            assert uid_to_service_class(uid) == QueryRetrieveServiceClass
+
+    def test_relevant_patient_uids(self):
+        """Test that the Relevant Patient SOP Class UIDs work correctly."""
+        for uid in _RELEVANT_PATIENT_QUERY_CLASSES.values():
+            assert uid_to_service_class(uid) == RelevantPatientInformationQueryServiceClass
 
     def test_rt_machine_uids(self):
         """Test that the RT Verification SOP Class UIDs work correctly."""
         for uid in _RT_MACHINE_VERIFICATION_CLASSES.values():
             assert uid_to_service_class(uid) == ServiceClass
 
-    def test_display_system_uids(self):
-        """Test that Display System SOP Class UIDs work correctly."""
-        for uid in _DISPLAY_SYSTEM_CLASSES.values():
-            assert uid_to_service_class(uid) == DisplaySystemManagementServiceClass
+    def test_storage_uids(self):
+        """Test that the Storage SOP Class UIDs work correctly."""
+        for uid in _STORAGE_CLASSES.values():
+            assert uid_to_service_class(uid) == StorageServiceClass
 
-    def test_protocol_approval_uids(self):
-        """Test that Protocol Approval SOP Class UIDs work correctly."""
-        for uid in _PROTOCOL_APPROVAL_SOP_CLASSES.values():
-            assert uid_to_service_class(uid) == ProtocolApprovalQueryRetrieveServiceClass
+    def test_storage_commitment_uids(self):
+        """Test that the Storage Commitment SOP Class UIDs work correctly."""
+        for uid in _STORAGE_COMMITMENT_CLASSES.values():
+            assert uid_to_service_class(uid) == ServiceClass
+
+    def test_substance_admin_uids(self):
+        """Test that the Substance Administration SOP Class UIDs work correctly."""
+        for uid in _SUBSTANCE_ADMINISTRATION_CLASSES.values():
+            assert uid_to_service_class(uid) == SubstanceAdministrationQueryServiceClass
+
+    def test_ups_uids(self):
+        """Test that the UPS SOP Class UIDs work correctly."""
+        for uid in _UNIFIED_PROCEDURE_STEP_CLASSES.values():
+            assert uid_to_service_class(uid) == ServiceClass
+
+    def test_verification_uids(self):
+        """Test that the Verification SOP Class UIDs work correctly."""
+        for uid in _VERIFICATION_CLASSES.values():
+            assert uid_to_service_class(uid) == VerificationServiceClass
 
     def test_unknown_uid(self):
         """Test that an unknown UID returns default service class."""
@@ -198,75 +272,115 @@ class TestUIDToServiceClass(object):
 
 class TestSOPClass(object):
     """Tests for sop_class.SOPClass."""
-    def test_creation(self):
-        """Test creating a new UIDSOPClass."""
-        sop_class = SOPClass('1.2.3')
-        sop_class._service_class = ServiceClass
+    def test_app_logging_sop(self):
+        assert ProceduralEventLoggingSOPClass == '1.2.840.10008.1.40'
+        assert ProceduralEventLoggingSOPClass.service_class == ServiceClass
 
-        assert sop_class == '1.2.3'
-        assert sop_class.service_class == ServiceClass
+    def test_basic_worklist_sop(self):
+        """Test a Basic Worklist Service SOP Class."""
+        assert ModalityWorklistInformationFind == '1.2.840.10008.5.1.4.31'
+        assert ModalityWorklistInformationFind.service_class == BasicWorklistManagementServiceClass
 
-        sop_class_b = SOPClass(sop_class)
-        assert sop_class == sop_class_b
-        assert sop_class_b == '1.2.3'
-        assert sop_class_b.service_class == ServiceClass
+    def test_color_palette_sop(self):
+        """Test a Color Palette Service SOP Class."""
+        assert ColorPaletteInformationModelMove == '1.2.840.10008.5.1.4.39.3'
+        assert ColorPaletteInformationModelMove.service_class == ColorPaletteQueryRetrieveServiceClass
 
-    def test_verification_sop(self):
-        """Test a Verification Service SOP Class."""
-        assert VerificationSOPClass == '1.2.840.10008.1.1'
-        assert VerificationSOPClass.service_class == VerificationServiceClass
+    def test_defined_procedure_sop(self):
+        """Test a Defined Procedure Protocol Service SOP Class."""
+        assert DefinedProcedureProtocolInformationModelFind == '1.2.840.10008.5.1.4.20.1'
+        assert DefinedProcedureProtocolInformationModelFind.service_class == DefinedProcedureProtocolQueryRetrieveServiceClass
 
-    def test_storage_sop(self):
-        """Test a Storage Service SOP Class."""
-        assert CTImageStorage == '1.2.840.10008.5.1.4.1.1.2'
-        assert CTImageStorage.service_class == StorageServiceClass
+    def test_display_sop(self):
+        assert DisplaySystemSOPClass == '1.2.840.10008.5.1.1.40'
+        assert DisplaySystemSOPClass.service_class == DisplaySystemManagementServiceClass
+
+    def test_hanging_protocol_sop(self):
+        """Test a Hanging Protocol Service SOP Class."""
+        assert HangingProtocolInformationModelGet == '1.2.840.10008.5.1.4.38.4'
+        assert HangingProtocolInformationModelGet.service_class == HangingProtocolQueryRetrieveServiceClass
+
+    def test_implant_template_sop(self):
+        """Test an Implant Template Service SOP Class."""
+        assert ImplantTemplateGroupInformationModelFind == '1.2.840.10008.5.1.4.45.2'
+        assert ImplantTemplateGroupInformationModelFind.service_class == ImplantTemplateQueryRetrieveServiceClass
+
+    def test_instance_sop(self):
+        assert InstanceAvailabilityNotificationSOPClass == '1.2.840.10008.5.1.4.33'
+        assert InstanceAvailabilityNotificationSOPClass.service_class == ServiceClass
+
+    def test_media_creation_sop(self):
+        assert MediaCreationManagementSOPClass == '1.2.840.10008.5.1.1.33'
+        assert MediaCreationManagementSOPClass.service_class == ServiceClass
+
+    def test_media_storage_sop(self):
+        assert MediaStorageDirectoryStorage == '1.2.840.10008.1.3.10'
+        assert MediaStorageDirectoryStorage.service_class == ServiceClass
+
+    def test_non_patient_sop(self):
+        """Test a Non-Patient Object Service SOP Class."""
+        assert HangingProtocolStorage == '1.2.840.10008.5.1.4.38.1'
+        assert HangingProtocolStorage.service_class == NonPatientObjectStorageServiceClass
+
+    def test_print_sop(self):
+        assert PrintJobSOPClass == '1.2.840.10008.5.1.1.14'
+        assert PrintJobSOPClass.service_class == ServiceClass
+
+    def test_procedure_step_sop(self):
+        assert ModalityPerformedProcedureStepSOPClass == '1.2.840.10008.3.1.2.3.3'
+        assert ModalityPerformedProcedureStepSOPClass.service_class == ModalityPerformedProcedureStepServiceClass
+
+    def test_protocol_approval_sop(self):
+        """Test an Protocol Approval Service SOP Class."""
+        assert ProtocolApprovalInformationModelFind == '1.2.840.10008.5.1.4.1.1.200.4'
+        assert ProtocolApprovalInformationModelFind.service_class == ProtocolApprovalQueryRetrieveServiceClass
 
     def test_qr_sop(self):
         """Test a Query/Retrieve Service SOP Class."""
         assert StudyRootQueryRetrieveInformationModelFind == '1.2.840.10008.5.1.4.1.2.2.1'
         assert StudyRootQueryRetrieveInformationModelFind.service_class == QueryRetrieveServiceClass
 
-    def test_basic_worklist_sop(self):
-        """Test a Basic Worklist Service SOP Class."""
-        assert ModalityWorklistInformationFind == '1.2.840.10008.5.1.4.31'
-        assert ModalityWorklistInformationFind.service_class == BasicWorklistManagementServiceClass
-
     def test_relevant_patient_info_sop(self):
         """Test a Relevant Patient Information Query Service SOP Class."""
         assert GeneralRelevantPatientInformationQuery == '1.2.840.10008.5.1.4.37.1'
         assert GeneralRelevantPatientInformationQuery.service_class == RelevantPatientInformationQueryServiceClass
 
+    def test_rt_sop(self):
+        assert RTConventionalMachineVerification == '1.2.840.10008.5.1.4.34.8'
+        assert RTConventionalMachineVerification.service_class == ServiceClass
+
+    def test_storage_sop(self):
+        """Test a Storage Service SOP Class."""
+        assert CTImageStorage == '1.2.840.10008.5.1.4.1.1.2'
+        assert CTImageStorage.service_class == StorageServiceClass
+
+    def test_storage_commitment_sop(self):
+        assert StorageCommitmentPushModelSOPClass == '1.2.840.10008.1.20.1'
+        assert StorageCommitmentPushModelSOPClass.service_class == ServiceClass
+
     def test_substance_admin_sop(self):
         """Test s Substance Administration Query Service SOP Class."""
         assert ProductCharacteristicsQueryInformationModelFind == '1.2.840.10008.5.1.4.41'
         assert ProductCharacteristicsQueryInformationModelFind.service_class == SubstanceAdministrationQueryServiceClass
 
-    def test_non_patient_sop(self):
-        """Test a Non-Patient Object Service SOP Class."""
-        assert HangingProtocolStorage == '1.2.840.10008.5.1.4.38.1'
-        assert HangingProtocolStorage.service_class == NonPatientObjectStorageServiceClass
+    def test_ups_sop(self):
+        assert UnifiedProcedureStepPullSOPClass == '1.2.840.10008.5.1.4.34.6.3'
+        assert UnifiedProcedureStepPullSOPClass.service_class == ServiceClass
 
-    def test_hanging_protocol_sop(self):
-        """Test a Hanging Protocol Service SOP Class."""
-        assert HangingProtocolInformationModelGet == '1.2.840.10008.5.1.4.38.4'
-        assert HangingProtocolInformationModelGet.service_class == HangingProtocolQueryRetrieveServiceClass
-
-    def test_defined_procedure_sop(self):
-        """Test a Defined Procedure Protocol Service SOP Class."""
-        assert DefinedProcedureProtocolInformationModelFind == '1.2.840.10008.5.1.4.20.1'
-        assert DefinedProcedureProtocolInformationModelFind.service_class == DefinedProcedureProtocolQueryRetrieveServiceClass
+    def test_verification_sop(self):
+        """Test a Verification Service SOP Class."""
+        assert VerificationSOPClass == '1.2.840.10008.1.1'
+        assert VerificationSOPClass.service_class == VerificationServiceClass
 
-    def test_color_palette_sop(self):
-        """Test a Color Palette Service SOP Class."""
-        assert ColorPaletteInformationModelMove == '1.2.840.10008.5.1.4.39.3'
-        assert ColorPaletteInformationModelMove.service_class == ColorPaletteQueryRetrieveServiceClass
+    def test_uid_creation(self):
+        """Test creating a new UIDSOPClass."""
+        sop_class = SOPClass('1.2.3')
+        sop_class._service_class = ServiceClass
 
-    def test_implant_template_sop(self):
-        """Test an Implant Template Service SOP Class."""
-        assert ImplantTemplateGroupInformationModelFind == '1.2.840.10008.5.1.4.45.2'
-        assert ImplantTemplateGroupInformationModelFind.service_class == ImplantTemplateQueryRetrieveServiceClass
+        assert sop_class == '1.2.3'
+        assert sop_class.service_class == ServiceClass
 
-    def test_protocol_approval_sop(self):
-        """Test an Protocol Approval Service SOP Class."""
-        assert ProtocolApprovalInformationModelFind == '1.2.840.10008.5.1.4.1.1.200.4'
-        assert ProtocolApprovalInformationModelFind.service_class == ProtocolApprovalQueryRetrieveServiceClass
+        sop_class_b = SOPClass(sop_class)
+        assert sop_class == sop_class_b
+        assert sop_class_b == '1.2.3'
+        assert sop_class_b.service_class == ServiceClass