Repository: pydicom/pynetdicom (python)

Issue:
Intermittent failing test TestState08::test_evt14
While running the tests several times in CI, there is one specific test failing from time to time in different runs (seen at least in pydicom-dev 3.7, pydicom-dev 3.9 and pydicom-release 3.7).

Here is the output (similar for each occurence):
```
=========================== short test summary info ============================
FAILED pynetdicom/tests/test_fsm.py::TestState08::test_evt14 - AssertionError: assert ['Evt1', 'Evt...t12', 'Evt17'] == ['Evt1', 'Evt...t12', 'Evt14']
  At index 4 diff: 'Evt17' != 'Evt14'
  Full diff:
  - ['Evt1', 'Evt2', 'Evt3', 'Evt12', 'Evt14']
  ?                                        ^
  + ['Evt1', 'Evt2', 'Evt3', 'Evt12', 'Evt17']
```
I don't know if this is only test-related, but it needs at least some investigation.

Pull request:
[MRG] Fixes for intermittent FSM test failures
#### Reference issue
Closes #827

#### Tasks
- [x] Fix or feature added
- [x] Unit tests passing and coverage at 100% after adding fix/feature



Patch:
diff --git a/docs/changelog/index.rst b/docs/changelog/index.rst
index f043c7358..523d43290 100644
--- a/docs/changelog/index.rst
+++ b/docs/changelog/index.rst
@@ -7,7 +7,6 @@ Release Notes
 .. toctree::
    :maxdepth: 1
 
-   v2.2.0
    v2.1.0
    v2.0.1
    v2.0.0
diff --git a/docs/changelog/v2.1.0.rst b/docs/changelog/v2.1.0.rst
index c811c7289..59e531c8b 100644
--- a/docs/changelog/v2.1.0.rst
+++ b/docs/changelog/v2.1.0.rst
@@ -16,6 +16,8 @@ Fixes
 Enhancements
 ............
 
+* Added :func:`~pynetdicom.sop_class.register_uid` to make registering new
+  private and public SOP Classes easier (:issue:`799`)
 
 Changes
 .......
diff --git a/docs/changelog/v2.2.0.rst b/docs/changelog/v2.2.0.rst
deleted file mode 100644
index 129114ae9..000000000
--- a/docs/changelog/v2.2.0.rst
+++ /dev/null
@@ -1,18 +0,0 @@
-.. _v2.2.0:
-
-2.2.0
-=====
-
-Fixes
-.....
-
-
-Enhancements
-............
-
-* Added :func:`~pynetdicom.sop_class.register_uid` to make registering new
-  private and public SOP Classes easier (:issue:`799`)
-
-
-Changes
-.......
diff --git a/docs/reference/sop_classes.rst b/docs/reference/sop_classes.rst
index 27c17eb6c..65dd359ba 100644
--- a/docs/reference/sop_classes.rst
+++ b/docs/reference/sop_classes.rst
@@ -100,6 +100,16 @@ Instance Availability
 
    InstanceAvailabilityNotification
 
+Inventory Query/Retrieve
+........................
+
+.. autosummary::
+   :toctree: generated/
+
+   InventoryFind
+   InventoryGet
+   InventoryMove
+
 Media Creation
 ..............
 
@@ -128,6 +138,7 @@ Non-patient Object
    HangingProtocolStorage
    ImplantAssemblyTemplateStorage
    ImplantTemplateGroupStorage
+   InventoryStorage
    ProtocolApprovalStorage
    XADefinedProcedureProtocolStorage
 
@@ -187,6 +198,7 @@ Query/Retrieve
    StudyRootQueryRetrieveInformationModelFind
    StudyRootQueryRetrieveInformationModelGet
    StudyRootQueryRetrieveInformationModelMove
+   RepositoryQuery
 
 Relevant Patient
 ................
@@ -255,10 +267,12 @@ Storage
    EncapsulatedOBJStorage
    EncapsulatedPDFStorage
    EncapsulatedSTLStorage
+   EnhancedContinuousRTImageStorage
    EnhancedCTImageStorage
    EnhancedMRColorImageStorage
    EnhancedMRImageStorage
    EnhancedPETImageStorage
+   EnhancedRTImageStorage
    EnhancedSRStorage
    EnhancedUSVolumeStorage
    EnhancedXAImageStorage
@@ -267,6 +281,7 @@ Storage
    ExtensibleSRStorage
    GeneralAudioWaveformStorage
    GeneralECGWaveformStorage
+   General32bitECGWaveformStorage
    GrayscalePlanarMPRVolumetricPresentationStateStorage
    GrayscaleSoftcopyPresentationStateStorage
    HemodynamicWaveformStorage
@@ -303,6 +318,7 @@ Storage
    ParametricMapStorage
    PatientRadiationDoseSRStorage
    PerformedImagingAgentAdministrationSRStorage
+   PhotoacousticImageStorage
    PlannedImagingAgentAdministrationSRStorage
    PositronEmissionTomographyImageStorage
    ProcedureLogStorage
@@ -322,6 +338,7 @@ Storage
    RTImageStorage
    RTIonBeamsTreatmentRecordStorage
    RTIonPlanStorage
+   RTPatientPositionAcquisitionInstructionStorage
    RTPhysicianIntentStorage
    RTPlanStorage
    RTRadiationRecordSetStorage
@@ -351,6 +368,7 @@ Storage
    TwelveLeadECGWaveformStorage
    UltrasoundImageStorage
    UltrasoundMultiFrameImageStorage
+   VariableModalityLUTSoftcopyPresentationStageStorage
    VideoEndoscopicImageStorage
    VideoMicroscopicImageStorage
    VideoPhotographicImageStorage
@@ -379,6 +397,14 @@ Storage Commitment
 
    StorageCommitmentPushModel
 
+Storage Management
+..................
+
+.. autosummary::
+   :toctree: generated/
+
+   InventoryCreation
+
 Substance Availability
 ......................
 
