Repository: pydicom/pynetdicom

Issue:
Match the selected SOP classes of StoragePresentationContexts to DCMTK
As mentioned in #977, pynetdicom currently uses other selected SOP classes in `StoragePresentationContexts` than DCMTK. In my opinion (and also from a radiologist's point of view), the DCMTK selection is a bit more appropriate (this is, of course, debatable).

[This is what DCMTK uses](https://github.com/DCMTK/dcmtk/blob/d1fb197927fd4178b5a24e0f0dba6f8d785a8f93/dcmdata/libsrc/dcuid.cc#L895)
[And this is what pynetdicom](https://github.com/pydicom/pynetdicom/blob/37ccf384e6a1e5a844122b81542d65b263fa0682/pynetdicom/presentation.py#L1095)

If there is some interest, I can create a PR that matches the `StoragePresentationContexts` with that of DCMTK.

Hints from issue comments:
@scaramallion: Sounds good to me@mdebic: Implemented in c22be4b

Solution patch:
diff --git a/.github/workflows/merge-pytest.yml b/.github/workflows/merge-pytest.yml
index 9fdc64ec9..59639d061 100644
--- a/.github/workflows/merge-pytest.yml
+++ b/.github/workflows/merge-pytest.yml
@@ -13,7 +13,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        python-version: ['3.10', '3.11', '3.12']
+        python-version: ['3.10', '3.11', '3.12', '3.13']
 
     steps:
     - uses: actions/checkout@v4
@@ -42,7 +42,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        python-version: ['3.10', '3.11', '3.12']
+        python-version: ['3.10', '3.11', '3.12', '3.13']
 
     steps:
       - uses: actions/checkout@v4
@@ -60,7 +60,7 @@ jobs:
           pytest --cov pynetdicom --ignore=pynetdicom/apps && coverage xml
       - name: Send coverage results
         if: success()
-        uses: codecov/codecov-action@v4
+        uses: codecov/codecov-action@v5
         env:
           CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
 
@@ -94,7 +94,7 @@ jobs:
   #       pytest --cov pynetdicom --ignore=pynetdicom/apps && coverage xml
   #   - name: Send coverage results
   #     if: success()
-  #     uses: codecov/codecov-action@v4
+  #     uses: codecov/codecov-action@v5
   #     env:
   #       CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
 
@@ -105,7 +105,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        python-version: ['3.10', '3.11', '3.12']
+        python-version: ['3.10', '3.11', '3.12', '3.13']
 
     steps:
     - uses: actions/checkout@v4
@@ -126,6 +126,6 @@ jobs:
         pytest --cov pynetdicom --ignore=pynetdicom/apps
     - name: Send coverage results
       if: success()
-      uses: codecov/codecov-action@v4
+      uses: codecov/codecov-action@v5
       env:
         CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
diff --git a/.github/workflows/pr-pytest.yml b/.github/workflows/pr-pytest.yml
index 37327bc8a..476416ff1 100644
--- a/.github/workflows/pr-pytest.yml
+++ b/.github/workflows/pr-pytest.yml
@@ -66,7 +66,7 @@ jobs:
           pytest -x --cov pynetdicom --ignore=pynetdicom/apps
       - name: Send coverage results
         if: ${{ success() }}
-        uses: codecov/codecov-action@v4
+        uses: codecov/codecov-action@v5
 
   # pydicom-dev:
   #   # Matrix builds with development pydicom
@@ -98,7 +98,7 @@ jobs:
   #       pytest -x --cov pynetdicom --ignore=pynetdicom/apps && coverage xml
   #   - name: Send coverage results
   #     if: ${{ success() }}
-  #     uses: codecov/codecov-action@v4
+  #     uses: codecov/codecov-action@v5
 
   pydicom-release:
     # Matrix builds with released pydicom
@@ -107,7 +107,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        python-version: ['3.10', '3.11', '3.12']
+        python-version: ['3.10', '3.11', '3.12', '3.13']
 
     steps:
     - uses: actions/checkout@v4
@@ -131,4 +131,4 @@ jobs:
         pytest -x --cov pynetdicom --ignore=pynetdicom/apps
     - name: Send coverage results
       if: ${{ success() }}
-      uses: codecov/codecov-action@v4
+      uses: codecov/codecov-action@v5
diff --git a/docs/changelog/v2.2.0.rst b/docs/changelog/v2.2.0.rst
new file mode 100644
index 000000000..e7152d5ef
--- /dev/null
+++ b/docs/changelog/v2.2.0.rst
@@ -0,0 +1,11 @@
+.. _v2.2.0:
+
+2.2.0
+=====
+
+Changes
+.......
+
+* Move and Get SCPs are now limited to a maximum of 65535 matches (:issue:`982`)
+* Minimum supported pydicom version is 3.0 (:issue:`981`)
+* Added support for Python 3.13
diff --git a/docs/changelog/v3.0.0.rst b/docs/changelog/v3.0.0.rst
new file mode 100644
index 000000000..459ba5118
--- /dev/null
+++ b/docs/changelog/v3.0.0.rst
@@ -0,0 +1,10 @@
+.. _v3.0.0:
+
+3.0.0
+=====
+
+The major breaking changes with the version 3.0 release are:
+
+  * Support for pydicom v3
+  * Changed ``StoragePresentationContexts`` to match DCMTK implementation
+     * Some presentation contexts were replaced
diff --git a/docs/examples/qr_get.rst b/docs/examples/qr_get.rst
index bb39aa118..8e7607e94 100644
--- a/docs/examples/qr_get.rst
+++ b/docs/examples/qr_get.rst
@@ -3,7 +3,7 @@ Query/Retrieve (Get) Service Examples
 
 The DICOM :dcm:`Query/Retrieve Service <part04/chapter_C.html>`
 provides a mechanism for a service user to query and retrieve the SOP Instances
-managed by a QR SCP. The QR (Get) SOP classes allow an SCU to receive SOP
+managed by a QR SCP. The QR (Get) SOP classes allow an SCU to receive up to 65535 SOP
 Instances that match the requested query. This is accomplished through the
 DIMSE C-GET and C-STORE services. Both query and
 retrieval occur over the same association, with the SCP of the Query/Retrieve
diff --git a/docs/examples/qr_move.rst b/docs/examples/qr_move.rst
index ee952004d..b4295df2b 100644
--- a/docs/examples/qr_move.rst
+++ b/docs/examples/qr_move.rst
@@ -4,7 +4,7 @@ Query/Retrieve (Move) Service Examples
 The DICOM :dcm:`Query/Retrieve Service <part04/chapter_C.html>`
 provides a mechanism for a service user to query and retrieve the SOP Instances
 managed by a QR SCP. The QR (Move) SOP classes allow an SCU to request an SCP
-send matching SOP Instances to a known Storage SCP over a new association.
+send up to 65535 matching SOP Instances to a known Storage SCP over a new association.
 This is accomplished through the DIMSE C-MOVE and C-STORE services.
 
 One limitation of the C-MOVE service is that the Move SCP/Storage SCU must
diff --git a/docs/examples/storage.rst b/docs/examples/storage.rst
index 84c8de333..db6bc1f00 100644
--- a/docs/examples/storage.rst
+++ b/docs/examples/storage.rst
@@ -57,7 +57,7 @@ single CT dataset.
 Of course it's rarely the case that someone wants to store just CT images,
 so you can also use the inbuilt
 :attr:`~pynetdicom.presentation.StoragePresentationContexts` which contains
-presentation contexts for the first 128 storage SOP Classes when setting
+presentation contexts for the first 120 storage SOP Classes when setting
 the requested contexts, or just add as many contexts as you need.
 
 .. code-block:: python
diff --git a/docs/service_classes/query_retrieve_service_class.rst b/docs/service_classes/query_retrieve_service_class.rst
index 7daafe44e..26819d366 100644
--- a/docs/service_classes/query_retrieve_service_class.rst
+++ b/docs/service_classes/query_retrieve_service_class.rst
@@ -236,6 +236,9 @@ pynetdicom Query/Retrieve (Get) Statuses
 | 0xC413           | Failure  | The handler bound to ``evt.EVT_C_GET``        |
 |                  |          | yielded an invalid number of sub-operations   |
 +------------------+----------+-----------------------------------------------+
+| 0xC416           | Failure  | The handler bound to ``evt.EVT_C_GET``        |
+|                  |          | yielded more than 65535 matches               |
++------------------+----------+-----------------------------------------------+
 
 
 .. _qr_move_statuses:
@@ -328,3 +331,6 @@ pynetdicom Query/Retrieve (Move) Statuses
 | 0xC515           | Failure  | The handler bound to ``evt.EVT_C_MOVE``       |
 |                  |          | failed to yield a valid (address, port) pair  |
 +------------------+----------+-----------------------------------------------+
+| 0xC516           | Failure  | The handler bound to ``evt.EVT_C_MOVE``       |
+|                  |          | yielded more than 65535 matches               |
++------------------+----------+-----------------------------------------------+
diff --git a/docs/user/ae.rst b/docs/user/ae.rst
index ba9d7bc00..74dc8ece9 100644
--- a/docs/user/ae.rst
+++ b/docs/user/ae.rst
@@ -88,8 +88,8 @@ Adding presentation contexts all at once:
     >>> ae.requested_contexts = StoragePresentationContexts
 
 Here :attr:`~pynetdicom.presentation.StoragePresentationContexts` is a
-prebuilt list of presentation contexts containing (almost) all the Storage
-Service Class' :dcm:`supported SOP Classes <part04/sect_B.5.html>`,
+prebuilt list of presentation contexts containing 120 of the most commonly used Storage
+Service Classes' :dcm:`supported SOP Classes <part04/sect_B.5.html>`,
 and there's a :ref:`similar list<api_presentation_prebuilt>` for all
 the supported service classes.
 Alternatively you can build your own list of presentation contexts, either
@@ -115,12 +115,13 @@ Combining the all-at-once and one-by-one approaches:
     >>> from pynetdicom import AE, StoragePresentationContexts
     >>> from pynetdicom.sop_class import Verification
     >>> ae = AE()
-    >>> ae.requested_contexts = StoragePresentationContexts[:127]
+    >>> ae.requested_contexts = StoragePresentationContexts
     >>> ae.add_requested_context(Verification)
 
 As the association *Requestor* you're limited to a total of 128 requested
 presentation contexts, so attempting to add more than 128 contexts will raise
-a :class:`ValueError` exception.
+a :class:`ValueError` exception.  :attr:`~pynetdicom.presentation.StoragePresentationContexts` consists of 120 of most commonly used Storage
+Service Classes, therefore you are able to add 8 additional presentation contexts without rasing a :class:`ValueError` exception.
 
 When you add presentation contexts as shown above, the following transfer
 syntaxes are used by default for each context:
@@ -285,8 +286,8 @@ Adding presentation contexts all at once:
     >>> ae.supported_contexts = StoragePresentationContexts
 
 Here :attr:`~pynetdicom.presentation.StoragePresentationContexts` is a prebuilt
-:class:`list` of presentation contexts containing (almost) all the Storage
-Service Class' :dcm:`supported SOP Classes<part04/sect_B.5.html>`,
+:class:`list` of presentation contexts containing 120 of the most commonly used Storage
+Service Classes' :dcm:`supported SOP Classes<part04/sect_B.5.html>`,
 and there's a :ref:`similar list<api_presentation_prebuilt>` for
 all the supported service classes. Alternatively you can build your own list
 of presentation contexts, either through creating new
diff --git a/docs/user/association.rst b/docs/user/association.rst
index 42ead28a6..7a97dd875 100644
--- a/docs/user/association.rst
+++ b/docs/user/association.rst
@@ -95,15 +95,16 @@ also acting as a Storage SCP), plus a *User Identity Negotiation* item:
 
     ae = AE()
     # Contexts supported as a Storage SCP - requires Role Selection
-    #   Note that we are limited to a maximum of 128 contexts so we
-    #   only include 127 to make room for the QR Get context
-    ae.requested_contexts = StoragePresentationContexts[:127]
+    #   Note that we are limited to a maximum of 128 contexts.
+    #   StoragePresentationContexts includes 120, it is therefore 
+    #   possible to add 8 additional presentation contexts if needed.
+    ae.requested_contexts = StoragePresentationContexts
     # Contexts proposed as a QR SCU
     ae.add_requested_context = PatientRootQueryRetrieveInformationModelGet
 
     # Add role selection items for the contexts we will be supporting as an SCP
     negotiation_items = []
-    for context in StoragePresentationContexts[:127]:
+    for context in StoragePresentationContexts:
         role = build_role(context.abstract_syntax, scp_role=True)
         negotiation_items.append(role)
 
diff --git a/pynetdicom/apps/getscu/getscu.py b/pynetdicom/apps/getscu/getscu.py
index 70f7dae80..aee0f6107 100755
--- a/pynetdicom/apps/getscu/getscu.py
+++ b/pynetdicom/apps/getscu/getscu.py
@@ -20,9 +20,6 @@
     PatientRootQueryRetrieveInformationModelGet,
     StudyRootQueryRetrieveInformationModelGet,
     PatientStudyOnlyQueryRetrieveInformationModelGet,
-    EncapsulatedSTLStorage,
-    EncapsulatedOBJStorage,
-    EncapsulatedMTLStorage,
 )
 
 
@@ -248,16 +245,6 @@ def main(args=None):
         APP_LOGGER.exception(exc)
         sys.exit(1)
 
-    # Exclude these SOP Classes
-    _exclusion = [
-        EncapsulatedSTLStorage,
-        EncapsulatedOBJStorage,
-        EncapsulatedMTLStorage,
-    ]
-    store_contexts = [
-        cx for cx in StoragePresentationContexts if cx.abstract_syntax not in _exclusion
-    ]
-
     # Create application entity
     # Binding to port 0 lets the OS pick an available port
     ae = AE(ae_title=args.calling_aet)
@@ -270,7 +257,7 @@ def main(args=None):
     ae.add_requested_context(PatientRootQueryRetrieveInformationModelGet)
     ae.add_requested_context(StudyRootQueryRetrieveInformationModelGet)
     ae.add_requested_context(PatientStudyOnlyQueryRetrieveInformationModelGet)
-    for cx in store_contexts:
+    for cx in StoragePresentationContexts:
         ae.add_requested_context(cx.abstract_syntax)
         # Add SCP/SCU Role Selection Negotiation to the extended negotiation
         # We want to act as a Storage SCP
diff --git a/pynetdicom/presentation.py b/pynetdicom/presentation.py
index 0b84cfa98..fba75c7ea 100644
--- a/pynetdicom/presentation.py
+++ b/pynetdicom/presentation.py
@@ -1093,139 +1093,132 @@ def build_role(
 """Pre-built presentation contexts for :dcm:`Storage<part04/chapter_B.html>` containing all 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
+    "1.2.840.10008.5.1.4.1.1.9.1.3", # AmbulatoryECGWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.9.5.1", # ArterialPulseWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.78.2", # AutorefractionMeasurementsStorage
+    "1.2.840.10008.5.1.4.1.1.131", # BasicStructuredDisplayStorage
+    "1.2.840.10008.5.1.4.1.1.88.11", # BasicTextSRStorage
+    "1.2.840.10008.5.1.4.1.1.9.4.1", # BasicVoiceAudioWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.11.4", # BlendingSoftcopyPresentationStateStorage
+    "1.2.840.10008.5.1.4.1.1.13.1.3", # BreastTomosynthesisImageStorage
+    "1.2.840.10008.5.1.4.1.1.9.3.1", # CardiacElectrophysiologyWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.88.65", # ChestCADSRStorage
+    "1.2.840.10008.5.1.4.1.1.88.69", # ColonCADSRStorage
+    "1.2.840.10008.5.1.4.1.1.11.2", # ColorSoftcopyPresentationStateStorage
+    "1.2.840.10008.5.1.4.1.1.88.34", # Comprehensive3DSRStorage
+    "1.2.840.10008.5.1.4.1.1.88.33", # ComprehensiveSRStorage
+    "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.66.3", # DeformableSpatialRegistrationStorage
+    "1.2.840.10008.5.1.4.1.1.1.3", # DigitalIntraOralXRayImageStorageForPresentation
+    "1.2.840.10008.5.1.4.1.1.1.3.1", # DigitalIntraOralXRayImageStorageForProcessing
+    "1.2.840.10008.5.1.4.1.1.1.2", # DigitalMammographyXRayImageStorageForPresentation
+    "1.2.840.10008.5.1.4.1.1.1.2.1", # DigitalMammographyXRayImageStorageForProcessing
+    "1.2.840.10008.5.1.4.1.1.1.1", # DigitalXRayImageStorageForPresentation
+    "1.2.840.10008.5.1.4.1.1.1.1.1", # DigitalXRayImageStorageForProcessing
+    "1.2.840.10008.5.1.4.1.1.104.2", # EncapsulatedCDAStorage
+    "1.2.840.10008.5.1.4.1.1.104.1", # EncapsulatedPDFStorage
+    "1.2.840.10008.5.1.4.1.1.2.1", # EnhancedCTImageStorage
+    "1.2.840.10008.5.1.4.1.1.4.3", # EnhancedMRColorImageStorage
+    "1.2.840.10008.5.1.4.1.1.4.1", # EnhancedMRImageStorage
+    "1.2.840.10008.5.1.4.1.1.130", # EnhancedPETImageStorage
+    "1.2.840.10008.5.1.4.1.1.88.22", # EnhancedSRStorage
+    "1.2.840.10008.5.1.4.1.1.6.2", # EnhancedUSVolumeStorage
+    "1.2.840.10008.5.1.4.1.1.12.1.1", # EnhancedXAImageStorage
+    "1.2.840.10008.5.1.4.1.1.12.2.1", # EnhancedXRFImageStorage
+    "1.2.840.10008.5.1.4.1.1.9.4.2", # GeneralAudioWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.9.1.2", # GeneralECGWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.11.1", # GrayscaleSoftcopyPresentationStateStorage
+    "1.2.840.10008.5.1.4.1.1.9.2.1", # HemodynamicWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.88.70", # ImplantationPlanSRStorage
+    "1.2.840.10008.5.1.4.1.1.78.8", # IntraocularLensCalculationsStorage
+    "1.2.840.10008.5.1.4.1.1.14.1", # IntravascularOpticalCoherenceTomographyImageStorageForPresentation
+    "1.2.840.10008.5.1.4.1.1.14.2", # IntravascularOpticalCoherenceTomographyImageStorageForProcessing
+    "1.2.840.10008.5.1.4.1.1.78.3", # KeratometryMeasurementsStorage
+    "1.2.840.10008.5.1.4.1.1.88.59", # KeyObjectSelectionDocumentStorage
+    "1.2.840.10008.5.1.4.1.1.2.2", # LegacyConvertedEnhancedCTImageStorage
+    "1.2.840.10008.5.1.4.1.1.4.4", # LegacyConvertedEnhancedMRImageStorage
+    "1.2.840.10008.5.1.4.1.1.128.1", # LegacyConvertedEnhancedPETImageStorage
+    "1.2.840.10008.5.1.4.1.1.78.1", # LensometryMeasurementsStorage
+    "1.2.840.10008.5.1.4.1.1.79.1", # MacularGridThicknessAndVolumeReportStorage
+    "1.2.840.10008.5.1.4.1.1.88.50", # MammographyCADSRStorage
+    "1.2.840.10008.5.1.4.1.1.4", # MRImageStorage
+    "1.2.840.10008.5.1.4.1.1.4.2", # MRSpectroscopyStorage
+    "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.1", # MultiframeSingleBitSecondaryCaptureImageStorage
+    "1.2.840.10008.5.1.4.1.1.7.4", # MultiframeTrueColorSecondaryCaptureImageStorage
+    "1.2.840.10008.5.1.4.1.1.20", # NuclearMedicineImageStorage
+    "1.2.840.10008.5.1.4.1.1.78.7", # OphthalmicAxialMeasurementsStorage
+    "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.1", # OphthalmicPhotography8BitImageStorage
+    "1.2.840.10008.5.1.4.1.1.81.1", # OphthalmicThicknessMapStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.5.4", # OphthalmicTomographyImageStorage
+    "1.2.840.10008.5.1.4.1.1.80.1", # OphthalmicVisualFieldStaticPerimetryMeasurementsStorage
+    "1.2.840.10008.5.1.4.1.1.128", # PositronEmissionTomographyImageStorage
+    "1.2.840.10008.5.1.4.1.1.88.40", # ProcedureLogStorage
+    "1.2.840.10008.5.1.4.1.1.11.3", # PseudoColorSoftcopyPresentationStateStorage
+    "1.2.840.10008.5.1.4.1.1.66", # RawDataStorage
+    "1.2.840.10008.5.1.4.1.1.67", # RealWorldValueMappingStorage
+    "1.2.840.10008.5.1.4.1.1.9.6.1", # RespiratoryWaveformStorage
+    "1.2.840.10008.5.1.4.34.7", # RTBeamsDeliveryInstructionStorage
+    "1.2.840.10008.5.1.4.1.1.481.4", # RTBeamsTreatmentRecordStorage
+    "1.2.840.10008.5.1.4.1.1.481.6", # RTBrachyTreatmentRecordStorage
+    "1.2.840.10008.5.1.4.1.1.481.2", # RTDoseStorage
+    "1.2.840.10008.5.1.4.1.1.481.1", # RTImageStorage
+    "1.2.840.10008.5.1.4.1.1.481.9", # RTIonBeamsTreatmentRecordStorage
+    "1.2.840.10008.5.1.4.1.1.481.8", # RTIonPlanStorage
+    "1.2.840.10008.5.1.4.1.1.481.5", # RTPlanStorage
+    "1.2.840.10008.5.1.4.1.1.481.3", # RTStructureSetStorage
+    "1.2.840.10008.5.1.4.1.1.481.7", # RTTreatmentSummaryRecordStorage
+    "1.2.840.10008.5.1.4.1.1.7", # SecondaryCaptureImageStorage
+    "1.2.840.10008.5.1.4.1.1.66.4", # SegmentationStorage
+    "1.2.840.10008.5.1.4.1.1.66.2", # SpatialFiducialsStorage
+    "1.2.840.10008.5.1.4.1.1.66.1", # SpatialRegistrationStorage
+    "1.2.840.10008.5.1.4.1.1.78.6", # SpectaclePrescriptionReportStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.5.3", # StereometricRelationshipStorage
+    "1.2.840.10008.5.1.4.1.1.78.4", # SubjectiveRefractionMeasurementsStorage
+    "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.66.5", # SurfaceSegmentationStorage
+    "1.2.840.10008.5.1.4.1.1.9.1.1", # TwelveLeadECGWaveformStorage
+    "1.2.840.10008.5.1.4.1.1.6.1", # UltrasoundImageStorage
+    "1.2.840.10008.5.1.4.1.1.3.1", # UltrasoundMultiframeImageStorage
+    "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.1", # VideoMicroscopicImageStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.4.1", # VideoPhotographicImageStorage
+    "1.2.840.10008.5.1.4.1.1.78.5", # VisualAcuityMeasurementsStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.1", # VLEndoscopicImageStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.2", # VLMicroscopicImageStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.4", # VLPhotographicImageStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.3", # VLSlideCoordinatesMicroscopicImageStorage
+    "1.2.840.10008.5.1.4.1.1.77.1.6", # VLWholeSlideMicroscopyImageStorage
+    "1.2.840.10008.5.1.4.1.1.11.5", # XAXRFGrayscaleSoftcopyPresentationStateStorage
+    "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.12.1", # XRayAngiographicImageStorage
+    "1.2.840.10008.5.1.4.1.1.88.67", # XRayRadiationDoseSRStorage
+    "1.2.840.10008.5.1.4.1.1.12.2", # XRayRadiofluoroscopicImageStorage
+    ## retired but still in use
+    "1.2.840.10008.5.1.1.30", # HardcopyColorImageStorage
+    "1.2.840.10008.5.1.1.29", # HardcopyGrayscaleImageStorage
+    "1.2.840.10008.5.1.4.1.1.5", # NuclearMedicineImageStorageRetired
+    "1.2.840.10008.5.1.4.1.1.9", # StandaloneCurveStorage
+    "1.2.840.10008.5.1.4.1.1.10", # StandaloneModalityLUTStorage
+    "1.2.840.10008.5.1.4.1.1.8", # StandaloneOverlayStorage
+    "1.2.840.10008.5.1.4.1.1.129", # StandalonePETCurveStorage
+    "1.2.840.10008.5.1.4.1.1.11", # StandaloneVOILUTStorage
+    "1.2.840.10008.5.1.1.27", # StoredPrintStorage
+    "1.2.840.10008.5.1.4.1.1.6", # UltrasoundImageStorageRetired
+    "1.2.840.10008.5.1.4.1.1.3", # UltrasoundMultiframeImageStorageRetired
+    "1.2.840.10008.5.1.4.1.1.77.1", # VLImageStorage
+    "1.2.840.10008.5.1.4.1.1.77.2", # VLMultiframeImageStorage
+    "1.2.840.10008.5.1.4.1.1.12.3", # XRayAngiographicBiPlaneImageStorage
 ]
-assert len(_storage) <= 128
+assert len(_storage) <= 120
 
 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."""
+"""Pre-built presentation contexts for :dcm:`Storage<part04/chapter_B.html>` containing 120 selected SOP Classes."""
 
 StorageCommitmentPresentationContexts = [
     build_context(uid) for uid in sorted(_STORAGE_COMMITMENT_CLASSES.values())
diff --git a/pynetdicom/service_class.py b/pynetdicom/service_class.py
index 015556173..797d9b9f2 100644
--- a/pynetdicom/service_class.py
+++ b/pynetdicom/service_class.py
@@ -1694,23 +1694,31 @@ def _get_scp(self, req: C_GET, context: "PresentationContext") -> None:
                 "sub-operations value"
             )
             ctx.error_status = 0xC413
-            no_suboperations = int(next(generator))
+            nr_suboperations = int(next(generator))
 
         if not ctx.success:
             return
 
-        if no_suboperations < 1:
+        if nr_suboperations < 1:
             rsp.Status = 0x0000
-            rsp.NumberOfRemainingSuboperations = 0
             rsp.NumberOfFailedSuboperations = 0
             rsp.NumberOfWarningSuboperations = 0
             rsp.NumberOfCompletedSuboperations = 0
             self.dimse.send_msg(rsp, cx_id)
             return
 
+        if nr_suboperations > 65535:
+            # Since Number of * Suboperations are US and have a maximum value of 65535,
+            #   and Sections C.4.3.2 and C.4.3.3 require them in the final response,
+            #   that implies no more than 65535 matches
+            LOGGER.error("The C-GET request handler yielded more than 65535 matches")
+            rsp.Status = 0xC416
+            self.dimse.send_msg(rsp, cx_id)
+            return
+
         # Track the sub operation results
         #   [remaining, failed, warning, complete]
-        store_results = [no_suboperations, 0, 0, 0]
+        store_results = [nr_suboperations, 0, 0, 0]
 
         # Store the SOP Instance UIDs from any failed C-STORE sub-operations
         failed_instances = []
@@ -1797,7 +1805,6 @@ def _add_failed_instance(ds: Dataset) -> None:
                     f"Get SCP Result {ii + 1}: 0x{rsp.Status:04X} "
                     f"({status[0]} - {status[1]})"
                 )