@@ -420,6 +446,7 @@ Well-known SOP Instances
    PrinterInstance
    ProceduralEventLoggingInstance
    StorageCommitmentPushModelInstance
+   StorageManagementInstance
    SubstanceAdministrationLoggingInstance
    UPSFilteredGlobalSubscriptionInstance
    UPSGlobalSubscriptionInstance
diff --git a/docs/tutorials/installation.rst b/docs/tutorials/installation.rst
index 5d2a51135..8adfeae49 100644
--- a/docs/tutorials/installation.rst
+++ b/docs/tutorials/installation.rst
@@ -74,9 +74,17 @@ branch (this will create a ``pynetdicom`` directory in your current directory)::
 
   git clone https://github.com/pydicom/pynetdicom
 
-Then install using pip in editable (``-e``) mode::
+Create a `new virtual environment <https://docs.python.org/3/tutorial/venv.html>`_
 
-  pip install -e pynetdicom/
+In the activated environment install `poetry <https://python-poetry.org/>`_::
+
+  pip install -U poetry
+
+Change to the ``pynetdicom`` directory and install *pynetdicom* and the required
+development packages using poetry::
+
+  cd pynetdicom/
+  poetry install --with dev
 
 When you want to update your copy of the source code, run ``git pull`` from
 within the ``pynetdicom`` directory and Git will download and apply any
diff --git a/pynetdicom/_version.py b/pynetdicom/_version.py
index 7af0ff93e..5d64386d3 100644
--- a/pynetdicom/_version.py
+++ b/pynetdicom/_version.py
@@ -4,10 +4,10 @@ import re
 
 
 # pynetdicom version
-__version__ = "2.2.0.dev0"
+__version__ = "2.1.0.dev0"
 
 # DICOM Standard version used for SOP classes and instances