-                rsp.NumberOfRemainingSuboperations = None
                 rsp.NumberOfFailedSuboperations = store_results[1] + store_results[0]
                 rsp.NumberOfWarningSuboperations = store_results[2]
                 rsp.NumberOfCompletedSuboperations = store_results[3]
@@ -1838,7 +1845,6 @@ def _add_failed_instance(ds: Dataset) -> None:
                     LOGGER.info(f"Get SCP Response {ii + 1}: 0x0000 (Success)")
                     rsp.Identifier = None
 
-                rsp.NumberOfRemainingSuboperations = None
                 rsp.NumberOfFailedSuboperations = store_results[1]
                 rsp.NumberOfWarningSuboperations = store_results[2]
                 rsp.NumberOfCompletedSuboperations = store_results[3]
@@ -1857,6 +1863,7 @@ def _add_failed_instance(ds: Dataset) -> None:
                     rsp.NumberOfFailedSuboperations = store_results[1]
                     rsp.NumberOfWarningSuboperations = store_results[2]
                     rsp.NumberOfCompletedSuboperations = store_results[3]
+
                     self.dimse.send_msg(rsp, cx_id)
                     continue
 
@@ -1961,7 +1968,7 @@ def _add_failed_instance(ds: Dataset) -> None:
             rsp.Status = 0x0000
             rsp.Identifier = None
         else:
-            if no_suboperations == store_results[1]:
+            if nr_suboperations == store_results[1]:
                 # Failure response - all sub-operations failed
                 LOGGER.info(f"Get SCP Response {ii + 2}: 0xA702 (Failure)")
                 rsp.Status = 0xA702  # Unable to perform sub-ops
@@ -1982,7 +1989,6 @@ def _add_failed_instance(ds: Dataset) -> None:
             )
             rsp.Identifier = BytesIO(cast(bytes, bytestream))
 
-        rsp.NumberOfRemainingSuboperations = None
         rsp.NumberOfFailedSuboperations = store_results[1]
         rsp.NumberOfWarningSuboperations = store_results[2]
         rsp.NumberOfCompletedSuboperations = store_results[3]
@@ -2085,21 +2091,29 @@ def _move_scp(self, req: C_MOVE, context: "PresentationContext") -> None:
                 "sub-operations value"
             )
             ctx.error_status = 0xC513
-            no_suboperations = int(next(generator))
+            nr_suboperations = int(next(generator))
 
         # Exception in context or handler aborted/released - second yield
         if not ctx.success or not self.assoc.is_established:
             return
 
-        if no_suboperations < 1:
+        if nr_suboperations < 1:
             rsp.Status = 0x0000
-            rsp.NumberOfRemainingSuboperations = 0
             rsp.NumberOfFailedSuboperations = 0
             rsp.NumberOfWarningSuboperations = 0
             rsp.NumberOfCompletedSuboperations = 0
             self.dimse.send_msg(rsp, cx_id)
             return
 