-__dicom_version__: str = "2021e"
+__dicom_version__: str = "2023d"
 
 VERSION_PATTERN = r"""
     v?
diff --git a/pynetdicom/presentation.py b/pynetdicom/presentation.py
index a71c46353..14be2b41f 100644
--- a/pynetdicom/presentation.py
+++ b/pynetdicom/presentation.py
@@ -1081,8 +1081,140 @@ AllStoragePresentationContexts = [
 ]
 """Pre-built presentation contexts for :dcm:`Storage<part04/chapter_B.html>` containing all SOP Classes."""
 
-StoragePresentationContexts = AllStoragePresentationContexts[:128]
-"""Pre-built presentation contexts for :dcm:`Storage<part04/chapter_B.html>` containing the first 128 SOP Classes."""
+_storage = [
+    "1.2.840.10008.5.1.4.1.1.1",  # ComputedRadiographyImageStorage
+    "1.2.840.10008.5.1.4.1.1.2",  # "CTImageStorage":
+    "1.2.840.10008.5.1.4.1.1.2.1",  # "EnhancedCTImageStorage":
+    "1.2.840.10008.5.1.4.1.1.3.1",  # "UltrasoundMultiFrameImageStorage":
+    "1.2.840.10008.5.1.4.1.1.4",  # "MRImageStorage":
+    "1.2.840.10008.5.1.4.1.1.4.1",  # "EnhancedMRImageStorage":
+    "1.2.840.10008.5.1.4.1.1.4.2",  # "MRSpectroscopyStorage":
+    "1.2.840.10008.5.1.4.1.1.4.3",  # "EnhancedMRColorImageStorage":
+    "1.2.840.10008.5.1.4.1.1.6.1",  # "UltrasoundImageStorage":
+    "1.2.840.10008.5.1.4.1.1.6.2",  # "EnhancedUSVolumeStorage":
+    "1.2.840.10008.5.1.4.1.1.6.3",  # "PhotoacousticImageStorage":
+    "1.2.840.10008.5.1.4.1.1.7",  # "SecondaryCaptureImageStorage":
+    "1.2.840.10008.5.1.4.1.1.7.1",  # "MultiFrameSingleBitSecondaryCaptureImageStorage":
+    "1.2.840.10008.5.1.4.1.1.7.2",  # "MultiFrameGrayscaleByteSecondaryCaptureImageStorage":
+    "1.2.840.10008.5.1.4.1.1.7.3",  # MultiFrameGrayscaleWordSecondaryCaptureImageStorage
+    "1.2.840.10008.5.1.4.1.1.7.4",  # MultiFrameTrueColorSecondaryCaptureImageStorage
+    "1.2.840.10008.5.1.4.1.1.9.1.1",  # TwelveLeadECGWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.9.1.2",  # GeneralECGWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.9.1.3",  # AmbulatoryECGWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.9.1.4",  # General32bitECGWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.9.2.1",  # HemodynamicWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.9.3.1",  # CardiacElectrophysiologyWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.9.4.1",  # BasicVoiceAudioWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.9.4.2",  # GeneralAudioWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.9.5.1",  # ArterialPulseWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.9.6.1",  # RespiratoryWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.9.6.2",  # MultichannelRespiratoryWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.9.7.1",  # RoutineScalpElectroencephalogramWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.9.7.2",  # ElectromyogramWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.9.7.3",  # ElectrooculogramWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.9.7.4",  # SleepElectroencephalogramWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.9.8.1",  # BodyPositionWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.12.1",  # XRayAngiographicImageStorage
+    "1.2.840.10008.5.1.4.1.1.12.1.1",  # EnhancedXAImageStorage
+    "1.2.840.10008.5.1.4.1.1.12.2",  # XRayRadiofluoroscopicImageStorage
+    "1.2.840.10008.5.1.4.1.1.12.2.1",  # EnhancedXRFImageStorage
+    "1.2.840.10008.5.1.4.1.1.13.1.1",  # XRay3DAngiographicImageStorage
+    "1.2.840.10008.5.1.4.1.1.13.1.2",  # XRay3DCraniofacialImageStorage
+    "1.2.840.10008.5.1.4.1.1.13.1.3",  # BreastTomosynthesisImageStorage
+    "1.2.840.10008.5.1.4.1.1.20",  # NuclearMedicineImageStorage
+    "1.2.840.10008.5.1.4.1.1.30",  # ParametricMapStorage
+    "1.2.840.10008.5.1.4.1.1.66",  # RawDataStorage
+    "1.2.840.10008.5.1.4.1.1.66.1",  # SpatialRegistrationStorage
+    "1.2.840.10008.5.1.4.1.1.66.2",  # SpatialFiducialsStorage
+    "1.2.840.10008.5.1.4.1.1.66.3",  # DeformableSpatialRegistrationStorage
+    "1.2.840.10008.5.1.4.1.1.66.4",  # SegmentationStorage
+    "1.2.840.10008.5.1.4.1.1.66.5",  # SurfaceSegmentationStorage
+    "1.2.840.10008.5.1.4.1.1.66.6",  # TractographyResultsStorage
+    "1.2.840.10008.5.1.4.1.1.67",  # RealWorldValueMappingStorage
+    "1.2.840.10008.5.1.4.1.1.68.1",  # SurfaceScanMeshStorage
+    "1.2.840.10008.5.1.4.1.1.68.2",  # SurfaceScanPointCloudStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.1",  # VLEndoscopicImageStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.1.1",  # VideoEndoscopicImageStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.2",  # VLMicroscopicImageStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.2.1",  # VideoMicroscopicImageStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.3",  # VLSlideCoordinatesMicroscopicImageStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.4",  # VLPhotographicImageStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.4.1",  # VideoPhotographicImageStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.5.1",  # OphthalmicPhotography8BitImageStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.5.2",  # OphthalmicPhotography16BitImageStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.5.3",  # StereometricRelationshipStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.5.4",  # OphthalmicTomographyImageStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.5.5",  # WideFieldOphthalmicPhotographyStereographicProjectionImageStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.5.6",  # WideFieldOphthalmicPhotography3DCoordinatesImageStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.5.7",  # OphthalmicOpticalCoherenceTomographyEnFaceImageStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.5.8",  # OphthlamicOpticalCoherenceTomographyBscanVolumeAnalysisStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.6",  # VLWholeSlideMicroscopyImageStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.7",  # DermoscopicPhotographyImageStorage
+    "1.2.840.10008.5.1.4.1.1.78.1",  # LensometryMeasurementsStorage
+    "1.2.840.10008.5.1.4.1.1.78.2",  # AutorefractionMeasurementsStorage
+    "1.2.840.10008.5.1.4.1.1.78.3",  # KeratometryMeasurementsStorage
+    "1.2.840.10008.5.1.4.1.1.78.4",  # SubjectiveRefractionMeasurementsStorage
+    "1.2.840.10008.5.1.4.1.1.78.5",  # VisualAcuityMeasurementsStorage
+    "1.2.840.10008.5.1.4.1.1.78.6",  # SpectaclePrescriptionReportStorage
+    "1.2.840.10008.5.1.4.1.1.78.7",  # OphthalmicAxialMeasurementsStorage
+    "1.2.840.10008.5.1.4.1.1.78.8",  # IntraocularLensCalculationsStorage
+    "1.2.840.10008.5.1.4.1.1.79.1",  # MacularGridThicknessAndVolumeReportStorage
+    "1.2.840.10008.5.1.4.1.1.80.1",  # OphthalmicVisualFieldStaticPerimetryMeasurementsStorage
+    "1.2.840.10008.5.1.4.1.1.81.1",  # OphthalmicThicknessMapStorage
+    "1.2.840.10008.5.1.4.1.1.82.1",  # CornealTopographyMapStorage
+    "1.2.840.10008.5.1.4.1.1.88.11",  # BasicTextSRStorage
+    "1.2.840.10008.5.1.4.1.1.88.22",  # EnhancedSRStorage
+    "1.2.840.10008.5.1.4.1.1.88.33",  # ComprehensiveSRStorage
+    "1.2.840.10008.5.1.4.1.1.88.34",  # Comprehensive3DSRStorage
+    "1.2.840.10008.5.1.4.1.1.88.35",  # ExtensibleSRStorage
+    "1.2.840.10008.5.1.4.1.1.88.50",  # MammographyCADSRStorage
+    "1.2.840.10008.5.1.4.1.1.88.65",  # ChestCADSRStorage
+    "1.2.840.10008.5.1.4.1.1.88.67",  # XRayRadiationDoseSRStorage
+    "1.2.840.10008.5.1.4.1.1.88.68",  # RadiopharmaceuticalRadiationDoseSRStorage
+    "1.2.840.10008.5.1.4.1.1.88.69",  # ColonCADSRStorage
+    "1.2.840.10008.5.1.4.1.1.88.70",  # ImplantationPlanSRStorage
+    "1.2.840.10008.5.1.4.1.1.88.71",  # AcquisitionContextSRStorage
+    "1.2.840.10008.5.1.4.1.1.88.72",  # SimplifiedAdultEchoSRStorage
+    "1.2.840.10008.5.1.4.1.1.88.73",  # PatientRadiationDoseSRStorage
+    "1.2.840.10008.5.1.4.1.1.88.76",  # EnhancedXRayRadiationDoseSRStorage
+    "1.2.840.10008.5.1.4.1.1.91.1",  # MicroscopyBulkSimpleAnnotationsStorage
+    "1.2.840.10008.5.1.4.1.1.104.1",  # EncapsulatedPDFStorage
+    "1.2.840.10008.5.1.4.1.1.104.2",  # EncapsulatedCDAStorage
+    "1.2.840.10008.5.1.4.1.1.104.3",  # EncapsulatedSTLStorage
+    "1.2.840.10008.5.1.4.1.1.104.4",  # EncapsulatedOBJStorage
+    "1.2.840.10008.5.1.4.1.1.104.5",  # EncapsulatedMTLStorage
+    "1.2.840.10008.5.1.4.1.1.128",  # PositronEmissionTomographyImageStorage
+    "1.2.840.10008.5.1.4.1.1.130",  # EnhancedPETImageStorage
+    "1.2.840.10008.5.1.4.1.1.481.1",  # RTImageStorage
+    "1.2.840.10008.5.1.4.1.1.481.2",  # RTDoseStorage
+    "1.2.840.10008.5.1.4.1.1.481.3",  # RTStructureSetStorage
+    "1.2.840.10008.5.1.4.1.1.481.4",  # RTBeamsTreatmentRecordStorage
+    "1.2.840.10008.5.1.4.1.1.481.5",  # RTPlanStorage
+    "1.2.840.10008.5.1.4.1.1.481.6",  # RTBrachyTreatmentRecordStorage
+    "1.2.840.10008.5.1.4.1.1.481.7",  # RTTreatmentSummaryRecordStorage
+    "1.2.840.10008.5.1.4.1.1.481.8",  # RTIonPlanStorage
+    "1.2.840.10008.5.1.4.1.1.481.9",  # RTIonBeamsTreatmentRecordStorage
+    "1.2.840.10008.5.1.4.1.1.481.10",  # RTPhysicianIntentStorage
+    "1.2.840.10008.5.1.4.1.1.481.11",  # RTSegmentAnnotationStorage
+    "1.2.840.10008.5.1.4.1.1.481.12",  # RTRadiationSetStorage
+    "1.2.840.10008.5.1.4.1.1.481.13",  # CArmPhotonElectronRadiationStorage
+    "1.2.840.10008.5.1.4.1.1.481.14",  # TomotherapeuticRadiationStorage
+    "1.2.840.10008.5.1.4.1.1.481.15",  # RoboticArmRadiationStorage
+    "1.2.840.10008.5.1.4.1.1.481.18",  # TomotherapeuticRadiationRecordStorage
+    "1.2.840.10008.5.1.4.1.1.481.19",  # CArmPhotonElectronRadiationRecordStorage
+    "1.2.840.10008.5.1.4.1.1.481.20",  # RoboticArmRadiationRecordStorage
+    "1.2.840.10008.5.1.4.1.1.481.21",  # RTRadiationSetDeliveryInstructionStorage
+    "1.2.840.10008.5.1.4.1.1.481.22",  # RTTreatmentPreparationStorage
+    "1.2.840.10008.5.1.4.1.1.481.23",  # EnhancedRTImageStorage
+    "1.2.840.10008.5.1.4.1.1.481.24",  # EnhancedContinuousRTImageStorage
+    "1.2.840.10008.5.1.4.1.1.481.25",  # RTPatientPositionAcquisitionInstructionStorage
+    "1.2.840.10008.5.1.4.34.7",  # RTBeamsDeliveryInstructionStorage
+    "1.2.840.10008.5.1.4.34.10",  # RTBrachyApplicationSetupDeliveryInstructionsStorage
+]
+assert len(_storage) <= 128
+
+StoragePresentationContexts = [build_context(uid) for uid in sorted(_storage)]
+"""Pre-built presentation contexts for :dcm:`Storage<part04/chapter_B.html>` containing 128 selected SOP Classes."""
 
 StorageCommitmentPresentationContexts = [
     build_context(uid) for uid in sorted(_STORAGE_COMMITMENT_CLASSES.values())
diff --git a/pynetdicom/sop_class.py b/pynetdicom/sop_class.py
index 376ec4b02..3d4c06ec7 100644
--- a/pynetdicom/sop_class.py
+++ b/pynetdicom/sop_class.py
@@ -210,6 +210,11 @@ _IMPLANT_TEMPLATE_CLASSES = {
 _INSTANCE_AVAILABILITY_CLASSES = {
     "InstanceAvailabilityNotification": "1.2.840.10008.5.1.4.33",
 }
+_INVENTORY_CLASSES = {
+    "InventoryFind": "1.2.840.10008.5.1.4.1.1.201.2",
+    "InventoryMove": "1.2.840.10008.5.1.4.1.1.201.3",
+    "InventoryGet": "1.2.840.10008.5.1.4.1.1.201.4",
+}
 _MEDIA_CREATION_CLASSES = {
     "MediaCreationManagement": "1.2.840.10008.5.1.1.33",
 }
@@ -225,6 +230,7 @@ _NON_PATIENT_OBJECT_CLASSES = {
     "CTDefinedProcedureProtocolStorage": "1.2.840.10008.5.1.4.1.1.200.1",
     "ProtocolApprovalStorage": "1.2.840.10008.5.1.4.1.1.200.3",
     "XADefinedProcedureProtocolStorage": "1.2.840.10008.5.1.4.1.1.200.7",
+    "InventoryStorage": "1.2.840.10008.5.1.4.1.1.201.1",
 }
 _PRINT_MANAGEMENT_CLASSES = {
     "BasicFilmSession": "1.2.840.10008.5.1.1.1",
@@ -265,6 +271,7 @@ _QR_CLASSES = {
     "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",
+    "RepositoryQuery": "1.2.840.10008.5.1.4.1.1.201.6",
 }
 _RELEVANT_PATIENT_QUERY_CLASSES = {
     "GeneralRelevantPatientInformationQuery": "1.2.840.10008.5.1.4.37.1",
@@ -294,6 +301,7 @@ _STORAGE_CLASSES = {
     "LegacyConvertedEnhancedMRImageStorage": "1.2.840.10008.5.1.4.1.1.4.4",  # A.71
     "UltrasoundImageStorage": "1.2.840.10008.5.1.4.1.1.6.1",  # A.6
     "EnhancedUSVolumeStorage": "1.2.840.10008.5.1.4.1.1.6.2",  # A.59
+    "PhotoacousticImageStorage": "1.2.840.10008.5.1.4.1.1.6.3",
     "SecondaryCaptureImageStorage": "1.2.840.10008.5.1.4.1.1.7",  # A.8.1
     "MultiFrameSingleBitSecondaryCaptureImageStorage": "1.2.840.10008.5.1.4.1.1.7.1",  # A.8.2
     "MultiFrameGrayscaleByteSecondaryCaptureImageStorage": "1.2.840.10008.5.1.4.1.1.7.2",  # A.8.3
@@ -302,6 +310,7 @@ _STORAGE_CLASSES = {
     "TwelveLeadECGWaveformStorage": "1.2.840.10008.5.1.4.1.1.9.1.1",  # A.34.3
     "GeneralECGWaveformStorage": "1.2.840.10008.5.1.4.1.1.9.1.2",  # A.34.4
     "AmbulatoryECGWaveformStorage": "1.2.840.10008.5.1.4.1.1.9.1.3",  # A.34.5
+    "General32bitECGWaveformStorage": "1.2.840.10008.5.1.4.1.1.9.1.4",
     "HemodynamicWaveformStorage": "1.2.840.10008.5.1.4.1.1.9.2.1",  # A.34.6
     "CardiacElectrophysiologyWaveformStorage": "1.2.840.10008.5.1.4.1.1.9.3.1",  # A.34.7
     "BasicVoiceAudioWaveformStorage": "1.2.840.10008.5.1.4.1.1.9.4.1",  # A.34.2
@@ -325,6 +334,7 @@ _STORAGE_CLASSES = {
     "VolumeRenderingVolumetricPresentationStateStorage": "1.2.840.10008.5.1.4.1.1.11.9",  # A.80.2
     "SegmentedVolumeRenderingVolumetricPresentationStateStorage": "1.2.840.10008.5.1.4.1.1.11.10",  # A.80.2
     "MultipleVolumeRenderingVolumetricPresentationStateStorage": "1.2.840.10008.5.1.4.1.1.11.11",  # A.80.2
+    "VariableModalityLUTSoftcopyPresentationStageStorage": "1.2.840.10008.5.1.4.1.1.11.12",
     "XRayAngiographicImageStorage": "1.2.840.10008.5.1.4.1.1.12.1",  # A.14
     "EnhancedXAImageStorage": "1.2.840.10008.5.1.4.1.1.12.1.1",  # A.47
     "XRayRadiofluoroscopicImageStorage": "1.2.840.10008.5.1.4.1.1.12.2",  # A.16
@@ -401,10 +411,10 @@ _STORAGE_CLASSES = {
     "EncapsulatedPDFStorage": "1.2.840.10008.5.1.4.1.1.104.1",  # A.45.1
     "EncapsulatedCDAStorage": "1.2.840.10008.5.1.4.1.1.104.2",  # A.45.2
     "EncapsulatedSTLStorage": "1.2.840.10008.5.1.4.1.1.104.3",  # A.85.1
+    # 128 presentation context limit here
     "EncapsulatedOBJStorage": "1.2.840.10008.5.1.4.1.1.104.4",  # A.85.2
     "EncapsulatedMTLStorage": "1.2.840.10008.5.1.4.1.1.104.5",  # A.85.3
     "PositronEmissionTomographyImageStorage": "1.2.840.10008.5.1.4.1.1.128",  # A.21
-    # 128 presentation context limit here
     "LegacyConvertedEnhancedPETImageStorage": "1.2.840.10008.5.1.4.1.1.128.1",  # A.72
     "EnhancedPETImageStorage": "1.2.840.10008.5.1.4.1.1.130",  # A.56
     "BasicStructuredDisplayStorage": "1.2.840.10008.5.1.4.1.1.131",  # A.33.5
@@ -432,12 +442,18 @@ _STORAGE_CLASSES = {
     "RoboticArmRadiationRecordStorage": "1.2.840.10008.5.1.4.1.1.481.20",  # A.86.1.12
     "RTRadiationSetDeliveryInstructionStorage": "1.2.840.10008.5.1.4.1.1.481.21",
     "RTTreatmentPreparationStorage": "1.2.840.10008.5.1.4.1.1.481.22",
+    "EnhancedRTImageStorage": "1.2.840.10008.5.1.4.1.1.481.23",
+    "EnhancedContinuousRTImageStorage": "1.2.840.10008.5.1.4.1.1.481.24",
+    "RTPatientPositionAcquisitionInstructionStorage": "1.2.840.10008.5.1.4.1.1.481.25",
     "RTBeamsDeliveryInstructionStorage": "1.2.840.10008.5.1.4.34.7",  # A.64
     "RTBrachyApplicationSetupDeliveryInstructionsStorage": "1.2.840.10008.5.1.4.34.10",  # A.79
 }
 _STORAGE_COMMITMENT_CLASSES = {
     "StorageCommitmentPushModel": "1.2.840.10008.1.20.1",
 }
+_STORAGE_MANAGEMENT_CLASSES = {
+    "InventoryCreation": "1.2.840.10008.5.1.4.1.1.201.5",
+}
 _SUBSTANCE_ADMINISTRATION_CLASSES = {
     "ProductCharacteristicsQuery": "1.2.840.10008.5.1.4.41",
     "SubstanceApprovalQuery": "1.2.840.10008.5.1.4.42",
@@ -488,6 +504,7 @@ _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(_INVENTORY_CLASSES)
 _generate_sop_classes(_MEDIA_CREATION_CLASSES)
 _generate_sop_classes(_MEDIA_STORAGE_CLASSES)
 _generate_sop_classes(_NON_PATIENT_OBJECT_CLASSES)
@@ -499,6 +516,7 @@ _generate_sop_classes(_RELEVANT_PATIENT_QUERY_CLASSES)
 _generate_sop_classes(_RT_MACHINE_VERIFICATION_CLASSES)
 _generate_sop_classes(_STORAGE_CLASSES)
 _generate_sop_classes(_STORAGE_COMMITMENT_CLASSES)
+_generate_sop_classes(_STORAGE_MANAGEMENT_CLASSES)
 _generate_sop_classes(_SUBSTANCE_ADMINISTRATION_CLASSES)
 _generate_sop_classes(_UNIFIED_PROCEDURE_STEP_CLASSES)
 _generate_sop_classes(_VERIFICATION_CLASSES)
@@ -645,6 +663,11 @@ StorageCommitmentPushModelInstance = UID("1.2.840.10008.1.20.1.1")
 
 .. versionadded:: 1.5
 """