+        if nr_suboperations > 65535:
+            # Since Number of * Suboperations are US and have a maximum value of 65535,
+            #   and Sections C.4.2.2 and C.4.2.3 require them in the final response,
+            #   that implies no more than 65535 matches
+            LOGGER.error("The C-MOVE request handler yielded more than 65535 matches")
+            rsp.Status = 0xC516
+            self.dimse.send_msg(rsp, cx_id)
+            return
+
         # Try to request new association with Move Destination
         with attempt(rsp, self.dimse, cx_id) as ctx:
             ctx.error_msg = (
@@ -2131,7 +2145,7 @@ def _move_scp(self, req: C_MOVE, context: "PresentationContext") -> None:
 
         # Track the sub operation results
         #   [remaining, failed, warning, complete]
-        store_results = [no_suboperations, 0, 0, 0]
+        store_results = [nr_suboperations, 0, 0, 0]
 
         # Store the SOP Instance UIDs from any failed C-STORE sub-operations
         failed_instances = []
@@ -2243,7 +2257,6 @@ def _add_failed_instance(ds: Dataset) -> None:
                 )
 
                 rsp.Identifier = BytesIO(cast(bytes, bytestream))
-                rsp.NumberOfRemainingSuboperations = None
                 rsp.NumberOfFailedSuboperations = store_results[1] + store_results[0]
                 rsp.NumberOfWarningSuboperations = store_results[2]
                 rsp.NumberOfCompletedSuboperations = store_results[3]
@@ -2275,7 +2288,6 @@ def _add_failed_instance(ds: Dataset) -> None:
                     LOGGER.info(f"Move SCP Response {ii + 1}: 0x0000 (Success)")
                     rsp.Identifier = None
 
-                rsp.NumberOfRemainingSuboperations = None
                 rsp.NumberOfFailedSuboperations = store_results[1]
                 rsp.NumberOfWarningSuboperations = store_results[2]
                 rsp.NumberOfCompletedSuboperations = store_results[3]
@@ -2367,7 +2379,7 @@ def _add_failed_instance(ds: Dataset) -> None:
             rsp.Status = 0x0000
             rsp.Identifier = None
         else:
-            if no_suboperations == store_results[1]:
+            if nr_suboperations == store_results[1]:
                 # Failure response - all sub-operations failed
                 LOGGER.info(f"Move SCP Response {ii + 2}: 0xA702 (Failure)")
                 rsp.Status = 0xA702  # Unable to perform sub-ops
@@ -2388,7 +2400,6 @@ def _add_failed_instance(ds: Dataset) -> None:
             )
             rsp.Identifier = BytesIO(cast(bytes, bytestream))
 
-        rsp.NumberOfRemainingSuboperations = None
         rsp.NumberOfFailedSuboperations = store_results[1]
         rsp.NumberOfWarningSuboperations = store_results[2]
         rsp.NumberOfCompletedSuboperations = store_results[3]