+StorageManagementInstance = UID("1.2.840.10008.5.1.4.1.1.201.1.1")
+"""``1.2.840.10008.5.1.4.1.1.201.1.1``
+
+.. versionadded:: 2.1
+"""
 SubstanceAdministrationLoggingInstance = UID("1.2.840.10008.1.42.1")
 """``1.2.840.10008.1.42.1``
 
diff --git a/pyproject.toml b/pyproject.toml
index 1b99c7931..82bf7ee8e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -40,7 +40,7 @@ maintainers = [
 ]
 name = "pynetdicom"
 readme = "README.rst"
-version = "2.2.0.dev0"
+version = "2.1.0.dev0"
 
 
 [tool.poetry.dependencies]


Test patch:
diff --git a/pynetdicom/apps/tests/test_findscu.py b/pynetdicom/apps/tests/test_findscu.py
index 095253694..0706cc6f6 100644
--- a/pynetdicom/apps/tests/test_findscu.py
+++ b/pynetdicom/apps/tests/test_findscu.py
@@ -114,7 +114,7 @@ class FindSCUBase:
         assert {} == requestor.sop_class_extended
         assert requestor.user_identity == None
         cxs = requestor.primitive.presentation_context_definition_list
-        assert len(cxs) == 18
+        assert len(cxs) == 19
         cxs = {cx.abstract_syntax: cx for cx in cxs}
         assert PatientRootQueryRetrieveInformationModelFind in cxs
         cx = cxs[PatientRootQueryRetrieveInformationModelFind]
diff --git a/pynetdicom/apps/tests/test_movescu.py b/pynetdicom/apps/tests/test_movescu.py
index 27bb70965..11608e28e 100644
--- a/pynetdicom/apps/tests/test_movescu.py
+++ b/pynetdicom/apps/tests/test_movescu.py
@@ -130,7 +130,7 @@ class MoveSCUBase:
         assert requestor.role_selection == {}
         assert requestor.user_identity == None
         cxs = requestor.primitive.presentation_context_definition_list
-        assert len(cxs) == 12
+        assert len(cxs) == 13
         cxs = {cx.abstract_syntax: cx for cx in cxs}
         assert PatientRootQueryRetrieveInformationModelMove in cxs
         cx = cxs[PatientRootQueryRetrieveInformationModelMove]
diff --git a/pynetdicom/tests/test_fsm.py b/pynetdicom/tests/test_fsm.py
index b25e42dca..f27fa2c69 100644
--- a/pynetdicom/tests/test_fsm.py
+++ b/pynetdicom/tests/test_fsm.py
@@ -401,7 +401,7 @@ class TestStateBase:
         fsm = self.monkey_patch(assoc.dul.state_machine)
         return assoc, fsm
 
-    def wait_on_state(self, fsm, state, timeout=2):
+    def wait_on_state(self, fsm, state, timeout=5):
         start = 0
         while (
             fsm.current_state != state
@@ -2305,7 +2305,11 @@ class TestState05(TestStateBase):
         # Sta5 + Evt3 -> AE-3 -> Sta6
         # Evt3: Receive A-ASSOCIATE-AC PDU from <remote>
         # AE-3: Issue A-ASSOCIATE (ac) primitive
-        commands = [("recv", None), ("send", a_associate_ac), ("exit", None)]
+        commands = [
+            ("recv", None),
+            ("send", a_associate_ac),
+            ("exit", None),
+        ]
         self.scp = scp = self.start_server(commands)
         self.move_to_state(self.assoc, scp)
 
@@ -2316,7 +2320,7 @@ class TestState05(TestStateBase):
         assert self.fsm._changes[:3] == [
             ("Sta1", "Evt1", "AE-1"),
             ("Sta4", "Evt2", "AE-2"),
-            ("Sta5", "Evt3", "AE-3"),
+            ("Sta5", "Evt3", "AE-3"),  # Sometimes not making it to Sta5...
         ]
         assert self.fsm._transitions[:3] == ["Sta4", "Sta5", "Sta6"]
         assert self.fsm._events[:3] == ["Evt1", "Evt2", "Evt3"]
@@ -3857,11 +3861,13 @@ class TestState08(TestStateBase):
             ("send", a_associate_ac),
             ("send", a_release_rq),
             ("send", a_associate_ac),
+            ("recv", None),
             ("exit", None),
         ]
         self.scp = scp = self.start_server(commands)
         self.move_to_state(self.assoc, scp)
 
+        scp.step()
         scp.step()
         scp.step()
         scp.shutdown()
@@ -3886,11 +3892,13 @@ class TestState08(TestStateBase):
             ("send", a_associate_ac),
             ("send", a_release_rq),
             ("send", a_associate_rj),
+            ("recv", None),
             ("exit", None),
         ]
         self.scp = scp = self.start_server(commands)
         self.move_to_state(self.assoc, scp)
 
+        scp.step()
         scp.step()
         scp.step()
         scp.shutdown()
@@ -3922,11 +3930,13 @@ class TestState08(TestStateBase):
             ("send", a_associate_ac),
             ("send", a_release_rq),
             ("send", a_associate_rq),
+            ("recv", None),
             ("exit", None),
         ]
         self.scp = scp = self.start_server(commands)
         self.move_to_state(self.assoc, scp)
 
+        scp.step()
         scp.step()
         scp.step()
         scp.shutdown()
@@ -4012,6 +4022,7 @@ class TestState08(TestStateBase):
             ("recv", None),
             ("send", a_associate_ac),
             ("send", a_release_rq),
+            ("recv", None),
             ("exit", None),
         ]
         self.scp = scp = self.start_server(commands)
@@ -4019,6 +4030,7 @@ class TestState08(TestStateBase):
 
         self.assoc.dul.send_pdu(self.get_pdata())
 
+        scp.step()
         scp.step()
         scp.shutdown()
 
@@ -4041,11 +4053,13 @@ class TestState08(TestStateBase):
             ("send", a_associate_ac),
             ("send", a_release_rq),
             ("send", p_data_tf),
+            ("recv", None),
             ("exit", None),
         ]
         self.scp = scp = self.start_server(commands)
         self.move_to_state(self.assoc, scp)
 
+        scp.step()
         scp.step()
         scp.step()
         scp.shutdown()
@@ -4101,11 +4115,13 @@ class TestState08(TestStateBase):
             ("send", a_associate_ac),
             ("send", a_release_rq),
             ("send", a_release_rq),
+            ("recv", None),
             ("exit", None),
         ]
         self.scp = scp = self.start_server(commands)
         self.move_to_state(self.assoc, scp)
 
+        scp.step()
         scp.step()
         scp.step()
         scp.shutdown()
@@ -4130,11 +4146,13 @@ class TestState08(TestStateBase):
             ("send", a_associate_ac),
             ("send", a_release_rq),
             ("send", a_release_rp),
+            ("recv", None),
             ("exit", None),
         ]
         self.scp = scp = self.start_server(commands)
         self.move_to_state(self.assoc, scp)
 
+        scp.step()
         scp.step()
         scp.step()
         scp.shutdown()
@@ -4158,6 +4176,7 @@ class TestState08(TestStateBase):
             ("recv", None),
             ("send", a_associate_ac),
             ("send", a_release_rq),
+            ("recv", None),
             ("exit", None),
         ]
         self.scp = scp = self.start_server(commands)
@@ -4165,6 +4184,7 @@ class TestState08(TestStateBase):
 
         self.assoc.dul.send_pdu(self.get_release(True))
 
+        scp.step()
         scp.step()
         scp.shutdown()
 
@@ -4308,11 +4328,13 @@ class TestState08(TestStateBase):
             ("send", a_associate_ac),
             ("send", a_release_rq),
             ("send", b"\x08\x00\x00\x00\x00\x00"),
+            ("recv", None),
             ("exit", None),
         ]
         self.scp = scp = self.start_server(commands)
         self.move_to_state(self.assoc, scp)
 
+        scp.step()
         scp.step()
         scp.step()
         scp.shutdown()
diff --git a/pynetdicom/tests/test_presentation.py b/pynetdicom/tests/test_presentation.py
index 0b63ded0a..29a5f7418 100644
--- a/pynetdicom/tests/test_presentation.py
+++ b/pynetdicom/tests/test_presentation.py
@@ -297,6 +297,7 @@ class TestPresentationContext:
 
         _config.ENFORCE_UID_CONFORMANCE = False
         pc.abstract_syntax = UID("1.4.1.")
+
         assert pc.abstract_syntax == UID("1.4.1.")
         assert isinstance(pc.abstract_syntax, UID)
 
@@ -335,6 +336,7 @@ class TestPresentationContext:
         pc = PresentationContext()
         pc.context_id = 1
         pc.transfer_syntax = ["1.4.1.", "1.2.840.10008.1.2"]
+
         assert pc.transfer_syntax == ["1.4.1.", "1.2.840.10008.1.2"]
         assert "A non-conformant UID has been added to 'transfer_syntax'" in caplog.text
 
@@ -652,11 +654,17 @@ class TestNegotiateAsAcceptor:
         assert context.result == 0x00
         assert context.transfer_syntax == ["1.2.840.10008.1.2.1"]
 
-    @pytest.mark.skipif(PYDICOM_VERSION < ["2", "2"], reason="Old data dict")
     def test_typical(self):
         """Test a typical set of presentation context negotiations."""
         req_contexts = []
         for ii, context in enumerate(StoragePresentationContexts):
+            # Old pydicom UID dict
+            if context.abstract_syntax in (
+                "1.2.840.10008.5.1.4.1.1.6.3",
+                "1.2.840.10008.5.1.4.1.1.9.1.4",
+            ):
+                continue
+
             pc = PresentationContext()
             pc.context_id = ii * 2 + 1
             pc.abstract_syntax = context.abstract_syntax
@@ -1594,11 +1602,17 @@ class TestNegotiateAsRequestor:
         assert context.result == 0x00
         assert context.transfer_syntax == ["1.2.840.10008.1.2.1"]
 
-    @pytest.mark.skipif(PYDICOM_VERSION < ["2", "2"], reason="Old data dict")
     def test_typical(self):
         """Test a typical set of presentation context negotiations."""
         req_contexts = []
         for ii, context in enumerate(StoragePresentationContexts):
+            # Old pydicom UID dict
+            if context.abstract_syntax in (
+                "1.2.840.10008.5.1.4.1.1.6.3",
+                "1.2.840.10008.5.1.4.1.1.9.1.4",
+            ):
+                continue
+
             pc = PresentationContext()
             pc.context_id = ii * 2 + 1
             pc.abstract_syntax = context.abstract_syntax
@@ -2035,7 +2049,7 @@ class TestServiceContexts:
     def test_non_patient(self):
         """Tests with non patient object presentation contexts"""
         contexts = NonPatientObjectPresentationContexts
-        assert len(contexts) == 8
+        assert len(contexts) == 9
 
         for context in contexts:
             assert context.transfer_syntax == DEFAULT_TRANSFER_SYNTAXES
@@ -2044,11 +2058,12 @@ class TestServiceContexts:
         assert contexts[0].abstract_syntax == "1.2.840.10008.5.1.4.1.1.200.1"
         assert contexts[1].abstract_syntax == "1.2.840.10008.5.1.4.1.1.200.3"
         assert contexts[2].abstract_syntax == "1.2.840.10008.5.1.4.1.1.200.7"
-        assert contexts[3].abstract_syntax == "1.2.840.10008.5.1.4.38.1"
-        assert contexts[4].abstract_syntax == "1.2.840.10008.5.1.4.39.1"
-        assert contexts[5].abstract_syntax == "1.2.840.10008.5.1.4.43.1"
-        assert contexts[6].abstract_syntax == "1.2.840.10008.5.1.4.44.1"
-        assert contexts[7].abstract_syntax == "1.2.840.10008.5.1.4.45.1"
+        assert contexts[3].abstract_syntax == "1.2.840.10008.5.1.4.1.1.201.1"
+        assert contexts[4].abstract_syntax == "1.2.840.10008.5.1.4.38.1"
+        assert contexts[5].abstract_syntax == "1.2.840.10008.5.1.4.39.1"
+        assert contexts[6].abstract_syntax == "1.2.840.10008.5.1.4.43.1"
+        assert contexts[7].abstract_syntax == "1.2.840.10008.5.1.4.44.1"
+        assert contexts[8].abstract_syntax == "1.2.840.10008.5.1.4.45.1"
 
     def test_print_management(self):
         """Tests with print management presentation contexts"""
@@ -2100,14 +2115,14 @@ class TestServiceContexts:
     def test_qr(self):
         """Test the query/retrieve service presentation contexts."""
         contexts = QueryRetrievePresentationContexts
-        assert len(contexts) == 12
+        assert len(contexts) == 13
 
         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[0].abstract_syntax == "1.2.840.10008.5.1.4.1.1.201.6"
+        assert contexts[4].abstract_syntax == "1.2.840.10008.5.1.4.1.2.2.1"
         assert contexts[-1].abstract_syntax == "1.2.840.10008.5.1.4.1.2.5.3"
 
     def test_relevant_patient(self):
@@ -2145,8 +2160,8 @@ class TestServiceContexts:
             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.66.5"
-        assert contexts[-1].abstract_syntax == "1.2.840.10008.5.1.4.1.1.88.65"
+        assert contexts[80].abstract_syntax == "1.2.840.10008.5.1.4.1.1.77.1.6"
+        assert contexts[-1].abstract_syntax == "1.2.840.10008.5.1.4.34.7"
 
     def test_storage_commitement(self):
         """Tests with storage commitment presentation contexts"""
diff --git a/pynetdicom/tests/test_sop.py b/pynetdicom/tests/test_sop.py
index 213d718c2..f9af2f201 100644
--- a/pynetdicom/tests/test_sop.py
+++ b/pynetdicom/tests/test_sop.py
@@ -27,6 +27,8 @@ from pynetdicom.sop_class import (
     ImplantTemplateGroupInformationModelFind,
     _INSTANCE_AVAILABILITY_CLASSES,
     InstanceAvailabilityNotification,
+    _INVENTORY_CLASSES,
+    InventoryCreation,
     _MEDIA_CREATION_CLASSES,
     MediaCreationManagement,
     _MEDIA_STORAGE_CLASSES,
@@ -51,6 +53,8 @@ from pynetdicom.sop_class import (
     CTImageStorage,
     _STORAGE_COMMITMENT_CLASSES,
     StorageCommitmentPushModel,
+    _STORAGE_MANAGEMENT_CLASSES,
+    InventoryFind,
     _SUBSTANCE_ADMINISTRATION_CLASSES,
     ProductCharacteristicsQuery,
     _UNIFIED_PROCEDURE_STEP_CLASSES,
@@ -62,6 +66,7 @@ from pynetdicom.sop_class import (
     PrinterInstance,
     ProceduralEventLoggingInstance,
     StorageCommitmentPushModelInstance,
+    StorageManagementInstance,
     SubstanceAdministrationLoggingInstance,
     UPSFilteredGlobalSubscriptionInstance,
     UPSGlobalSubscriptionInstance,
@@ -116,6 +121,8 @@ def test_all_sop_classes():
         assert uid in UID_dictionary
     for uid in _INSTANCE_AVAILABILITY_CLASSES.values():
         assert uid in UID_dictionary
+    for uid in _INVENTORY_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():
@@ -134,11 +141,15 @@ def test_all_sop_classes():
         assert uid in UID_dictionary
     for uid in _RT_MACHINE_VERIFICATION_CLASSES.values():
         assert uid in UID_dictionary
-    if PYDICOM_VERSION >= ["2", "2"]:
-        for uid in _STORAGE_CLASSES.values():
-            assert uid in UID_dictionary
+    for uid in _STORAGE_CLASSES.values():
+        if uid in ("1.2.840.10008.5.1.4.1.1.6.3", "1.2.840.10008.5.1.4.1.1.9.1.4"):
+            continue
+
+        assert uid in UID_dictionary
     for uid in _STORAGE_COMMITMENT_CLASSES.values():
         assert uid in UID_dictionary
+    for uid in _STORAGE_MANAGEMENT_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():
@@ -160,6 +171,7 @@ def test_all_sop_instances():
     assert PrinterInstance in UID_dictionary
     assert ProceduralEventLoggingInstance in UID_dictionary
     assert StorageCommitmentPushModelInstance in UID_dictionary
+    assert StorageManagementInstance in UID_dictionary
     assert SubstanceAdministrationLoggingInstance in UID_dictionary
     assert UPSFilteredGlobalSubscriptionInstance in UID_dictionary
     assert UPSGlobalSubscriptionInstance in UID_dictionary