diff --git a/pyproject.toml b/pyproject.toml
index d06de01e9..66f032e36 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -17,6 +17,8 @@ classifiers=[
     "Programming Language :: Python :: 3.10",
     "Programming Language :: Python :: 3.11",
     "Programming Language :: Python :: 3.12",
+    "Programming Language :: Python :: 3.13",
+    "Programming Language :: Python :: 3.14",
     "Operating System :: OS Independent",
     "Topic :: Scientific/Engineering :: Medical Science Apps.",
     "Topic :: Software Development :: Libraries",


Test patch:
diff --git a/pynetdicom/apps/tests/test_getscu.py b/pynetdicom/apps/tests/test_getscu.py
index b5b6f34d8..40aecf8ea 100644
--- a/pynetdicom/apps/tests/test_getscu.py
+++ b/pynetdicom/apps/tests/test_getscu.py
@@ -111,14 +111,14 @@ def handle_release(event):
         assert "GETSCU" == requestor.ae_title
         assert 16382 == requestor.maximum_length
         assert "ANY-SCP" == requestor.primitive.called_ae_title
-        assert 125 == len(requestor.extended_negotiation)
+        assert 120 == len(requestor.extended_negotiation)
         assert (1, 1) == requestor.asynchronous_operations
         assert {} == requestor.sop_class_common_extended
         assert {} == requestor.sop_class_extended
         assert requestor.role_selection != {}
         assert requestor.user_identity == None
         cxs = requestor.primitive.presentation_context_definition_list
-        assert len(cxs) == 128
+        assert len(cxs) == 123
         cxs = {cx.abstract_syntax: cx for cx in cxs}
         assert PatientRootQueryRetrieveInformationModelGet in cxs
         cx = cxs[PatientRootQueryRetrieveInformationModelGet]
diff --git a/pynetdicom/apps/tests/test_storescu.py b/pynetdicom/apps/tests/test_storescu.py
index 88b8cf8e6..bda0bd762 100644
--- a/pynetdicom/apps/tests/test_storescu.py
+++ b/pynetdicom/apps/tests/test_storescu.py
@@ -104,7 +104,7 @@ def handle_release(event):
         assert {} == requestor.sop_class_extended
         assert requestor.user_identity == None
         cxs = requestor.primitive.presentation_context_definition_list
-        assert len(cxs) == 128
+        assert len(cxs) == 120
         cxs = {cx.abstract_syntax: cx for cx in cxs}
         assert CTImageStorage in cxs
         assert cxs[CTImageStorage].transfer_syntax == [
@@ -422,7 +422,7 @@ def handle_release(event):
         assert events[1].event == evt.EVT_RELEASED
         requestor = events[1].assoc.requestor
         cxs = requestor.primitive.presentation_context_definition_list
-        assert len(cxs) == 128
+        assert len(cxs) == 120
         cxs = {cx.abstract_syntax: cx for cx in cxs}
         assert CTImageStorage in cxs
         assert cxs[CTImageStorage].transfer_syntax == [ExplicitVRLittleEndian]
@@ -459,7 +459,7 @@ def handle_release(event):
         requestor = events[1].assoc.requestor
         cxs = requestor.primitive.presentation_context_definition_list
         cxs = requestor.primitive.presentation_context_definition_list
-        assert len(cxs) == 128
+        assert len(cxs) == 120
         cxs = {cx.abstract_syntax: cx for cx in cxs}
         assert CTImageStorage in cxs
         assert cxs[CTImageStorage].transfer_syntax == [ExplicitVRBigEndian]
@@ -496,7 +496,7 @@ def handle_release(event):
         requestor = events[1].assoc.requestor
         cxs = requestor.primitive.presentation_context_definition_list
         cxs = requestor.primitive.presentation_context_definition_list
-        assert len(cxs) == 128
+        assert len(cxs) == 120
         cxs = {cx.abstract_syntax: cx for cx in cxs}
         assert CTImageStorage in cxs
         assert cxs[CTImageStorage].transfer_syntax == [ImplicitVRLittleEndian]
diff --git a/pynetdicom/tests/test_presentation.py b/pynetdicom/tests/test_presentation.py
index 29a5f7418..fef0f7e62 100644
--- a/pynetdicom/tests/test_presentation.py
+++ b/pynetdicom/tests/test_presentation.py
@@ -2153,14 +2153,17 @@ def test_rt_machine(self):
     def test_storage(self):
         """Test the storage service presentation contexts"""
         contexts = StoragePresentationContexts
-        assert len(contexts) == 128
+        assert len(contexts) == 120
+
+        # If this assert fails and the previous passes, there is a duplicate in the list
+        assert len(contexts) == len(set(contexts))
 
         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.6"
+        assert contexts[0].abstract_syntax == "1.2.840.10008.5.1.1.27"
+        assert contexts[80].abstract_syntax == "1.2.840.10008.5.1.4.1.1.77.1.5.1"
         assert contexts[-1].abstract_syntax == "1.2.840.10008.5.1.4.34.7"
 
     def test_storage_commitement(self):
diff --git a/pynetdicom/tests/test_service_qr.py b/pynetdicom/tests/test_service_qr.py
index fa25da6ae..e4dd1212b 100644
--- a/pynetdicom/tests/test_service_qr.py
+++ b/pynetdicom/tests/test_service_qr.py
@@ -10,6 +10,7 @@
 """
 
 from io import BytesIO
+import logging
 import os
 import time
 
@@ -1390,6 +1391,50 @@ def handle_store(event):
         assert assoc.is_released
         scp.shutdown()
 
+    def test_get_handler_too_many_subops(self, caplog):
+        """Test handler yielding more than 65535 subops"""
+
+        def handle(event):
+            yield 65536
+            status = Dataset()
+            status.Status = 0xFF00
+            yield status, self.ds
+            yield 0x0000, None
+
+        def handle_store(event):
+            return 0x0000
+
+        handlers = [(evt.EVT_C_GET, handle), (evt.EVT_C_STORE, handle_store)]
+
+        self.ae = ae = AE()
+        ae.add_supported_context(PatientRootQueryRetrieveInformationModelGet)
+        ae.add_supported_context(CTImageStorage, scu_role=False, scp_role=True)
+        ae.add_requested_context(PatientRootQueryRetrieveInformationModelGet)
+        ae.add_requested_context(CTImageStorage)
+        scp = ae.start_server(("localhost", 11112), block=False, evt_handlers=handlers)
+
+        role = build_role(CTImageStorage, scp_role=True)
+
+        ae.acse_timeout = 5
+        ae.dimse_timeout = 5
+        assoc = ae.associate("localhost", 11112, ext_neg=[role])
+        assert assoc.is_established
+        with caplog.at_level(logging.ERROR, logger="pynetdicom"):
+            result = assoc.send_c_get(
+                self.query, PatientRootQueryRetrieveInformationModelGet
+            )
+            status, identifier = next(result)
+            assert status.Status == 0xC416
+            pytest.raises(StopIteration, next, result)
+
+            assoc.release()
+            assert assoc.is_released
+            scp.shutdown()
+
+        assert (
+            "The C-GET request handler yielded more than 65535 matches" in caplog.text
+        )
+
     def test_get_handler_status_dataset(self):
         """Test handler yielding a Dataset status"""
 
@@ -3064,11 +3109,11 @@ def handle_store(event):
 
         self.ae = ae = AE()
         ae.add_supported_context(PatientRootQueryRetrieveInformationModelGet)
-        ae.requested_contexts = StoragePresentationContexts[:120]
+        ae.requested_contexts = StoragePresentationContexts
         ae.add_requested_context(PatientRootQueryRetrieveInformationModelGet)
 
         roles = []
-        for cx in StoragePresentationContexts[:120]:
+        for cx in StoragePresentationContexts:
             roles.append(build_role(cx.abstract_syntax, scp_role=True))
             ae.add_supported_context(cx.abstract_syntax, scu_role=False, scp_role=True)
 
@@ -3869,6 +3914,42 @@ def handle(event):
         assoc.release()
         scp.shutdown()
 
+    def test_move_handler_too_many_subops(self, caplog):
+        """Test handler yielding more than 65535 subops"""
+
+        def handle(event):
+            yield ("127.0.0.1", 11112)
+            yield 65536
+            yield 0xFF00, self.ds
+
+        handlers = [(evt.EVT_C_MOVE, handle)]
+
+        self.ae = ae = AE()
+        ae.add_supported_context(PatientRootQueryRetrieveInformationModelMove)
+        ae.add_supported_context(CTImageStorage, scu_role=False, scp_role=True)
+        ae.add_requested_context(PatientRootQueryRetrieveInformationModelMove)
+        ae.add_requested_context(CTImageStorage)
+        scp = ae.start_server(("localhost", 11112), block=False, evt_handlers=handlers)
+
+        ae.acse_timeout = 5
+        ae.dimse_timeout = 5
+        assoc = ae.associate("localhost", 11112)
+        assert assoc.is_established
+        with caplog.at_level(logging.ERROR, logger="pynetdicom"):
+            result = assoc.send_c_move(
+                self.query, "TESTMOVE", PatientRootQueryRetrieveInformationModelMove
+            )
+            status, identifier = next(result)
+            assert status.Status == 0xC516
+            pytest.raises(StopIteration, next, result)
+
+            assoc.release()
+            scp.shutdown()
+
+        assert (
+            "The C-MOVE request handler yielded more than 65535 matches" in caplog.text
+        )
+
     def test_move_handler_bad_aet(self):
         """Test handler yielding a bad move aet"""