Repository: pydicom/pynetdicom

Issue:
Add ability to pass extra arguments to the event handlers
Currently we have (always) an event handler as:
```python
def handle_event(event):
    """Some handler"""
    pass
```
It would be nice to be able to pass extra arguments to the event handler to simplify things:
```python
def handle_event(event, arg1, arg2, ...):
    """Some handler"""
    print(arg1, arg2)
```

Suggested change is to expand the `evt_handlers` tuple so that if an optional extra value (as a list) is included the list items are the argument objects to be passed:
```python
def handle_accepted(event):
    # no optional arguments passed
    pass

def handle_echo(event, a, b c):
    assert a == 'list'
    assert b == 'of'
    assert c == 'objects'

handlers = [
    (evt.EVT_C_ECHO, handle_echo, ['list', 'of', 'objects']),
    (evt.EVT_ACCEPTED, handle_accepted),
]
ae.start_server((host, port), evt_handlers=handlers)
```



Discussion:

Patch:
diff --git a/.travis.yml b/.travis.yml
index 27a815b2a..1ed44085c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,9 +4,6 @@ language: python
 # Build against pydicom master and current release
 matrix:
     include:
-        - name: "Python 2.7, pydicom master"
-          python: "2.7"
-          env: TEST_SUITE=pydicom_master
         - name: "Python 3.5, pydicom master"
           python: "3.5"
           env: TEST_SUITE=pydicom_master
diff --git a/README.rst b/README.rst
index b5ef9757c..1eb85eea3 100644
--- a/README.rst
+++ b/README.rst
@@ -11,7 +11,7 @@
     :target: https://img.shields.io/pypi/pyversions/pynetdicom.svg
 .. image:: https://zenodo.org/badge/DOI/10.5281/zenodo.3345559.svg
    :target: https://doi.org/10.5281/zenodo.3345559
-.. image:: https://badges.gitter.im/pydicom.png
+.. image:: https://badges.gitter.im/pydicom/Lobby.svg
     :target: https://gitter.im/pydicom/Lobby
 
 
@@ -53,98 +53,83 @@ Sections `7.5 <http://dicom.nema.org/medical/dicom/current/output/html/part07.ht
 `9 <http://dicom.nema.org/medical/dicom/current/output/html/part07.html#chapter_9>`_,
 and `10 <http://dicom.nema.org/medical/dicom/current/output/html/part07.html#chapter_10>`_).
 
+Installation
+------------
+Dependencies
+~~~~~~~~~~~~
+`pydicom <https://github.com/pydicom/pydicom>`_
+
+Installing current release
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. code-block:: sh
+
+        $ pip install pynetdicom
+
+Installing development version
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. code-block:: sh
+
+        $ pip install git+git://github.com/pydicom/pynetdicom.git
 
-Supported Service Classes
-~~~~~~~~~~~~~~~~~~~~~~~~~
-*pynetdicom* supports the following DICOM service classes:
-
-- `Application Event Logging Service Class <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_P>`_
-- `Basic Worklist Management Service Class <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_K>`_
-- `Color Palette Query/Retrieve Service Class <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_X>`_
-- `Defined Procedure Protocol Query/Retrieve Service Class <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_HH>`_
-- `Display System Management Service Class <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_EE>`_
-- `Hanging Protocol Query/Retrieve Service Class <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_U>`_
-- `Implant Template Query/Retrieve Service Class <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_BB>`_
-- `Instance Availability Notification Service Class <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_R>`_
-- `Media Creation Management Service Class <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_S>`_
-- `Modality Performed Procedure Step Management <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_F>`_
-- `Non-Patient Object Storage Service Class <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_GG>`_
-- `Print Management Service Class <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_H>`_
-- `Protocol Approval Query/Retrieve Service Class <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_II>`_
-- `Query/Retrieve Service Class <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_C>`_
-
-  - `Composite Instance Retrieve Without Bulk Data <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_Z>`_
-  - `Instance and Frame Level Retrieve <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_Y>`_
-- `Relevant Patient Information Query Service Class <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_Q>`_
-- `RT Machine Verification Service Class <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_DD>`_
-- `Storage Service Class <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_B>`_
-
-  - `Ophthalmic Refractive Measurements Storage <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_AA>`_
-  - `Softcopy Presentation State Storage <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_N>`_
-  - `Structured Reporting Storage <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_O>`_
-  - `Volumetric Presentation State Storage <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_FF>`_
-- `Storage Commitment Service Class <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_J>`_
-- `Substance Administration Query Service Class <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_V>`_
-- `Unified Procedure Step Service Class <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_CC>`_
-- `Verification Service Class <http://dicom.nema.org/medical/dicom/current/output/html/part04.html#chapter_A>`_
-
-
-Supported DIMSE SCU Services
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Documentation
+-------------
+The *pynetdicom*
+`user guide <https://pydicom.github.io/pynetdicom/stable/#user-guide>`_,
+`code examples <https://pydicom.github.io/pynetdicom/stable/#examples>`_ and
+`API reference <https://pydicom.github.io/pynetdicom/stable/reference/index.html>`_
+documentation is available for the
+`current release <https://pydicom.github.io/pynetdicom/>`_ as well as the
+`development version <https://pydicom.github.io/pynetdicom/dev>`_.
+
+Supported DIMSE Services
+------------------------
+SCU Services
+~~~~~~~~~~~~
 
 When the AE is acting as an SCU and an association has been established with a
 peer SCP, the following DIMSE-C and -N services are available (provided the
 peer supports the Service Class and a corresponding Presentation Context has
 been accepted):
 
-.. _send_c_echo: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association.send_c_echo
-.. _send_c_find: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association.send_c_find
-.. _send_c_get: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association.send_c_get
-.. _send_c_move: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association.send_c_move
-.. _send_c_store: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association.send_c_store
-.. _send_n_action: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association.send_n_action
-.. _send_n_create: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association.send_n_create
-.. _send_n_delete: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association.send_n_delete
-.. _send_n_event_report: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association.send_n_event_report
-.. _send_n_get: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association.send_n_get
-.. _send_n_set: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association.send_n_set
-
-+----------------+----------------------------------------------------------+
-| DIMSE service  | ``Association`` method                                   |
-+================+==========================================================+
-| C-ECHO         | ``send_c_echo()``                                        |
-|                |                                                          |
-+----------------+----------------------------------------------------------+
-| C-FIND         | ``send_c_find(dataset, query_model)``                    |
-|                |                                                          |
-+----------------+----------------------------------------------------------+
-| C-GET          | ``send_c_get(dataset, query_model)``                     |
-|                |                                                          |
-+----------------+----------------------------------------------------------+
-| C-MOVE         | ``send_c_move(dataset, move_aet, query_model)``          |
-|                |                                                          |
-+----------------+----------------------------------------------------------+
-| C-STORE        | ``send_c_store(dataset)``                                |
-|                |                                                          |
-+----------------+----------------------------------------------------------+
-| N-ACTION       | ``send_n_action(dataset, action_type, class_uid,         |
-|                | instance_uid)``                                          |
-+----------------+----------------------------------------------------------+
-| N-CREATE       | ``send_n_create(dataset, class_uid, instance_uid)``      |
-|                |                                                          |
-+----------------+----------------------------------------------------------+
-| N-DELETE       | ``send_n_delete(class_uid, instance_uid)``               |
-|                |                                                          |
-+----------------+----------------------------------------------------------+
-| N-EVENT-REPORT | ``send_n_event_report(dataset, event_type,               |
-|                | class_uid, instance_uid)``                               |
-+----------------+----------------------------------------------------------+
-| N-GET          | ``send_n_get(identifier_list, class_uid, instance_uid)`` |
-|                |                                                          |
-+----------------+----------------------------------------------------------+
-| N-SET          | ``send_n_set(dataset, class_uid, instance_uid)``         |
-|                |                                                          |
-+----------------+----------------------------------------------------------+
+.. _assoc: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association
+.. _echo: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association.send_c_echo
+.. _find: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association.send_c_find
+.. _c_get: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association.send_c_get
+.. _move: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association.send_c_move
+.. _store: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association.send_c_store
+.. _action: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association.send_n_action
+.. _create: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association.send_n_create
+.. _delete: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association.send_n_delete
+.. _er: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association.send_n_event_report
+.. _n_get: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association.send_n_get
+.. _set: https:pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom.association.Association.html#pynetdicom.association.Association.send_n_set
+
++----------------+--------------------------------------------------------------------------------------+
+| DIMSE service  | `Association<assoc>`_ method                                                         |
++================+======================================================================================+
+| C-ECHO         | `Association.send_c_echo()<echo>`_                                                   |
++----------------+--------------------------------------------------------------------------------------+
+| C-FIND         | `Association.send_c_find(dataset, query_model)<find>`_                               |
++----------------+--------------------------------------------------------------------------------------+
+| C-GET          | `Association.send_c_get(dataset, query_model)<c_get>`_                               |
++----------------+--------------------------------------------------------------------------------------+
+| C-MOVE         | `Association.send_c_move(dataset, move_aet, query_model)<move>`_                     |
++----------------+--------------------------------------------------------------------------------------+
+| C-STORE        | `Association.send_c_store(dataset)<store>`_                                          |
++----------------+--------------------------------------------------------------------------------------+
+| N-ACTION       | `Association.send_n_action(dataset, action_type, class_uid, instance_uid)<action>`_  |
++----------------+--------------------------------------------------------------------------------------+
+| N-CREATE       | `Association.send_n_create(dataset, class_uid, instance_uid)<create>`_               |
++----------------+--------------------------------------------------------------------------------------+
+| N-DELETE       | `Association.send_n_delete(class_uid, instance_uid)<delete>`_                        |
++----------------+--------------------------------------------------------------------------------------+
+| N-EVENT-REPORT | `Association.send_n_event_report(dataset, event_type, class_uid, instance_uid)<er>`_ |
++----------------+--------------------------------------------------------------------------------------+
+| N-GET          | `Association.send_n_set(dataset, class_uid, instance_uid)<n_get>`_                   |
++----------------+--------------------------------------------------------------------------------------+
+| N-SET          | `Association.send_n_set(dataset, class_uid, instance_uid)<set>`_                     |
++----------------+--------------------------------------------------------------------------------------+
 
 Where *dataset* is a pydicom
 `Dataset <https://pydicom.github.io/pydicom/stable/ref_guide.html#dataset>`_
@@ -156,49 +141,49 @@ objects, *event_type* and *action_type* are ints and *class_uid* and
 for more information.
 
 
-Supported DIMSE SCP Services
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+SCP Services
+~~~~~~~~~~~~
 
 When the AE is acting as an SCP the following DIMSE-C and -N services are
 available to the peer once an association has been established:
 
-.. _handle_echo: https://pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom._handlers.doc_handle_echo.html
-.. _handle_find: https://pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom._handlers.doc_handle_find.html
-.. _handle_c_get: https://pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom._handlers.doc_handle_c_get.html
-.. _handle_move: https://pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom._handlers.doc_handle_move.html
-.. _handle_store: https://pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom._handlers.doc_handle_store.html
-.. _handle_action: https://pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom._handlers.doc_handle_action.html
-.. _handle_create: https://pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom._handlers.doc_handle_create.html
-.. _handle_delete: https://pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom._handlers.doc_handle_delete.html
-.. _handle_event_report: https://pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom._handlers.doc_handle_event_report.html
-.. _handle_n_get: https://pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom._handlers.doc_handle_n_get.html
-.. _handle_set: https://pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom._handlers.doc_handle_set.html
-
-+----------------+----------------------------+
-| DIMSE service  | Intervention Event         |
-+================+============================+
-| C-ECHO         | ``evt.EVT_C_ECHO``         |
-+----------------+----------------------------+
-| C-FIND         | ``evt.EVT_C_FIND``         |
-+----------------+----------------------------+
-| C-GET          | ``evt.EVT_C_GET``          |
-+----------------+----------------------------+
-| C-MOVE         | ``evt.EVT_C_MOVE``         |
-+----------------+----------------------------+
-| C-STORE        | ``evt.EVT_C_STORE``        |
-+----------------+----------------------------+
-| N-ACTION       | ``evt.EVT_N_ACTION``       |
-+----------------+----------------------------+
-| N-CREATE       | ``evt.EVT_N_CREATE``       |
-+----------------+----------------------------+
-| N-DELETE       | ``evt.EVT_N_DELETE``       |
-+----------------+----------------------------+
-| N-EVENT-REPORT | ``evt.EVT_N_EVENT_REPORT`` |
-+----------------+----------------------------+
-| N-GET          | ``evt.EVT_N_GET``          |
-+----------------+----------------------------+
-| N-SET          | ``evt.EVT_N_SET``          |
-+----------------+----------------------------+
+.. _hecho: https://pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom._handlers.doc_handle_echo.html
+.. _hfind: https://pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom._handlers.doc_handle_find.html
+.. _hc_get: https://pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom._handlers.doc_handle_c_get.html
+.. _hmove: https://pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom._handlers.doc_handle_move.html
+.. _hstore: https://pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom._handlers.doc_handle_store.html
+.. _haction: https://pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom._handlers.doc_handle_action.html
+.. _hcreate: https://pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom._handlers.doc_handle_create.html
+.. _hdelete: https://pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom._handlers.doc_handle_delete.html
+.. _her: https://pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom._handlers.doc_handle_event_report.html
+.. _hn_get: https://pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom._handlers.doc_handle_n_get.html
+.. _hset: https://pydicom.github.io/pynetdicom/stable/reference/generated/pynetdicom._handlers.doc_handle_set.html
+
++----------------+----------------------------+-------------------------------+
+| DIMSE service  | Intervention Event         | Handler documentation         |
++================+============================+===============================+
+| C-ECHO         | ``evt.EVT_C_ECHO``         | `Handle C-ECHO<hecho>`_       |
++----------------+----------------------------+-------------------------------+
+| C-FIND         | ``evt.EVT_C_FIND``         | `Handle C-FIND<hfind>`_       |
++----------------+----------------------------+-------------------------------+
+| C-GET          | ``evt.EVT_C_GET``          | `Handle C-GET<hc_get>`_       |
++----------------+----------------------------+-------------------------------+
+| C-MOVE         | ``evt.EVT_C_MOVE``         | `Handle C-MOVE<hmove>`_       |
++----------------+----------------------------+-------------------------------+
+| C-STORE        | ``evt.EVT_C_STORE``        | `Handle C-STORE<hstore>`_     |
++----------------+----------------------------+-------------------------------+
+| N-ACTION       | ``evt.EVT_N_ACTION``       | `Handle N-ACTION<haction>`_   |
++----------------+----------------------------+-------------------------------+
+| N-CREATE       | ``evt.EVT_N_CREATE``       | `Handle N-CREATE<gcreate>`_   |
++----------------+----------------------------+-------------------------------+
+| N-DELETE       | ``evt.EVT_N_DELETE``       | `Handle N-DELETE<hdelete>`_   |
++----------------+----------------------------+-------------------------------+
+| N-EVENT-REPORT | ``evt.EVT_N_EVENT_REPORT`` | `Handle N-EVENT-REPORT<her>`_ |
++----------------+----------------------------+-------------------------------+
+| N-GET          | ``evt.EVT_N_GET``          | `Handle N-GET<hn_get>`_       |
++----------------+----------------------------+-------------------------------+
+| N-SET          | ``evt.EVT_N_SET``          | `Handle N-SET<hset>`_         |
++----------------+----------------------------+-------------------------------+
 
 
 With the exception of the C-ECHO service, a user-defined callable function,
@@ -218,36 +203,6 @@ for information on what attributes and properties are available in ``Event``
 for each event type and the expected returns/yields for the
 corresponding handlers.
 
-
-Documentation
--------------
-The *pynetdicom*
-`user guide <https://pydicom.github.io/pynetdicom/stable/#user-guide>`_,
-`code examples <https://pydicom.github.io/pynetdicom/stable/#examples>`_ and
-`API reference <https://pydicom.github.io/pynetdicom/stable/reference/index.html>`_
-documentation is available for the
-`current release <https://pydicom.github.io/pynetdicom/>`_ as well as the
-`development version <https://pydicom.github.io/pynetdicom/dev>`_.
-
-
-Installation
-------------
-Dependencies
-~~~~~~~~~~~~
-`pydicom <https://github.com/pydicom/pydicom>`_
-
-Installing current release
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. code-block:: sh
-
-        $ pip install pynetdicom
-
-Installing development version
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.. code-block:: sh
-
-        $ pip install git+git://github.com/pydicom/pynetdicom.git
-
 Examples
 --------
 Send a DICOM C-ECHO to a peer Verification SCP (at TCP/IP address *addr*,
diff --git a/docs/changelog/v1.5.0.rst b/docs/changelog/v1.5.0.rst
index c8831436b..a4366d83c 100644
--- a/docs/changelog/v1.5.0.rst
+++ b/docs/changelog/v1.5.0.rst
@@ -51,6 +51,8 @@ Enhancements
   ``storescu.py``
 * Added non-toy implementations for ``findscu.py``, ``getscu.py`` and
   ``movescu.py`` apps
+* Added ability to pass optional extra arguments to event handlers by using
+  ``(evt.EVT_NAME, handler, ['list', 'of', 'args'])``. (:issue:`447`)
 
 Changes
 .......
@@ -70,6 +72,13 @@ Changes
   <pynetdicom.acse.ACSE.is_aborted>`
 * Support for Python 2 is deprecated and will be removed starting in version
   2.0.
+* Added `args` keyword parameter to
+  :meth:`Association.bind()<Association.bind>` and
+  :meth:`AssociationServer.bind()<pynetdicom.transport.AssociationServer.bind>`
+* :meth:`Association.get_handlers()<Association.get_handlers>` and
+  :meth:`AssociationServer.get_handlers()
+  <pynetdicom.transport.AssociationServer.get_handlers>` now return a 2-tuple
+  or list of 2-tuples.
 
 
 Known Issues
diff --git a/docs/user/association.rst b/docs/user/association.rst
index f4bc8442f..6873f681f 100644
--- a/docs/user/association.rst
+++ b/docs/user/association.rst
@@ -146,9 +146,10 @@ use the *evt_handlers* keyword argument:
 
     import logging
 
-    from pynetdicom import AE, evt
+    from pynetdicom import AE, evt, debug_logger
     from pynetdicom.sop_class import VerificationSOPClass
 
+    debug_logger()
     LOGGER = logging.getLogger('pynetdicom')
 
     def handle_open(event):
@@ -156,7 +157,16 @@ use the *evt_handlers* keyword argument:
         msg = 'Connected with remote at ({})'.format(event.address)
         LOGGER.info(msg)
 
-    handlers = [(evt.EVT_CONN_OPEN, handle_open)]
+    def handle_accepted(event, arg1, arg2):
+        """Demonstrate the use of the optional extra arguments"""
+        LOGGER.info("Extra args: '{}' and '{}'".format(arg1, arg2))
+
+    # If a 2-tuple then only `event` parameter
+    # If a 3-tuple then the third value should be a list of objects to pass the handler
+    handlers = [
+        (evt.EVT_CONN_OPEN, handle_open)
+        (evt.EVT_ACCEPTED, handle_accepted, ['optional', 'parameters'])
+    ]
 
     ae = AE()
     ae.add_requested_context(VerificationSOPClass)
@@ -172,9 +182,10 @@ Handlers can also be bound and unbound from events in an existing
 
     import logging
 
-    from pynetdicom import AE, evt
+    from pynetdicom import AE, evt, debug_logger
     from pynetdicom.sop_class import VerificationSOPClass
 
+    debug_logger()
     LOGGER = logging.getLogger('pynetdicom')
 
     def handle_open(event):
@@ -397,9 +408,10 @@ generated by the SCP you can use the *evt_handlers* keyword argument:
 
     import logging
 
-    from pynetdicom import AE, evt
+    from pynetdicom import AE, evt, debug_logger
     from pynetdicom.sop_class import VerificationSOPClass
 
+    debug_logger()
     LOGGER = logging.getLogger('pynetdicom')
 
     def handle_open(event):
@@ -407,7 +419,16 @@ generated by the SCP you can use the *evt_handlers* keyword argument:
         msg = 'Connected with remote at ({})'.format(event.address)
         LOGGER.info(msg)
 
-    handlers = [(evt.EVT_CONN_OPEN, handle_open)]
+    def handle_accepted(event, arg1, arg2):
+        """Demonstrate the use of the optional extra arguments"""
+        LOGGER.info("Extra args: '{}' and '{}'".format(arg1, arg2))
+
+    # If a 2-tuple then only `event` parameter
+    # If a 3-tuple then the third value should be a list of objects to pass the handler
+    handlers = [
+        (evt.EVT_CONN_OPEN, handle_open)
+        (evt.EVT_ACCEPTED, handle_accepted, ['optional', 'parameters'])
+    ]
 
     ae = AE()
     ae.add_supported_context(VerificationSOPClass)
@@ -422,9 +443,10 @@ non-blocking mode:
 
     import logging
 
-    from pynetdicom import AE, evt
+    from pynetdicom import AE, evt, debug_logger
     from pynetdicom.sop_class import VerificationSOPClass
 
+    debug_logger()
     LOGGER = logging.getLogger('pynetdicom')
 
     def handle_open(event):
diff --git a/docs/user/events.rst b/docs/user/events.rst
index 45ec30fd6..5d85b2953 100644
--- a/docs/user/events.rst
+++ b/docs/user/events.rst
@@ -21,47 +21,29 @@ bound to it and any exceptions raised by the handlers are caught
 and the exception message logged instead. The table below lists the available
 notification events.
 
-+----------------------------+-----------------------------------+
-| Event                      | Description                       |
-+============================+===================================+
-| ``evt.EVT_ABORTED``        | Association aborted               |
-+----------------------------+-----------------------------------+
-| ``evt.EVT_ACCEPTED``       | Association accepted              |
-+----------------------------+-----------------------------------+
-| ``evt.EVT_ACSE_RECV``      | ACSE received a primitive         |
-|                            | from the DUL service provider     |
-+----------------------------+-----------------------------------+
-| ``evt.EVT_ACSE_SENT``      | ACSE sent a primitive             |
-|                            | to the DUL service provider       |
-+----------------------------+-----------------------------------+
-| ``evt.EVT_CONN_CLOSE``     | Connection with remote closed     |
-+----------------------------+-----------------------------------+
-| ``evt.EVT_CONN_OPEN``      | Connection with remote opened     |
-+----------------------------+-----------------------------------+
-| ``evt.EVT_DATA_RECV``      | Data received from the peer AE    |
-+----------------------------+-----------------------------------+
-| ``evt.EVT_DATA_SENT``      | Data sent to the peer AE          |
-+----------------------------+-----------------------------------+
-| ``evt.EVT_DIMSE_RECV``     | DIMSE service received and        |
-|                            | decoded a message                 |
-+----------------------------+-----------------------------------+
-| ``evt.EVT_DIMSE_SENT``     | DIMSE service encoded and         |
-|                            | sent a message                    |
-+----------------------------+-----------------------------------+
-| ``evt.EVT_ESTABLISHED``    | Association established           |
-+----------------------------+-----------------------------------+
-| ``evt.EVT_FSM_TRANSITION`` | State machine transitioning       |
-+----------------------------+-----------------------------------+
-| ``evt.EVT_PDU_RECV``       | PDU received from the peer AE     |
-+----------------------------+-----------------------------------+
-| ``evt.EVT_PDU_SENT``       | PDU sent to the peer AE           |
-+----------------------------+-----------------------------------+
-| ``evt.EVT_REJECTED``       | Association rejected              |
-+----------------------------+-----------------------------------+
-| ``evt.EVT_RELEASED``       | Association released              |
-+----------------------------+-----------------------------------+
-| ``evt.EVT_REQUESTED``      | Association requested             |
-+----------------------------+-----------------------------------+
+.. currentmodule:: pynetdicom._handlers
+
+.. csv-table::
+   :header: Event, Description
+   :widths: 15, 30
+
+   :func:`evt.EVT_ABORTED<doc_handle_assoc>`,Association aborted
+   :func:`evt.EVT_ACCEPTED<doc_handle_assoc>`,Association accepted
+   :func:`evt.EVT_ACSE_RECV<doc_handle_acse>`,ACSE received a primitive from the DUL service provider
+   :func:`evt.EVT_ACSE_SENT<doc_handle_acse>`,ACSE sent a primitive to the DUL service provider
+   :func:`evt.EVT_CONN_CLOSE<doc_handle_transport>`,Connection with remote closed
+   :func:`evt.EVT_CONN_OPEN<doc_handle_transport>`, Connection with remote opened
+   :func:`evt.EVT_DATA_RECV<doc_handle_data>`,Data received from the peer AE
+   :func:`evt.EVT_DATA_SENT<doc_handle_data>`,Data sent to the peer AE
+   :func:`evt.EVT_DIMSE_RECV<doc_handle_dimse>`,DIMSE service received and decoded a message
+   :func:`evt.EVT_DIMSE_SENT<doc_handle_dimse>`,DIMSE service encoded and sent a message
+   :func:`evt.EVT_ESTABLISHED<doc_handle_assoc>`,Association established
+   :func:`evt.EVT_FSM_TRANSITION<doc_handle_fsm>`,State machine transitioning
+   :func:`evt.EVT_PDU_RECV<doc_handle_pdu>`,PDU received from the peer AE
+   :func:`evt.EVT_PDU_SENT<doc_handle_pdu>`,PDU sent to the peer AE
+   :func:`evt.EVT_REJECTED<doc_handle_assoc>`,Association rejected
+   :func:`evt.EVT_RELEASED<doc_handle_assoc>`,Association released
+   :func:`evt.EVT_REQUESTED<doc_handle_assoc>`,Association requested
 
 By default a number of notification handlers are bound for logging purposes.
 If you wish to remove these then you can do the following before creating any
@@ -92,70 +74,46 @@ table below lists the possible intervention events.
 
 .. currentmodule:: pynetdicom._handlers
 
-+----------------------------+--------------------------------+----------------------------------------------------------+
-| Event                      | Description                    |                                                          |
-+============================+================================+==========================================================+
-| Association request includes extended negotiation items                                                                |
-+----------------------------+--------------------------------+----------------------------------------------------------+
-| ``evt.EVT_ASYNC_OPS``      | Association request includes   | :func:`Handler documentation<doc_handle_async>`          |
-|                            | Asynchronous Operations Window |                                                          |
-|                            | negotiation item               |                                                          |
-+----------------------------+--------------------------------+----------------------------------------------------------+
-| ``evt.EVT_SOP_COMMON``     | Association request includes   | :func:`Handler documentation<doc_handle_sop_common>`     |
-|                            | SOP Class Common Extended      |                                                          |
-|                            | negotiation item(s)            |                                                          |
-+----------------------------+--------------------------------+----------------------------------------------------------+
-| ``evt.EVT_SOP_EXTENDED``   | Association request includes   | :func:`Handler documentation<doc_handle_sop_extended>`   |
-|                            | SOP Class Extended negotiation |                                                          |
-|                            | item(s)                        |                                                          |
-+----------------------------+--------------------------------+----------------------------------------------------------+
-| ``evt.EVT_USER_ID``        | Association request includes   | :func:`Handler documentation<doc_handle_userid>`         |
-|                            | User Identity negotiation item |                                                          |
-+----------------------------+--------------------------------+----------------------------------------------------------+
-| Service class received a DIMSE service request                                                                         |
-+----------------------------+--------------------------------+----------------------------------------------------------+
-| ``evt.EVT_C_ECHO``         | Service class received         | :func:`Handler documentation<doc_handle_echo>`           |
-|                            | C-ECHO request                 |                                                          |
-+----------------------------+--------------------------------+----------------------------------------------------------+
-| ``evt.EVT_C_FIND``         | Service class received         | :func:`Handler documentation<doc_handle_find>`           |
-|                            | C-FIND request                 |                                                          |
-+----------------------------+--------------------------------+----------------------------------------------------------+
-| ``evt.EVT_C_GET``          | Service class received         | :func:`Handler documentation<doc_handle_c_get>`          |
-|                            | C-GET request                  |                                                          |
-+----------------------------+--------------------------------+----------------------------------------------------------+
-| ``evt.EVT_C_MOVE``         | Service class received         | :func:`Handler documentation<doc_handle_move>`           |
-|                            | C-MOVE request                 |                                                          |
-+----------------------------+--------------------------------+----------------------------------------------------------+
-| ``evt.EVT_C_STORE``        | Service class received         | :func:`Handler documentation<doc_handle_store>`          |
-|                            | C-STORE request                |                                                          |
-+----------------------------+--------------------------------+----------------------------------------------------------+
-| ``evt.EVT_N_ACTION``       | Service class received         | :func:`Handler documentation<doc_handle_action>`         |
-|                            | N-ACTION request               |                                                          |
-+----------------------------+--------------------------------+----------------------------------------------------------+
-| ``evt.EVT_N_CREATE``       | Service class received         | :func:`Handler documentation<doc_handle_create>`         |
-|                            | N-CREATE request               |                                                          |
-+----------------------------+--------------------------------+----------------------------------------------------------+
-| ``evt.EVT_N_DELETE``       | Service class received         | :func:`Handler documentation<doc_handle_delete>`         |
-|                            | N-DELETE request               |                                                          |
-+----------------------------+--------------------------------+----------------------------------------------------------+
-| ``evt.EVT_N_EVENT_REPORT`` | Service class received         | :func:`Handler documentation<doc_handle_event_report>`   |
-|                            | N-EVENT-REPORT request         |                                                          |
-+----------------------------+--------------------------------+----------------------------------------------------------+
-| ``evt.EVT_N_GET``          | Service class received         | :func:`Handler documentation<doc_handle_n_get>`          |
-|                            | N-GET request                  |                                                          |
-+----------------------------+--------------------------------+----------------------------------------------------------+
-| ``evt.EVT_N_SET``          | Service class received         | :func:`Handler documentation<doc_handle_set>`            |
-|                            | N-SET request                  |                                                          |
-+----------------------------+--------------------------------+----------------------------------------------------------+
+Associtation related
+~~~~~~~~~~~~~~~~~~~~
+
+.. csv-table::
+   :header: Event, Description
+   :widths: 10, 30
+
+   :func:`evt.EVT_ASYNC_OPS<doc_handle_async>`,Association request includes asynchronous operations negotiation item
+   :func:`evt.EVT_SOP_COMMON<doc_handle_sop_common>`,Association request includes SOP Class Common Extended negotiation item(s)
+   :func:`evt.EVT_SOP_EXTENDED<doc_handle_sop_extended>`,Association request includes SOP Class Extended negotiation item(s)
+   :func:`evt.EVT_USER_ID<doc_handle_userid>`,Association request includes User Identity negotiation item
+
+
+Service Class related
+~~~~~~~~~~~~~~~~~~~~~
+
+.. csv-table::
+   :header: Event, Description
+   :widths: 15, 30
+
+   :func:`evt.EVT_C_ECHO<doc_handle_echo>`,Received C-ECHO request
+   :func:`evt.EVT_C_FIND<doc_handle_find>`,Received C-FIND request
+   :func:`evt.EVT_C_GET<doc_handle_c_get>`,Received C-GET request
+   :func:`evt.EVT_C_MOVE<doc_handle_move>`,Received C-MOVE request
+   :func:`evt.EVT_C_STORE<doc_handle_store>`,Received C-STORE request
+   :func:`evt.EVT_N_ACTION<doc_handle_action>`,Received N-ACTION request
+   :func:`evt.EVT_N_CREATE<doc_handle_create>`,Received N-CREATE request
+   :func:`evt.EVT_N_DELETE<doc_handle_delete>`,Received N-DELETE request
+   :func:`evt.EVT_N_EVENT_REPORT<doc_handle_event_report>`,Received N-EVENT-REPORT request
+   :func:`evt.EVT_N_GET<doc_handle_n_get>`,Received N-GET request
+   :func:`evt.EVT_N_SET<doc_handle_set>`,Received N-SET request
 
 .. currentmodule:: pynetdicom.events
 
 Event Handlers
 ..............
 
-Event handlers are callable functions bound to an event that get passed a
-single parameter, *event*, which is an :class:`Event` instance. All
-:class:`Event` instances come with at least three attributes:
+Event handlers are callable functions bound to an event that, at a minimum,
+gets passed a single parameter, *event*, which is an :class:`Event` instance.
+All :class:`Event` instances come with at least three attributes:
 
 * :attr:`Event.assoc` - the
   :class:`Association <pynetdicom.association.Association>` in which the
@@ -169,13 +127,47 @@ Additional attributes and properties are available depending on the event type,
 see the `handler implementation documentation
 <../reference/events.html>`_ for more information.
 
-Handlers can be bound to events through the ``bind(event, handler)`` methods
-in the :class:`~pynetdicom.association.Association` and
-:class:`~pynetdicom.transport.AssociationServer` classes or by using the
-*evt_handlers* keyword argument with
-:meth:`AE.associate()<pynetdicom.ae.ApplicationEntity.associate>` and
+Handlers can be bound to events through the *evt_handlers* keyword argument
+with :meth:`AE.associate()<pynetdicom.ae.ApplicationEntity.associate>` and
 :meth:`AE.start_server()<pynetdicom.ae.ApplicationEntity.start_server>`.
-Handlers can be unbound with the ``unbind(event, handler)`` methods in the
-:class:`~pynetdicom.association.Association` and
-:class:`~pynetdicom.transport.AssociationServer` classes. See the
-:ref:`Association<association>` guide for more details.
+*evt_handlers* should be a list of 2- or 3-tuples::
+
+    from pynetdicom import evt, AE
+    from pynetdicom.sop_class import VerificationSOPClass, CTImageStorage
+
+    def handle_echo(event):
+        # Because we used a 2-tuple to bind `handle_echo` we
+        #   have no extra parameters
+        return 0x0000
+
+    def handle_store(event, arg1, arg2):
+        # Because we used a 3-tuple to bind `handle_store` we
+        #   have optional extra parameters
+        assert arg1 == 'optional'
+        assert arg2 == 'parameters'
+        return 0x0000
+
+    handlers = [
+        (evt.EVT_C_ECHO, handle_echo),
+        (evt.EVT_C_STORE, handle_store, ['optional', 'parameters']),
+    ]
+
+    ae = AE()
+    ae.add_supported_context(VerificationSOPClass)
+    ae.add_supported_context(CTImageStorage)
+    ae.start_server(('localhost', 11112), evt_handlers=handlers)
+
+If using a 3-tuple then the third value should be a list of objects that will
+be passed to the handler as extra parameters.
+
+The other way to bind handlers to events is through the
+:class:`Association.bind(event, handler, args=None)
+<pynetdicom.association.Association.bind>` and
+:class:`<AssociationServer.bind(event, handler, args=None)
+<pynetdicom.transport.AssociationServer.bind>` methods, where the `args`
+keyword parameter is a list of objects to pass the handler as extra parameters.
+
+Handlers can be unbound with
+:class:`Association.unbind()<pynetdicom.association.Association.unbind>` and
+:class:`AssociationServer.unbind()<pynetdicom.transport.AssociationServer>`
+methods. See the :ref:`Association<association>` guide for more details.
diff --git a/pynetdicom/_handlers.py b/pynetdicom/_handlers.py
index 54c5fc85a..8be06fb38 100644
--- a/pynetdicom/_handlers.py
+++ b/pynetdicom/_handlers.py
@@ -2017,7 +2017,7 @@ def _recv_n_delete_rsp(event):
 
 # Example handlers used for the documentation
 # Intervention event handler documentation
-def doc_handle_echo(event):
+def doc_handle_echo(event, *args):
     """Documentation for handlers bound to ``evt.EVT_C_ECHO``.
 
     User implementation of this event handler is optional. If a handler is
@@ -2067,6 +2067,12 @@ def doc_handle_echo(event):
 
         * :attr:`~pynetdicom.events.Event.message_id`: the C-ECHO request's
           *Message ID* as :class:`int`.
+    args
+        If the handler was bound to the event using
+        ``bind(event, handler, args)`` or by passing
+        ``evt_handlers=[(event, handler, args), ...]``, where `args` is a
+        :class:`list` then there will be one or more optional extra parameters
+        matching the contents of `args`.
 
     Returns
     -------
@@ -2097,7 +2103,7 @@ def doc_handle_echo(event):
     """
     pass
 
-def doc_handle_find(event):
+def doc_handle_find(event, *args):
     """Documentation for handlers bound to ``evt.EVT_C_FIND``.
 
     User implementation of this event handler is required if one or more
@@ -2183,6 +2189,12 @@ def doc_handle_find(event):
           and ``return``.
         * :attr:`~pynetdicom.events.Event.message_id`: the C-FIND request's
           *Message ID* as :class:`int`.
+    args
+        If the handler was bound to the event using
+        ``bind(event, handler, args)`` or by passing
+        ``evt_handlers=[(event, handler, args), ...]``, where `args` is a
+        :class:`list` then there will be one or more optional extra parameters
+        matching the contents of `args`.
 
     Yields
     ------
@@ -2244,7 +2256,7 @@ def doc_handle_find(event):
     """
     pass
 
-def doc_handle_c_get(event):
+def doc_handle_c_get(event, *args):
     """Documentation for handlers bound to ``evt.EVT_C_GET``.
 
     User implementation of this event handler is required if one or more
@@ -2334,6 +2346,12 @@ def doc_handle_c_get(event):
           and ``return``.
         * :attr:`~pynetdicom.events.Event.message_id`: the C-GET request's
           *Message ID* as :class:`int`.
+    args
+        If the handler was bound to the event using
+        ``bind(event, handler, args)`` or by passing
+        ``evt_handlers=[(event, handler, args), ...]``, where `args` is a
+        :class:`list` then there will be one or more optional extra parameters
+        matching the contents of `args`.
 
     Yields
     ------
@@ -2397,7 +2415,7 @@ def doc_handle_c_get(event):
     """
     pass
 
-def doc_handle_move(event):
+def doc_handle_move(event, *args):
     """Documentation for handlers bound to ``evt.EVT_C_MOVE``.
 
     User implementation of this event handler is required if one or more
@@ -2495,7 +2513,12 @@ def doc_handle_move(event):
           *Message ID* as :class:`int`.
         * :attr:`~pynetdicom.events.Event.move_destination`: the C-MOVE
           request's *Move Destination* value as :class:`bytes`.
-
+    args
+        If the handler was bound to the event using
+        ``bind(event, handler, args)`` or by passing
+        ``evt_handlers=[(event, handler, args), ...]``, where `args` is a
+        :class:`list` then there will be one or more optional extra parameters
+        matching the contents of `args`.
 
     Yields
     ------
@@ -2563,7 +2586,7 @@ def doc_handle_move(event):
     """
     pass
 
-def doc_handle_store(event):
+def doc_handle_store(event, *args):
     """Documentation for handlers bound to ``evt.EVT_C_STORE``.
 
     User implementation of this event handler is required if one or more
@@ -2641,6 +2664,12 @@ def doc_handle_store(event):
           event.file_meta``.
         * :attr:`~pynetdicom.events.Event.message_id`: the C-STORE request's
           *Message ID* as :class:`int`.
+    args
+        If the handler was bound to the event using
+        ``bind(event, handler, args)`` or by passing
+        ``evt_handlers=[(event, handler, args), ...]``, where `args` is a
+        :class:`list` then there will be one or more optional extra parameters
+        matching the contents of `args`.
 
     Returns
     -------
@@ -2681,7 +2710,7 @@ def doc_handle_store(event):
     """
     pass
 
-def doc_handle_action(event):
+def doc_handle_action(event, *args):
     """Documentation for handlers bound to ``evt.EVT_N_ACTION``.
 
     User implementation of this event handler is required if one or more
@@ -2812,6 +2841,12 @@ def doc_handle_action(event):
           *Action Type ID* as :class:`int`.
         * :attr:`~pynetdicom.events.Event.message_id`: the N-ACTION request's
           *Message ID* as :class:`int`.
+    args
+        If the handler was bound to the event using
+        ``bind(event, handler, args)`` or by passing
+        ``evt_handlers=[(event, handler, args), ...]``, where `args` is a
+        :class:`list` then there will be one or more optional extra parameters
+        matching the contents of `args`.
 
     Returns
     -------
@@ -2867,7 +2902,7 @@ def doc_handle_action(event):
     """
     pass
 
-def doc_handle_create(event):
+def doc_handle_create(event, *args):
     """Documentation for handlers bound to ``evt.EVT_N_CREATE``.
 
     User implementation of this event handler is required if one or more
@@ -2964,6 +2999,12 @@ def doc_handle_create(event):
           exception at the time of use.
         * :attr:`~pynetdicom.events.Event.message_id`: the N-CREATE request's
           *Message ID* as :class:`int`.
+    args
+        If the handler was bound to the event using
+        ``bind(event, handler, args)`` or by passing
+        ``evt_handlers=[(event, handler, args), ...]``, where `args` is a
+        :class:`list` then there will be one or more optional extra parameters
+        matching the contents of `args`.
 
     Returns
     -------
@@ -3019,7 +3060,7 @@ def doc_handle_create(event):
     """
     pass
 
-def doc_handle_delete(event):
+def doc_handle_delete(event, *args):
     """Documentation for handlers bound to ``evt.EVT_N_DELETE``.
 
     User implementation of this event handler is required if one or more
@@ -3078,7 +3119,12 @@ def doc_handle_delete(event):
 
         * :attr:`~pynetdicom.events.Event.message_id`: the N-DELETE request's
           *Message ID* as :class:`int`.
-
+    args
+        If the handler was bound to the event using
+        ``bind(event, handler, args)`` or by passing
+        ``evt_handlers=[(event, handler, args), ...]``, where `args` is a
+        :class:`list` then there will be one or more optional extra parameters
+        matching the contents of `args`.
 
     Returns
     -------
@@ -3119,7 +3165,7 @@ def doc_handle_delete(event):
     """
     pass
 
-def doc_handle_event_report(event):
+def doc_handle_event_report(event, *args):
     """Documentation for handlers bound to ``evt.EVT_N_EVENT_REPORT``.
 
     User implementation of this event handler is required if one or more
@@ -3194,6 +3240,12 @@ def doc_handle_event_report(event):
           request's *Event Type ID* parameter value as :class:`int`.
         * :attr:`~pynetdicom.events.Event.message_id`: the N-EVENT-REPORT
           request's *Message ID* as :class:`int`.
+    args
+        If the handler was bound to the event using
+        ``bind(event, handler, args)`` or by passing
+        ``evt_handlers=[(event, handler, args), ...]``, where `args` is a
+        :class:`list` then there will be one or more optional extra parameters
+        matching the contents of `args`.
 
     Returns
     -------
@@ -3247,7 +3299,7 @@ def doc_handle_event_report(event):
     """
     pass
 
-def doc_handle_n_get(event):
+def doc_handle_n_get(event, *args):
     """Documentation for handlers bound to ``evt.EVT_N_GET``.
 
     User implementation of this event handler is required if one or more
@@ -3321,6 +3373,12 @@ def doc_handle_n_get(event):
           N-GET request's *Attribute Identifier List* parameter.
         * :attr:`~pynetdicom.events.Event.message_id`: the N-GET request's
           *Message ID* as :class:`int`.
+    args
+        If the handler was bound to the event using
+        ``bind(event, handler, args)`` or by passing
+        ``evt_handlers=[(event, handler, args), ...]``, where `args` is a
+        :class:`list` then there will be one or more optional extra parameters
+        matching the contents of `args`.
 
     Returns
     -------
@@ -3370,7 +3428,7 @@ def doc_handle_n_get(event):
     """
     pass
 
-def doc_handle_set(event):
+def doc_handle_set(event, *args):
     """Documentation for handlers bound to ``evt.EVT_N_SET``.
 
     User implementation of this event handler is required if one or more
@@ -3475,6 +3533,12 @@ def doc_handle_set(event):
           uses a deferred read when decoding data, if the decode fails the
           returned :class:`~pydicom.dataset.Dataset` will only raise an
           exception at the time of use.
+    args
+        If the handler was bound to the event using
+        ``bind(event, handler, args)`` or by passing
+        ``evt_handlers=[(event, handler, args), ...]``, where `args` is a
+        :class:`list` then there will be one or more optional extra parameters
+        matching the contents of `args`.
 
     Returns
     -------
@@ -3526,7 +3590,7 @@ def doc_handle_set(event):
     """
     pass
 
-def doc_handle_async(event):
+def doc_handle_async(event, *args):
     """Documentation for handlers bound to ``evt.EVT_ASYNC_OPS``.
 
     User implementation of this event handler is optional. If a handler is
@@ -3567,6 +3631,12 @@ def doc_handle_async(event):
         * :attr:`~pynetdicom.events.Event.timestamp`: the date and time
           that the negotiation request was processed as
           :class:`datetime.datetime`.
+    args
+        If the handler was bound to the event using
+        ``bind(event, handler, args)`` or by passing
+        ``evt_handlers=[(event, handler, args), ...]``, where `args` is a
+        :class:`list` then there will be one or more optional extra parameters
+        matching the contents of `args`.
 
     Returns
     -------
@@ -3577,7 +3647,6 @@ def doc_handle_async(event):
         supported the returned values will be ignored and (1, 1) sent in
         response.
 
-
     References
     ----------
 
@@ -3585,7 +3654,7 @@ def doc_handle_async(event):
     """
     pass
 
-def doc_handle_sop_common(event):
+def doc_handle_sop_common(event, *args):
     """Documentation for handlers bound to ``evt.EVT_SOP_COMMON``.
 
     User implementation of this event handler is required only if
@@ -3615,6 +3684,12 @@ def doc_handle_sop_common(event):
         * :attr:`~pynetdicom.events.Event.timestamp`: the date and time
           that the negotiation request was processed as
           :class:`datetime.datetime`.
+    args
+        If the handler was bound to the event using
+        ``bind(event, handler, args)`` or by passing
+        ``evt_handlers=[(event, handler, args), ...]``, where `args` is a
+        :class:`list` then there will be one or more optional extra parameters
+        matching the contents of `args`.
 
     Returns
     -------
@@ -3633,7 +3708,7 @@ def doc_handle_sop_common(event):
     """
     pass
 
-def doc_handle_sop_extended(event):
+def doc_handle_sop_extended(event, *args):
     """Documentation for handlers bound to ``evt.EVT_SOP_EXTENDED``.
 
     User implementation of this event handler is required only if
@@ -3666,6 +3741,12 @@ def doc_handle_sop_extended(event):
         * :attr:`~pynetdicom.events.Event.timestamp`: the date and time
           that the negotiation request was processed as
           :class:`datetime.datetime`.
+    args
+        If the handler was bound to the event using
+        ``bind(event, handler, args)`` or by passing
+        ``evt_handlers=[(event, handler, args), ...]``, where `args` is a
+        :class:`list` then there will be one or more optional extra parameters
+        matching the contents of `args`.
 
     Returns
     -------
@@ -3683,7 +3764,7 @@ def doc_handle_sop_extended(event):
     """
     pass
 
-def doc_handle_userid(event):
+def doc_handle_userid(event, *args):
     """Documentation for handlers bound to ``evt.EVT_USER_ID``.
 
     User implementation of this handler is required if
@@ -3729,6 +3810,12 @@ def doc_handle_userid(event):
           * ``3`` - Kerberos Service ticket
           * ``4`` - SAML Assertion
           * ``5`` - JSON Web Token
+    args
+        If the handler was bound to the event using
+        ``bind(event, handler, args)`` or by passing
+        ``evt_handlers=[(event, handler, args), ...]``, where `args` is a
+        :class:`list` then there will be one or more optional extra parameters
+        matching the contents of `args`.
 
     Returns
     -------
@@ -3751,7 +3838,7 @@ def doc_handle_userid(event):
     pass
 
 # Notification event handler documentation
-def doc_handle_acse(event):
+def doc_handle_acse(event, *args):
     """Documentation for handlers bound to ``evt.EVT_ACSE_RECV`` or
     ``evt.EVT_ACSE_SENT``.
 
@@ -3776,10 +3863,16 @@ def doc_handle_acse(event):
         * :attr:`~pynetdicom.events.Event.timestamp`: the date and time
           that the negotiation item was processed as
           :class:`datetime.datetime`.
+    args
+        If the handler was bound to the event using
+        ``bind(event, handler, args)`` or by passing
+        ``evt_handlers=[(event, handler, args), ...]``, where `args` is a
+        :class:`list` then there will be one or more optional extra parameters
+        matching the contents of `args`.
     """
     pass
 
-def doc_handle_assoc(event):
+def doc_handle_assoc(event, *args):
     """Documentation for handlers bound to ``evt.EVT_ACCEPTED``,
     ``evt.EVT_ESTABLISHED``, ``evt.EVT_REJECTED``, ``evt.EVT_REQUESTED``,
     ``evt.EVT_RELEASED`` or ``evt.EVT_ABORTED``.
@@ -3797,10 +3890,16 @@ def doc_handle_assoc(event):
           :class:`~pynetdicom.events.NotificationEvent`.
         * :attr:`~pynetdicom.events.Event.timestamp`: the date and time
           that the association status changed as :class:`datetime.datetime`.
+    args
+        If the handler was bound to the event using
+        ``bind(event, handler, args)`` or by passing
+        ``evt_handlers=[(event, handler, args), ...]``, where `args` is a
+        :class:`list` then there will be one or more optional extra parameters
+        matching the contents of `args`.
     """
     pass
 
-def doc_handle_dimse(event):
+def doc_handle_dimse(event, *args):
     """Documentation for handlers bound to ``evt.EVT_DIMSE_RECV`` or
     ``evt.EVT_DIMSE_SENT``.
 
@@ -3843,10 +3942,16 @@ def doc_handle_dimse(event):
           :class:`~pynetdicom.dimse_messages.N_SET_RSP`
         * :attr:`~pynetdicom.events.Event.timestamp`: the date and time
           that the message was processed as :class:`datetime.datetime`.
+    args
+        If the handler was bound to the event using
+        ``bind(event, handler, args)`` or by passing
+        ``evt_handlers=[(event, handler, args), ...]``, where `args` is a
+        :class:`list` then there will be one or more optional extra parameters
+        matching the contents of `args`.
     """
     pass
 
-def doc_handle_data(event):
+def doc_handle_data(event, *args):
     """Documentation for handlers bound to ``evt.EVT_DATA_RECV`` or
     ``evt.EVT_DATA_SENT``.
 
@@ -3865,10 +3970,16 @@ def doc_handle_data(event):
           :class:`~pynetdicom.events.NotificationEvent`.
         * :attr:`~pynetdicom.events.Event.timestamp`: the date and time
           that the data was sent/received as :class:`datetime.datetime`.
+    args
+        If the handler was bound to the event using
+        ``bind(event, handler, args)`` or by passing
+        ``evt_handlers=[(event, handler, args), ...]``, where `args` is a
+        :class:`list` then there will be one or more optional extra parameters
+        matching the contents of `args`.
     """
     pass
 
-def doc_handle_fsm(event):
+def doc_handle_fsm(event, *args):
     """Documentation for handlers bound to ``evt.EVT_FSM_TRANSITION``.
 
     Parameters
@@ -3893,10 +4004,16 @@ def doc_handle_fsm(event):
           action has been performed as :class:`str`.
         * :attr:`~pynetdicom.events.Event.timestamp`: the date and time
           that the FSM transition occurred as :class:`datetime.datetime`.
+    args
+        If the handler was bound to the event using
+        ``bind(event, handler, args)`` or by passing
+        ``evt_handlers=[(event, handler, args), ...]``, where `args` is a
+        :class:`list` then there will be one or more optional extra parameters
+        matching the contents of `args`.
     """
     pass
 
-def doc_handle_pdu(event):
+def doc_handle_pdu(event, *args):
     """Documentation for handlers bound to ``evt.EVT_PDU_RECV`` or
     ``evt.EVT_PDU_SENT``.
 
@@ -3921,10 +4038,16 @@ def doc_handle_pdu(event):
           :class:`P_DATA_TF<pynetdicom.pdu.P_DATA_TF>`.
         * :attr:`~pynetdicom.events.Event.timestamp`: the date and time
           that the PDU was processed as :class:`datetime.datetime`.
+    args
+        If the handler was bound to the event using
+        ``bind(event, handler, args)`` or by passing
+        ``evt_handlers=[(event, handler, args), ...]``, where `args` is a
+        :class:`list` then there will be one or more optional extra parameters
+        matching the contents of `args`.
     """
     pass
 
-def doc_handle_transport(event):
+def doc_handle_transport(event, *args):
     """Documentation for handlers bound to ``evt.EVT_CONN_OPEN`` or
     ``evt.EVT_CONN_CLOSE``.
 
@@ -3944,5 +4067,11 @@ def doc_handle_transport(event):
         * :attr:`~pynetdicom.events.Event.timestamp`: the date and time
           that the connection was opened/closed as
           :class:`datetime.datetime`.
+    args
+        If the handler was bound to the event using
+        ``bind(event, handler, args)`` or by passing
+        ``evt_handlers=[(event, handler, args), ...]``, where `args` is a
+        :class:`list` then there will be one or more optional extra parameters
+        matching the contents of `args`.
     """
     pass
diff --git a/pynetdicom/ae.py b/pynetdicom/ae.py
index 2c8a41fe6..5068cdb99 100644
--- a/pynetdicom/ae.py
+++ b/pynetdicom/ae.py
@@ -450,6 +450,10 @@ class ApplicationEntity(object):
 
             Added `evt_handlers` keyword parameter
 
+        .. versionchanged:: 1.5
+
+            `evt_handlers` now takes a list of 2- or 3-tuples
+
         Parameters
         ----------
         addr : str
@@ -479,14 +483,15 @@ class ApplicationEntity(object):
             and `server_hostname` is the value to use for the corresponding
             keyword argument in :meth:`~ssl.SSLContext.wrap_socket`. If no
             `tls_args` is supplied then TLS will not be used (default).
-        evt_handlers : list of 2-tuple, optional
-            A list of (`event`, `handler`), where `event` is an ``evt.EVT_*``
-            event tuple and `handler` is a callable function that will be
-            bound to the event. The handler should take a single
-            :class:`Event<pynetdicom.events.Event>` parameter and may return
-            or yield objects depending on the exact event that the handler is
-            bound to. For more information see the
-            :ref:`documentation<user_events>`.
+        evt_handlers : list of 2- or 3-tuple, optional
+            A list of (*event*, *handler*) or (*event*, *handler*, *args*),
+            where `event` is an ``evt.EVT_*`` event tuple, `handler` is a
+            callable function that will be bound to the event and `args` is a
+            :class:`list` of objects that will be passed to `handler` as
+            optional extra arguments. At a minimum, `handler` should take an
+            :class:`~pynetdicom.events.Event` parameter and may return or yield
+            objects depending on the exact event that the handler is bound to.
+            For more information see the :ref:`documentation<user_events>`.
 
         Returns
         -------
@@ -561,8 +566,8 @@ class ApplicationEntity(object):
 
         # Bind events to the handlers
         evt_handlers = evt_handlers or {}
-        for (event, handler) in evt_handlers:
-            assoc.bind(event, handler)
+        for evt_hh_args in evt_handlers:
+            assoc.bind(*evt_hh_args)
 
         # Send an A-ASSOCIATE request to the peer and start negotiation
         assoc.request()
@@ -1084,6 +1089,10 @@ class ApplicationEntity(object):
 
             Added `ae_title` and `contexts` keyword parameters
 
+        .. versionchanged:: 1.5
+
+            `evt_handlers` now takes a list of 2- or 3-tuples
+
         Parameters
         ----------
         address : 2-tuple
@@ -1096,10 +1105,12 @@ class ApplicationEntity(object):
             If TLS is required then this should the :class:`ssl.SSLContext`
             instance to use to wrap the client sockets, otherwise if ``None``
             then no TLS will be used (default).
-        evt_handlers : list of 2-tuple, optional
-            A list of (*event*, *handler*), where `event` is an ``evt.EVT_*``
-            event tuple and `handler` is a callable function that will be bound
-            to the event. The handler should take a single
+        evt_handlers : list of 2- or 3-tuple, optional
+            A list of (*event*, *handler*) or (*event*, *handler*, *args*),
+            where `event` is an ``evt.EVT_*`` event tuple, `handler` is a
+            callable function that will be bound to the event and `args` is a
+            :class:`list` of objects that will be passed to `handler` as
+            optional extra arguments. At a minimum, `handler` should take an
             :class:`~pynetdicom.events.Event` parameter and may return or yield
             objects depending on the exact event that the handler is bound to.
             For more information see the :ref:`documentation<user_events>`.
diff --git a/pynetdicom/apps/common.py b/pynetdicom/apps/common.py
index e9398cf98..5c8308512 100644
--- a/pynetdicom/apps/common.py
+++ b/pynetdicom/apps/common.py
@@ -531,11 +531,13 @@ def setup_logging(args, app_name):
     return app_logger
 
 
-def wrap_handle_store(args, app_logger):
-    """Wrap the EVT_C_STORE handler so it can access local variables.
+def handle_store(event, args, app_logger):
+    """Handle a C-STORE request.
 
     Parameters
     ----------
+    event : pynetdicom.event.event
+        The event corresponding to a C-STORE request.
     args : argparse.Namespace
         The namespace containing the arguments to use. The namespace should
         contain ``args.ignore`` and ``args.output_directory`` attributes.
@@ -544,104 +546,89 @@ def wrap_handle_store(args, app_logger):
 
     Returns
     -------
-    callable
-        The EVT_C_STORE handler.
+    status : pynetdicom.sop_class.Status or int
+        A valid return status code, see PS3.4 Annex B.2.3 or the
+        ``StorageServiceClass`` implementation for the available statuses
     """
-    def handle_store(event):
-        """Handle a C-STORE request.
+    if args.ignore:
+        return 0x0000
+
+    try:
+        ds = event.dataset
+        # Remove any Group 0x0002 elements that may have been included
+        ds = ds[0x00030000:]
+    except Exception as exc:
+        app_logger.error("Unable to decode the dataset")
+        app_logger.exception(exc)
+        # Unable to decode dataset
+        return 0x210
+
+    # Add the file meta information elements
+    ds.file_meta = event.file_meta
+
+    # Because pydicom uses deferred reads for its decoding, decoding errors
+    #   are hidden until encountered by accessing a faulty element
+    try:
+        sop_class = ds.SOPClassUID
+        sop_instance = ds.SOPInstanceUID
+    except Exception as exc:
+        app_logger.error(
+            "Unable to decode the received dataset or missing 'SOP Class "
+            "UID' and/or 'SOP Instance UID' elements"
+        )
+        app_logger.exception(exc)
+        # Unable to decode dataset
+        return 0xC210
 
-        Parameters
-        ----------
-        event : pynetdicom.event.event
-            The event corresponding to a C-STORE request.
+    try:
+        # Get the elements we need
+        mode_prefix = SOP_CLASS_PREFIXES[sop_class][0]
+    except KeyError:
+        mode_prefix = 'UN'
 
-        Returns
-        -------
-        status : pynetdicom.sop_class.Status or int
-            A valid return status code, see PS3.4 Annex B.2.3 or the
-            ``StorageServiceClass`` implementation for the available statuses
-        """
-        if args.ignore:
-            return 0x0000
+    filename = '{0!s}.{1!s}'.format(mode_prefix, sop_instance)
+    app_logger.info('Storing DICOM file: {0!s}'.format(filename))
 
-        try:
-            ds = event.dataset
-            # Remove any Group 0x0002 elements that may have been included
-            ds = ds[0x00030000:]
-        except Exception as exc:
-            app_logger.error("Unable to decode the dataset")
-            app_logger.exception(exc)
-            # Unable to decode dataset
-            return 0x210
+    if os.path.exists(filename):
+        app_logger.warning('DICOM file already exists, overwriting')
 
-        # Add the file meta information elements
-        ds.file_meta = event.file_meta
+    status_ds = Dataset()
+    status_ds.Status = 0x0000
 
-        # Because pydicom uses deferred reads for its decoding, decoding errors
-        #   are hidden until encountered by accessing a faulty element
+    # Try to save to output-directory
+    if args.output_directory is not None:
+        filename = os.path.join(args.output_directory, filename)
         try:
-            sop_class = ds.SOPClassUID
-            sop_instance = ds.SOPInstanceUID
+            os.makedirs(args.output_directory)
         except Exception as exc:
-            app_logger.error(
-                "Unable to decode the received dataset or missing 'SOP Class "
-                "UID' and/or 'SOP Instance UID' elements"
-            )
+            app_logger.error('Unable to create the output directory:')
+            app_logger.error("    {0!s}".format(args.output_directory))
             app_logger.exception(exc)
-            # Unable to decode dataset
-            return 0xC210
-
-        try:
-            # Get the elements we need
-            mode_prefix = SOP_CLASS_PREFIXES[sop_class][0]
-        except KeyError:
-            mode_prefix = 'UN'
-
-        filename = '{0!s}.{1!s}'.format(mode_prefix, sop_instance)
-        app_logger.info('Storing DICOM file: {0!s}'.format(filename))
-
-        if os.path.exists(filename):
-            app_logger.warning('DICOM file already exists, overwriting')
-
-        status_ds = Dataset()
-        status_ds.Status = 0x0000
-
-        # Try to save to output-directory
-        if args.output_directory is not None:
-            filename = os.path.join(args.output_directory, filename)
-            try:
-                os.makedirs(args.output_directory)
-            except Exception as exc:
-                app_logger.error('Unable to create the output directory:')
-                app_logger.error("    {0!s}".format(args.output_directory))
-                app_logger.exception(exc)
-                # Failed - Out of Resources - IOError
-                status.Status = 0xA700
-                return status
-
-        try:
-            # We use `write_like_original=False` to ensure that a compliant
-            #   File Meta Information Header is written
-            ds.save_as(filename, write_like_original=False)
-            status_ds.Status = 0x0000 # Success
-        except IOError:
-            app_logger.error('Could not write file to specified directory:')
-            app_logger.error("    {0!s}".format(os.path.dirname(filename)))
-            app_logger.error(
-                'Directory may not exist or you may not have write permission '
-            )
             # Failed - Out of Resources - IOError
-            status_ds.Status = 0xA700
-        except Exception as exc:
-            app_logger.error('Could not write file to specified directory:')
-            app_logger.error("    {0!s}".format(os.path.dirname(filename)))
-            app_logger.exception(exc)
-            # Failed - Out of Resources - Miscellaneous error
-            status_ds.Status = 0xA701
-
-        return status_ds
-
-    return handle_store
+            status.Status = 0xA700
+            return status
+
+    try:
+        # We use `write_like_original=False` to ensure that a compliant
+        #   File Meta Information Header is written
+        ds.save_as(filename, write_like_original=False)
+        status_ds.Status = 0x0000 # Success
+    except IOError:
+        app_logger.error('Could not write file to specified directory:')
+        app_logger.error("    {0!s}".format(os.path.dirname(filename)))
+        app_logger.error(
+            'Directory may not exist or you may not have write permission '
+        )
+        # Failed - Out of Resources - IOError
+        status_ds.Status = 0xA700
+    except Exception as exc:
+        app_logger.error('Could not write file to specified directory:')
+        app_logger.error("    {0!s}".format(os.path.dirname(filename)))
+        app_logger.exception(exc)
+        # Failed - Out of Resources - Miscellaneous error
+        status_ds.Status = 0xA701
+
+    return status_ds
 
 
 SOP_CLASS_PREFIXES = {
diff --git a/pynetdicom/apps/getscu/getscu.py b/pynetdicom/apps/getscu/getscu.py
index 22a771336..bbcd27766 100755
--- a/pynetdicom/apps/getscu/getscu.py
+++ b/pynetdicom/apps/getscu/getscu.py
@@ -18,9 +18,7 @@ from pynetdicom import (
     StoragePresentationContexts,
     QueryRetrievePresentationContexts,
 )
-from pynetdicom.apps.common import (
-    setup_logging, create_dataset, wrap_handle_store
-)
+from pynetdicom.apps.common import setup_logging, create_dataset, handle_store
 from pynetdicom._globals import DEFAULT_MAX_LENGTH
 from pynetdicom.sop_class import (
     PatientRootQueryRetrieveInformationModelGet,
@@ -256,15 +254,13 @@ if __name__ == "__main__":
     else:
         query_model = PatientRootQueryRetrieveInformationModelGet
 
-    handle_store = wrap_handle_store(args, APP_LOGGER)
-
     # Request association with remote
     assoc = ae.associate(
         args.addr,
         args.port,
         ae_title=args.called_aet,
         ext_neg=ext_neg,
-        evt_handlers=[(evt.EVT_C_STORE, handle_store)],
+        evt_handlers=[(evt.EVT_C_STORE, handle_store, [args, APP_LOGGER])],
         max_pdu=args.max_pdu
     )
 
diff --git a/pynetdicom/apps/movescu/movescu.py b/pynetdicom/apps/movescu/movescu.py
index 7921b0a31..5ff601901 100755
--- a/pynetdicom/apps/movescu/movescu.py
+++ b/pynetdicom/apps/movescu/movescu.py
@@ -13,9 +13,7 @@ from pydicom.dataset import Dataset
 from pynetdicom import (
     AE, evt, QueryRetrievePresentationContexts, AllStoragePresentationContexts
 )
-from pynetdicom.apps.common import (
-    setup_logging, create_dataset, wrap_handle_store
-)
+from pynetdicom.apps.common import setup_logging, create_dataset, handle_store
 from pynetdicom._globals import ALL_TRANSFER_SYNTAXES, DEFAULT_MAX_LENGTH
 from pynetdicom.sop_class import (
     PatientRootQueryRetrieveInformationModelMove,
@@ -252,8 +250,7 @@ if __name__ == "__main__":
     scp = None
     if args.store:
         transfer_syntax = ALL_TRANSFER_SYNTAXES[:]
-        handle_store = wrap_handle_store(args, APP_LOGGER)
-        store_handlers = [(evt.EVT_C_STORE, handle_store)]
+        store_handlers = [(evt.EVT_C_STORE, handle_store, [args, APP_LOGGER])]
         ae.ae_title = args.store_aet
         for cx in AllStoragePresentationContexts:
             ae.add_supported_context(cx.abstract_syntax, transfer_syntax)
diff --git a/pynetdicom/apps/storescp/storescp.py b/pynetdicom/apps/storescp/storescp.py
index 8c8bb047a..65408dd3d 100755
--- a/pynetdicom/apps/storescp/storescp.py
+++ b/pynetdicom/apps/storescp/storescp.py
@@ -18,7 +18,7 @@ from pynetdicom import (
     AllStoragePresentationContexts,
     VerificationPresentationContexts,
 )
-from pynetdicom.apps.common import setup_logging, wrap_handle_store
+from pynetdicom.apps.common import setup_logging, handle_store
 from pynetdicom._globals import ALL_TRANSFER_SYNTAXES, DEFAULT_MAX_LENGTH
 
 
@@ -191,8 +191,7 @@ if __name__ == "__main__":
     elif args.implicit:
         transfer_syntax = [ImplicitVRLittleEndian]
 
-    handle_store = wrap_handle_store(args, APP_LOGGER)
-    handlers = [(evt.EVT_C_STORE, handle_store)]
+    handlers = [(evt.EVT_C_STORE, handle_store, [args, APP_LOGGER])]
 
     # Create application entity
     ae = AE(ae_title=args.ae_title)
diff --git a/pynetdicom/association.py b/pynetdicom/association.py
index d9a301e29..cac8e1f56 100644
--- a/pynetdicom/association.py
+++ b/pynetdicom/association.py
@@ -171,7 +171,7 @@ class Association(threading.Thread):
     @acse_timeout.setter
     def acse_timeout(self, value):
         """Set the ACSE timeout using numeric or ``None``."""
-        with threading.Lock():
+        with self.lock:
             self.dul.artim_timer.timeout = value
             self._acse_timeout = value
 
@@ -180,34 +180,38 @@ class Association(threading.Thread):
         """Return the parent :class:`~pynetdicom.ae.ApplicationEntity`."""
         return self._ae
 
-    def bind(self, event, handler):
+    def bind(self, event, handler, args=None):
         """Bind a callable `handler` to an `event`.
 
         .. versionadded:: 1.3
 
+        .. versionchanged:: 1.5
+
+            Added `args` keyword parameter.
+
         Parameters
         ----------
         event : namedtuple
             The event to bind the function to.
         handler : callable
             The function that will be called if the event occurs.
+        args : list, optional
+            Optional extra arguments to be passed to the handler (default:
+            no extra arguments passed to the handler).
         """
         # Make sure no access to `_handlers` while its being changed
-        with threading.Lock():
+        with self.lock:
             # Notification events - multiple handlers allowed
             if event.is_notification:
                 if event not in self._handlers:
                     self._handlers[event] = []
-                if handler not in self._handlers[event]:
-                    self._handlers[event].append(handler)
+
+                if (handler, args) not in self._handlers[event]:
+                    self._handlers[event].append((handler, args))
 
             # Intervention events - only one handler allowed
             if event.is_intervention:
-                if event not in self._handlers:
-                    self._handlers[event] = None
-
-                if self._handlers[event] != handler:
-                    self._handlers[event] = handler
+                self._handlers[event] = (handler, args)
 
     def _bind_defaults(self):
         """Bind the default event handlers."""
@@ -269,7 +273,7 @@ class Association(threading.Thread):
     @dimse_timeout.setter
     def dimse_timeout(self, value):
         """Set the DIMSE timeout using numeric or ``None``."""
-        with threading.Lock():
+        with self.lock:
             self._dimse_timeout = value
 
     def get_events(self):
@@ -284,6 +288,10 @@ class Association(threading.Thread):
 
         .. versionadded:: 1.3
 
+        .. versionchanged:: 1.5
+
+            Returns a 2-tuple of (callable, args) or list of 2-tuple.
+
         Parameters
         ----------
         event : namedtuple
@@ -291,12 +299,13 @@ class Association(threading.Thread):
 
         Returns
         -------
-        callable, list of callable or None
+        2-tuple of (callable, args), list of 2-tuple
             If the event is a notification event then returns a list of
-            callable functions bound to `event`, if the event is an
-            intervention event then returns either a callable function if a
-            handler is bound to the event or ``None`` if no handler has been
-            bound.
+            2-tuples containing the callable functions bound to `event` and
+            the arguments passed to the callable as ``(callable, args)``. If
+            the event is an intervention event then returns either a 2-tuple of
+            (callable, args) if a handler is bound to the event or
+            ``(None, None)`` if no handler has been bound.
         """
         if event not in self._handlers:
             return []
@@ -459,7 +468,7 @@ class Association(threading.Thread):
     @network_timeout.setter
     def network_timeout(self, value):
         """Set the network timeout using numeric or ``None``."""
-        with threading.Lock():
+        with self.lock:
             self.dul._idle_timer.timeout = value
             self._network_timeout = value
 
@@ -654,17 +663,23 @@ class Association(threading.Thread):
             return
 
         # Make sure no access to `_handlers` while its being changed
-        with threading.Lock():
+        with self.lock:
+
             # Notification events
-            if event.is_notification and handler in self._handlers[event]:
-                self._handlers[event].remove(handler)
+            if event.is_notification:
+                handlers = [hh[0] for hh in self._handlers[event]]
+                try:
+                    ii = handlers.index(handler)
+                    del self._handlers[event][ii]
+                except ValueError:
+                    pass
 
                 if not self._handlers[event]:
                     del self._handlers[event]
 
             # Intervention events - unbind and replace with default
-            if event.is_intervention and self._handlers[event] == handler:
-                self._handlers[event] = evt.get_default_handler(event)
+            if event.is_intervention and handler in self._handlers[event]:
+                self._handlers[event] = (evt.get_default_handler(event), None)
 
     # DIMSE-C services provided by the Association
     def _c_store_scp(self, req):
diff --git a/pynetdicom/events.py b/pynetdicom/events.py
index 7f872ed8e..344754cd8 100644
--- a/pynetdicom/events.py
+++ b/pynetdicom/events.py
@@ -193,10 +193,12 @@ def trigger(assoc, event, attrs=None):
         handler then the exception will be caught and logged instead.
     """
     # Get the handler(s) bound to the event
-    #   notification events: returns a list of callable
-    #   intervention events: returns a callable or None
+    #   notification events: returns a list of 2-tuple (callable, args)
+    #   intervention events: returns a 2-tuple of (callable, args)
+    #       or (None, None)
     handlers = assoc.get_handlers(event)
-    if not handlers:
+    # Empty list or (None, None)
+    if not handlers or handlers[0] is None:
         return
 
     evt = Event(assoc, event, attrs or {})
@@ -204,11 +206,17 @@ def trigger(assoc, event, attrs=None):
     try:
         # Intervention event - only single handler allowed
         if event.is_intervention:
-            return handlers(evt)
+            if handlers[1] is not None:
+                return handlers[0](evt, *handlers[1])
+
+            return handlers[0](evt)
 
         # Notification event - multiple handlers are allowed
-        for func in handlers:
-            func(evt)
+        for func, args in handlers:
+            if args:
+                func(evt, *args)
+            else:
+                func(evt)
     except Exception as exc:
         # Intervention exceptions get raised
         if event.is_intervention:
diff --git a/pynetdicom/transport.py b/pynetdicom/transport.py
index 01ffb0d40..022175348 100644
--- a/pynetdicom/transport.py
+++ b/pynetdicom/transport.py
@@ -437,10 +437,10 @@ class RequestHandler(BaseRequestHandler):
         for event in self.server._handlers:
             # Intervention events
             if event.is_intervention and self.server._handlers[event]:
-                assoc.bind(event, self.server._handlers[event])
+                assoc.bind(event, *self.server._handlers[event])
             elif event.is_notification:
                 for handler in self.server._handlers[event]:
-                    assoc.bind(event, handler)
+                    assoc.bind(event, *handler)
 
         # Trigger must be after binding the events
         evt.trigger(
@@ -505,9 +505,10 @@ class AssociationServer(TCPServer):
             If TLS is to be used then this should be the
             :class:`ssl.SSLContext` used to wrap the client sockets, otherwise
             if ``None`` then no TLS will be used (default).
-        evt_handlers : list of 2-tuple, optional
-            A list of ``(event, callable)``, the *callable* function to run
-            when *event* occurs.
+        evt_handlers : list of 2- or 3-tuple, optional
+            A list of ``(event, callable)`` or ``(event, callable, args)``,
+            the *callable* function to run when *event* occurs and the
+            optional extra *args* to pass to the callable.
         """
         self.ae = ae
         self.ae_title = ae_title
@@ -532,40 +533,43 @@ class AssociationServer(TCPServer):
         self._bind_defaults()
 
         # Bind the functions to their events
-        for (event, handler) in (evt_handlers or {}):
-            self.bind(event, handler)
+        for evt_hh_args in (evt_handlers or {}):
+            self.bind(*evt_hh_args)
 
-    def bind(self, event, handler):
+    def bind(self, event, handler, args=None):
         """Bind a callable `handler` to an `event`.
 
         .. versionadded:: 1.3
 
+        .. versionchanged:: 1.5
+
+            Added `args` keyword parameter.
+
         Parameters
         ----------
-        event : 3-tuple
+        event : namedtuple
             The event to bind the function to.
         handler : callable
             The function that will be called if the event occurs.
+        args : list, optional
+            Optional extra arguments to be passed to the handler (default:
+            no extra arguments passed to the handler).
         """
         # Notification events - multiple handlers allowed
         if event.is_notification:
             if event not in self._handlers:
                 self._handlers[event] = []
 
-            if handler not in self._handlers[event]:
-                self._handlers[event].append(handler)
+            if (handler, args) not in self._handlers[event]:
+                self._handlers[event].append((handler, args))
 
         # Intervention events - only one handler allowed
         if event.is_intervention:
-            if event not in self._handlers:
-                self._handlers[event] = None
-
-            if self._handlers[event] != handler:
-                self._handlers[event] = handler
+            self._handlers[event] = (handler, args)
 
         # Bind our child Association events
         for assoc in self.active_associations:
-            assoc.bind(event, handler)
+            assoc.bind(event, handler, args)
 
     def _bind_defaults(self):
         """Bind the default event handlers."""
@@ -604,19 +608,24 @@ class AssociationServer(TCPServer):
 
         .. versionadded:: 1.3
 
+        .. versionchanged:: 1.5
+
+            Returns a 2-tuple of (callable, args) or list of 2-tuple.
+
         Parameters
         ----------
-        event : tuple
+        event : namedtuple
             The event bound to the handlers.
 
         Returns
         -------
-        callable, list of callable or None
+        2-tuple of (callable, args), list of 2-tuple
             If the event is a notification event then returns a list of
-            callable functions bound to *event*, if the event is an
-            intervention event then returns either a callable function if a
-            handler is bound to the event or ``None`` if no handler has been
-            bound.
+            2-tuples containing the callable functions bound to `event` and
+            the arguments passed to the callable as ``(callable, args)``. If
+            the event is an intervention event then returns either a 2-tuple of
+            (callable, args) if a handler is bound to the event or
+            ``(None, None)`` if no handler has been bound.
         """
         if event not in self._handlers:
             return []
@@ -737,22 +746,25 @@ class AssociationServer(TCPServer):
         if event not in self._handlers:
             return
 
-        # Make sure no access to `_handlers` while its being changed
-        with threading.Lock():
-            # Notification events
-            if event.is_notification and handler in self._handlers[event]:
-                self._handlers[event].remove(handler)
+        # Notification events
+        if event.is_notification:
+            handlers = [hh[0] for hh in self._handlers[event]]
+            try:
+                ii = handlers.index(handler)
+                del self._handlers[event][ii]
+            except ValueError:
+                pass
 
-                if not self._handlers[event]:
-                    del self._handlers[event]
+            if not self._handlers[event]:
+                del self._handlers[event]
 
-            # Intervention events - unbind and replace with default
-            if event.is_intervention and self._handlers[event] == handler:
-                self._handlers[event] = evt.get_default_handler(event)
+        # Intervention events - unbind and replace with default
+        if event.is_intervention and handler in self._handlers[event]:
+            self._handlers[event] = (evt.get_default_handler(event), None)
 
-            # Unbind from our child Association events
-            for assoc in self.active_associations:
-                assoc.unbind(event, handler)
+        # Unbind from our child Association events
+        for assoc in self.active_associations:
+            assoc.unbind(event, handler)
 
 
 class ThreadedAssociationServer(ThreadingMixIn, AssociationServer):


Test patch:
diff --git a/pynetdicom/tests/test_acse.py b/pynetdicom/tests/test_acse.py
index 85c69c193..bbea92441 100644
--- a/pynetdicom/tests/test_acse.py
+++ b/pynetdicom/tests/test_acse.py
@@ -2183,16 +2183,16 @@ class TestEventHandlingAcceptor(object):
         ae.add_requested_context(VerificationSOPClass)
         handlers = [(evt.EVT_ACSE_SENT, handle)]
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
-        assert scp.get_handlers(evt.EVT_ACSE_SENT) == [handle]
+        assert scp.get_handlers(evt.EVT_ACSE_SENT) == [(handle, None)]
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
         assert len(scp.active_associations) == 1
-        assert scp.get_handlers(evt.EVT_ACSE_SENT) == [handle]
+        assert scp.get_handlers(evt.EVT_ACSE_SENT) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_ACSE_SENT) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_ACSE_SENT) == [handle]
+        assert child.get_handlers(evt.EVT_ACSE_SENT) == [(handle, None)]
 
         assoc.send_c_echo()
 
@@ -2237,11 +2237,11 @@ class TestEventHandlingAcceptor(object):
         scp.bind(evt.EVT_ACSE_SENT, handle)
 
         assert len(scp.active_associations) == 1
-        assert scp.get_handlers(evt.EVT_ACSE_SENT) == [handle]
+        assert scp.get_handlers(evt.EVT_ACSE_SENT) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_ACSE_SENT) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_ACSE_SENT) == [handle]
+        assert child.get_handlers(evt.EVT_ACSE_SENT) == [(handle, None)]
 
         assoc.send_c_echo(msg_id=21)
 
@@ -2272,13 +2272,13 @@ class TestEventHandlingAcceptor(object):
         ae.add_requested_context(VerificationSOPClass)
         handlers = [(evt.EVT_ACSE_SENT, handle)]
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
-        assert scp.get_handlers(evt.EVT_ACSE_SENT) == [handle]
+        assert scp.get_handlers(evt.EVT_ACSE_SENT) == [(handle, None)]
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_ACSE_SENT) == [handle]
+        assert child.get_handlers(evt.EVT_ACSE_SENT) == [(handle, None)]
 
         assert assoc.get_handlers(evt.EVT_ACSE_SENT) == []
 
@@ -2350,16 +2350,16 @@ class TestEventHandlingAcceptor(object):
         ae.add_requested_context(VerificationSOPClass)
         handlers = [(evt.EVT_ACSE_RECV, handle)]
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
-        assert scp.get_handlers(evt.EVT_ACSE_RECV) == [handle]
+        assert scp.get_handlers(evt.EVT_ACSE_RECV) == [(handle, None)]
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
         assert len(scp.active_associations) == 1
-        assert scp.get_handlers(evt.EVT_ACSE_RECV) == [handle]
+        assert scp.get_handlers(evt.EVT_ACSE_RECV) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_ACSE_RECV) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_ACSE_RECV) == [handle]
+        assert child.get_handlers(evt.EVT_ACSE_RECV) == [(handle, None)]
 
         assoc.send_c_echo()
 
@@ -2402,11 +2402,11 @@ class TestEventHandlingAcceptor(object):
 
         scp.bind(evt.EVT_ACSE_RECV, handle)
 
-        assert scp.get_handlers(evt.EVT_ACSE_RECV) == [handle]
+        assert scp.get_handlers(evt.EVT_ACSE_RECV) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_ACSE_RECV) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_ACSE_RECV) == [handle]
+        assert child.get_handlers(evt.EVT_ACSE_RECV) == [(handle, None)]
 
         assoc.send_c_echo(msg_id=21)
 
@@ -2436,14 +2436,14 @@ class TestEventHandlingAcceptor(object):
         ae.add_requested_context(VerificationSOPClass)
         handlers = [(evt.EVT_ACSE_RECV, handle)]
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
-        assert scp.get_handlers(evt.EVT_ACSE_RECV) == [handle]
+        assert scp.get_handlers(evt.EVT_ACSE_RECV) == [(handle, None)]
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
         assert len(scp.active_associations) == 1
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_ACSE_RECV) == [handle]
+        assert child.get_handlers(evt.EVT_ACSE_RECV) == [(handle, None)]
 
         assoc.send_c_echo(msg_id=12)
 
@@ -2555,7 +2555,7 @@ class TestEventHandlingRequestor(object):
         assert assoc.is_established
         assert len(scp.active_associations) == 1
         assert scp.get_handlers(evt.EVT_ACSE_SENT) == []
-        assert assoc.get_handlers(evt.EVT_ACSE_SENT) == [handle]
+        assert assoc.get_handlers(evt.EVT_ACSE_SENT) == [(handle, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_ACSE_SENT) == []
@@ -2595,7 +2595,7 @@ class TestEventHandlingRequestor(object):
         assert assoc.is_established
         assert len(scp.active_associations) == 1
         assert scp.get_handlers(evt.EVT_ACSE_SENT) == []
-        assert assoc.get_handlers(evt.EVT_ACSE_SENT) == [handle]
+        assert assoc.get_handlers(evt.EVT_ACSE_SENT) == [(handle, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_ACSE_SENT) == []
@@ -2639,7 +2639,7 @@ class TestEventHandlingRequestor(object):
 
         assert len(scp.active_associations) == 1
         assert scp.get_handlers(evt.EVT_ACSE_SENT) == []
-        assert assoc.get_handlers(evt.EVT_ACSE_SENT) == [handle]
+        assert assoc.get_handlers(evt.EVT_ACSE_SENT) == [(handle, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_ACSE_SENT) == []
@@ -2680,7 +2680,7 @@ class TestEventHandlingRequestor(object):
         assoc.send_c_echo(msg_id=12)
         assert len(scp.active_associations) == 1
         assert scp.get_handlers(evt.EVT_ACSE_SENT) == []
-        assert assoc.get_handlers(evt.EVT_ACSE_SENT) == [handle]
+        assert assoc.get_handlers(evt.EVT_ACSE_SENT) == [(handle, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_ACSE_SENT) == []
@@ -2747,7 +2747,7 @@ class TestEventHandlingRequestor(object):
         assert assoc.is_established
         assert len(scp.active_associations) == 1
         assert scp.get_handlers(evt.EVT_ACSE_RECV) == []
-        assert assoc.get_handlers(evt.EVT_ACSE_RECV) == [handle]
+        assert assoc.get_handlers(evt.EVT_ACSE_RECV) == [(handle, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_ACSE_RECV) == []
@@ -2811,7 +2811,7 @@ class TestEventHandlingRequestor(object):
         assoc.bind(evt.EVT_ACSE_RECV, handle)
 
         assert scp.get_handlers(evt.EVT_ACSE_RECV) == []
-        assert assoc.get_handlers(evt.EVT_ACSE_RECV) == [handle]
+        assert assoc.get_handlers(evt.EVT_ACSE_RECV) == [(handle, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_ACSE_RECV) == []
@@ -2842,7 +2842,7 @@ class TestEventHandlingRequestor(object):
 
         assoc = ae.associate('localhost', 11112, evt_handlers=handlers)
         assert assoc.is_established
-        assert assoc.get_handlers(evt.EVT_ACSE_RECV) == [handle]
+        assert assoc.get_handlers(evt.EVT_ACSE_RECV) == [(handle, None)]
         assoc.send_c_echo(msg_id=12)
 
         assoc.unbind(evt.EVT_ACSE_RECV, handle)
diff --git a/pynetdicom/tests/test_assoc.py b/pynetdicom/tests/test_assoc.py
index 24d38cf9a..4d49f5373 100644
--- a/pynetdicom/tests/test_assoc.py
+++ b/pynetdicom/tests/test_assoc.py
@@ -4326,10 +4326,10 @@ class TestEventHandlingAcceptor(object):
         ae.add_requested_context(VerificationSOPClass)
         scp = ae.start_server(('', 11112), block=False)
         scp.bind(evt.EVT_C_ECHO, dummy)
-        assert scp.get_handlers(evt.EVT_C_ECHO) == dummy
+        assert scp.get_handlers(evt.EVT_C_ECHO) == (dummy, None)
         scp.unbind(evt.EVT_C_ECHO, dummy)
-        assert scp.get_handlers(evt.EVT_C_ECHO) != dummy
-        assert scp.get_handlers(evt.EVT_C_ECHO) == evt._c_echo_handler
+        assert scp.get_handlers(evt.EVT_C_ECHO) != (dummy, None)
+        assert scp.get_handlers(evt.EVT_C_ECHO) == (evt._c_echo_handler, None)
 
         scp.shutdown()
 
@@ -4343,7 +4343,7 @@ class TestEventHandlingAcceptor(object):
         ae.add_requested_context(VerificationSOPClass)
         scp = ae.start_server(('', 11112), block=False)
         scp.bind(evt.EVT_C_ECHO, dummy)
-        assert scp.get_handlers(evt.EVT_C_ECHO) == dummy
+        assert scp.get_handlers(evt.EVT_C_ECHO) == (dummy, None)
 
         assoc = ae.associate('localhost', 11112)
 
@@ -4351,13 +4351,15 @@ class TestEventHandlingAcceptor(object):
         assert len(scp.active_associations) == 1
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_C_ECHO) == dummy
+        assert child.get_handlers(evt.EVT_C_ECHO) == (dummy, None)
 
         scp.unbind(evt.EVT_C_ECHO, dummy)
-        assert scp.get_handlers(evt.EVT_C_ECHO) != dummy
-        assert scp.get_handlers(evt.EVT_C_ECHO) == evt._c_echo_handler
-        assert child.get_handlers(evt.EVT_C_ECHO) != dummy
-        assert child.get_handlers(evt.EVT_C_ECHO) == evt._c_echo_handler
+        assert scp.get_handlers(evt.EVT_C_ECHO) != (dummy, None)
+        assert scp.get_handlers(evt.EVT_C_ECHO) == (evt._c_echo_handler, None)
+        assert child.get_handlers(evt.EVT_C_ECHO) != (dummy, None)
+        assert child.get_handlers(evt.EVT_C_ECHO) == (
+            evt._c_echo_handler, None
+        )
 
         assoc.release()
 
@@ -4374,7 +4376,7 @@ class TestEventHandlingAcceptor(object):
         ae.add_requested_context(VerificationSOPClass)
         handlers = [(evt.EVT_ABORTED, handle)]
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
-        assert scp.get_handlers(evt.EVT_ABORTED) == [handle]
+        assert scp.get_handlers(evt.EVT_ABORTED) == [(handle, None)]
         assert scp.get_handlers(evt.EVT_ACCEPTED) == []
         assert scp.get_handlers(evt.EVT_ESTABLISHED) == []
         assert scp.get_handlers(evt.EVT_REJECTED) == []
@@ -4385,7 +4387,7 @@ class TestEventHandlingAcceptor(object):
         assert assoc.is_established
         assert len(scp.active_associations) == 1
 
-        assert scp.get_handlers(evt.EVT_ABORTED) == [handle]
+        assert scp.get_handlers(evt.EVT_ABORTED) == [(handle, None)]
         assert scp.get_handlers(evt.EVT_ACCEPTED) == []
         assert scp.get_handlers(evt.EVT_ESTABLISHED) == []
         assert scp.get_handlers(evt.EVT_REJECTED) == []
@@ -4400,7 +4402,7 @@ class TestEventHandlingAcceptor(object):
         assert assoc.get_handlers(evt.EVT_REQUESTED) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_ABORTED) == [handle]
+        assert child.get_handlers(evt.EVT_ABORTED) == [(handle, None)]
         assert child.get_handlers(evt.EVT_ACCEPTED) == []
         assert child.get_handlers(evt.EVT_ESTABLISHED) == []
         assert child.get_handlers(evt.EVT_REJECTED) == []
@@ -4467,7 +4469,7 @@ class TestEventHandlingAcceptor(object):
 
         scp.bind(evt.EVT_ABORTED, handle)
 
-        assert scp.get_handlers(evt.EVT_ABORTED) == [handle]
+        assert scp.get_handlers(evt.EVT_ABORTED) == [(handle, None)]
         assert scp.get_handlers(evt.EVT_ACCEPTED) == []
         assert scp.get_handlers(evt.EVT_ESTABLISHED) == []
         assert scp.get_handlers(evt.EVT_REJECTED) == []
@@ -4482,7 +4484,7 @@ class TestEventHandlingAcceptor(object):
         assert assoc.get_handlers(evt.EVT_REQUESTED) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_ABORTED) == [handle]
+        assert child.get_handlers(evt.EVT_ABORTED) == [(handle, None)]
         assert child.get_handlers(evt.EVT_ACCEPTED) == []
         assert child.get_handlers(evt.EVT_ESTABLISHED) == []
         assert child.get_handlers(evt.EVT_REJECTED) == []
@@ -4514,7 +4516,7 @@ class TestEventHandlingAcceptor(object):
         ae.add_requested_context(VerificationSOPClass)
         handlers = [(evt.EVT_ABORTED, handle)]
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
-        assert scp.get_handlers(evt.EVT_ABORTED) == [handle]
+        assert scp.get_handlers(evt.EVT_ABORTED) == [(handle, None)]
         assert scp.get_handlers(evt.EVT_ACCEPTED) == []
         assert scp.get_handlers(evt.EVT_ESTABLISHED) == []
         assert scp.get_handlers(evt.EVT_REJECTED) == []
@@ -4525,7 +4527,7 @@ class TestEventHandlingAcceptor(object):
         assert assoc.is_established
         assert len(scp.active_associations) == 1
 
-        assert scp.get_handlers(evt.EVT_ABORTED) == [handle]
+        assert scp.get_handlers(evt.EVT_ABORTED) == [(handle, None)]
         assert scp.get_handlers(evt.EVT_ACCEPTED) == []
         assert scp.get_handlers(evt.EVT_ESTABLISHED) == []
         assert scp.get_handlers(evt.EVT_REJECTED) == []
@@ -4540,7 +4542,7 @@ class TestEventHandlingAcceptor(object):
         assert assoc.get_handlers(evt.EVT_REQUESTED) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_ABORTED) == [handle]
+        assert child.get_handlers(evt.EVT_ABORTED) == [(handle, None)]
         assert child.get_handlers(evt.EVT_ACCEPTED) == []
         assert child.get_handlers(evt.EVT_ESTABLISHED) == []
         assert child.get_handlers(evt.EVT_REJECTED) == []
@@ -4651,7 +4653,7 @@ class TestEventHandlingAcceptor(object):
         handlers = [(evt.EVT_ACCEPTED, handle)]
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
         assert scp.get_handlers(evt.EVT_ABORTED) == []
-        assert scp.get_handlers(evt.EVT_ACCEPTED) == [handle]
+        assert scp.get_handlers(evt.EVT_ACCEPTED) == [(handle, None)]
         assert scp.get_handlers(evt.EVT_ESTABLISHED) == []
         assert scp.get_handlers(evt.EVT_REJECTED) == []
         assert scp.get_handlers(evt.EVT_RELEASED) == []
@@ -4662,7 +4664,7 @@ class TestEventHandlingAcceptor(object):
         assert len(scp.active_associations) == 1
 
         assert scp.get_handlers(evt.EVT_ABORTED) == []
-        assert scp.get_handlers(evt.EVT_ACCEPTED) == [handle]
+        assert scp.get_handlers(evt.EVT_ACCEPTED) == [(handle, None)]
         assert scp.get_handlers(evt.EVT_ESTABLISHED) == []
         assert scp.get_handlers(evt.EVT_REJECTED) == []
         assert scp.get_handlers(evt.EVT_RELEASED) == []
@@ -4677,7 +4679,7 @@ class TestEventHandlingAcceptor(object):
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_ABORTED) == []
-        assert child.get_handlers(evt.EVT_ACCEPTED) == [handle]
+        assert child.get_handlers(evt.EVT_ACCEPTED) == [(handle, None)]
         assert child.get_handlers(evt.EVT_ESTABLISHED) == []
         assert child.get_handlers(evt.EVT_REJECTED) == []
         assert child.get_handlers(evt.EVT_RELEASED) == []
@@ -4722,9 +4724,9 @@ class TestEventHandlingAcceptor(object):
 
         scp.bind(evt.EVT_ACCEPTED, handle)
 
-        assert scp.get_handlers(evt.EVT_ACCEPTED) == [handle]
+        assert scp.get_handlers(evt.EVT_ACCEPTED) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_ACCEPTED) == []
-        assert child.get_handlers(evt.EVT_ACCEPTED) == [handle]
+        assert child.get_handlers(evt.EVT_ACCEPTED) == [(handle, None)]
 
         assoc2 = ae.associate('localhost', 11112)
 
@@ -4750,16 +4752,16 @@ class TestEventHandlingAcceptor(object):
         ae.add_requested_context(VerificationSOPClass)
         handlers = [(evt.EVT_ACCEPTED, handle)]
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
-        assert scp.get_handlers(evt.EVT_ACCEPTED) == [handle]
+        assert scp.get_handlers(evt.EVT_ACCEPTED) == [(handle, None)]
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
         assert len(scp.active_associations) == 1
 
-        assert scp.get_handlers(evt.EVT_ACCEPTED) == [handle]
+        assert scp.get_handlers(evt.EVT_ACCEPTED) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_ACCEPTED) == []
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_ACCEPTED) == [handle]
+        assert child.get_handlers(evt.EVT_ACCEPTED) == [(handle, None)]
 
         assert len(triggered) == 1
         assert triggered[0].event.name == "EVT_ACCEPTED"
@@ -4826,7 +4828,7 @@ class TestEventHandlingAcceptor(object):
         assert scp.get_handlers(evt.EVT_ACCEPTED) == []
         assert scp.get_handlers(evt.EVT_ESTABLISHED) == []
         assert scp.get_handlers(evt.EVT_REJECTED) == []
-        assert scp.get_handlers(evt.EVT_RELEASED) == [handle]
+        assert scp.get_handlers(evt.EVT_RELEASED) == [(handle, None)]
         assert scp.get_handlers(evt.EVT_REQUESTED) == []
 
         assoc = ae.associate('localhost', 11112)
@@ -4837,7 +4839,7 @@ class TestEventHandlingAcceptor(object):
         assert scp.get_handlers(evt.EVT_ACCEPTED) == []
         assert scp.get_handlers(evt.EVT_ESTABLISHED) == []
         assert scp.get_handlers(evt.EVT_REJECTED) == []
-        assert scp.get_handlers(evt.EVT_RELEASED) == [handle]
+        assert scp.get_handlers(evt.EVT_RELEASED) == [(handle, None)]
         assert scp.get_handlers(evt.EVT_REQUESTED) == []
 
         assert assoc.get_handlers(evt.EVT_ABORTED) == []
@@ -4852,7 +4854,7 @@ class TestEventHandlingAcceptor(object):
         assert child.get_handlers(evt.EVT_ACCEPTED) == []
         assert child.get_handlers(evt.EVT_ESTABLISHED) == []
         assert child.get_handlers(evt.EVT_REJECTED) == []
-        assert child.get_handlers(evt.EVT_RELEASED) == [handle]
+        assert child.get_handlers(evt.EVT_RELEASED) == [(handle, None)]
         assert child.get_handlers(evt.EVT_REQUESTED) == []
 
         assoc.release()
@@ -4894,10 +4896,10 @@ class TestEventHandlingAcceptor(object):
 
         scp.bind(evt.EVT_RELEASED, handle)
 
-        assert scp.get_handlers(evt.EVT_RELEASED) == [handle]
+        assert scp.get_handlers(evt.EVT_RELEASED) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_RELEASED) == []
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_RELEASED) == [handle]
+        assert child.get_handlers(evt.EVT_RELEASED) == [(handle, None)]
 
         assoc.release()
 
@@ -5017,7 +5019,7 @@ class TestEventHandlingAcceptor(object):
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
         assert scp.get_handlers(evt.EVT_ABORTED) == []
         assert scp.get_handlers(evt.EVT_ACCEPTED) == []
-        assert scp.get_handlers(evt.EVT_ESTABLISHED) == [handle]
+        assert scp.get_handlers(evt.EVT_ESTABLISHED) == [(handle, None)]
         assert scp.get_handlers(evt.EVT_REJECTED) == []
         assert scp.get_handlers(evt.EVT_RELEASED) == []
         assert scp.get_handlers(evt.EVT_REQUESTED) == []
@@ -5028,7 +5030,7 @@ class TestEventHandlingAcceptor(object):
 
         assert scp.get_handlers(evt.EVT_ABORTED) == []
         assert scp.get_handlers(evt.EVT_ACCEPTED) == []
-        assert scp.get_handlers(evt.EVT_ESTABLISHED) == [handle]
+        assert scp.get_handlers(evt.EVT_ESTABLISHED) == [(handle, None)]
         assert scp.get_handlers(evt.EVT_REJECTED) == []
         assert scp.get_handlers(evt.EVT_RELEASED) == []
         assert scp.get_handlers(evt.EVT_REQUESTED) == []
@@ -5043,7 +5045,7 @@ class TestEventHandlingAcceptor(object):
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_ABORTED) == []
         assert child.get_handlers(evt.EVT_ACCEPTED) == []
-        assert child.get_handlers(evt.EVT_ESTABLISHED) == [handle]
+        assert child.get_handlers(evt.EVT_ESTABLISHED) == [(handle, None)]
         assert child.get_handlers(evt.EVT_REJECTED) == []
         assert child.get_handlers(evt.EVT_RELEASED) == []
         assert child.get_handlers(evt.EVT_REQUESTED) == []
@@ -5081,10 +5083,10 @@ class TestEventHandlingAcceptor(object):
         assert assoc.is_established
         assert len(scp.active_associations) == 1
 
-        assert scp.get_handlers(evt.EVT_ESTABLISHED) == [handle]
+        assert scp.get_handlers(evt.EVT_ESTABLISHED) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_ESTABLISHED) == []
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_ESTABLISHED) == [handle]
+        assert child.get_handlers(evt.EVT_ESTABLISHED) == [(handle, None)]
 
         assoc.release()
 
@@ -5176,7 +5178,7 @@ class TestEventHandlingAcceptor(object):
         assert scp.get_handlers(evt.EVT_ESTABLISHED) == []
         assert scp.get_handlers(evt.EVT_REJECTED) == []
         assert scp.get_handlers(evt.EVT_RELEASED) == []
-        assert scp.get_handlers(evt.EVT_REQUESTED) == [handle]
+        assert scp.get_handlers(evt.EVT_REQUESTED) == [(handle, None)]
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
@@ -5187,7 +5189,7 @@ class TestEventHandlingAcceptor(object):
         assert scp.get_handlers(evt.EVT_ESTABLISHED) == []
         assert scp.get_handlers(evt.EVT_REJECTED) == []
         assert scp.get_handlers(evt.EVT_RELEASED) == []
-        assert scp.get_handlers(evt.EVT_REQUESTED) == [handle]
+        assert scp.get_handlers(evt.EVT_REQUESTED) == [(handle, None)]
 
         assert assoc.get_handlers(evt.EVT_ABORTED) == []
         assert assoc.get_handlers(evt.EVT_ACCEPTED) == []
@@ -5202,7 +5204,7 @@ class TestEventHandlingAcceptor(object):
         assert child.get_handlers(evt.EVT_ESTABLISHED) == []
         assert child.get_handlers(evt.EVT_REJECTED) == []
         assert child.get_handlers(evt.EVT_RELEASED) == []
-        assert child.get_handlers(evt.EVT_REQUESTED) == [handle]
+        assert child.get_handlers(evt.EVT_REQUESTED) == [(handle, None)]
 
         assoc.release()
 
@@ -5237,10 +5239,10 @@ class TestEventHandlingAcceptor(object):
         assert assoc.is_established
         assert len(scp.active_associations) == 1
 
-        assert scp.get_handlers(evt.EVT_REQUESTED) == [handle]
+        assert scp.get_handlers(evt.EVT_REQUESTED) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_REQUESTED) == []
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_REQUESTED) == [handle]
+        assert child.get_handlers(evt.EVT_REQUESTED) == [(handle, None)]
 
         assoc.release()
 
@@ -5331,7 +5333,7 @@ class TestEventHandlingAcceptor(object):
         assert scp.get_handlers(evt.EVT_ABORTED) == []
         assert scp.get_handlers(evt.EVT_ACCEPTED) == []
         assert scp.get_handlers(evt.EVT_ESTABLISHED) == []
-        assert scp.get_handlers(evt.EVT_REJECTED) == [handle]
+        assert scp.get_handlers(evt.EVT_REJECTED) == [(handle, None)]
         assert scp.get_handlers(evt.EVT_RELEASED) == []
         assert scp.get_handlers(evt.EVT_REQUESTED) == []
 
@@ -5341,7 +5343,7 @@ class TestEventHandlingAcceptor(object):
         assert scp.get_handlers(evt.EVT_ABORTED) == []
         assert scp.get_handlers(evt.EVT_ACCEPTED) == []
         assert scp.get_handlers(evt.EVT_ESTABLISHED) == []
-        assert scp.get_handlers(evt.EVT_REJECTED) == [handle]
+        assert scp.get_handlers(evt.EVT_REJECTED) == [(handle, None)]
         assert scp.get_handlers(evt.EVT_RELEASED) == []
         assert scp.get_handlers(evt.EVT_REQUESTED) == []
 
@@ -5380,7 +5382,7 @@ class TestEventHandlingAcceptor(object):
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_rejected
 
-        assert scp.get_handlers(evt.EVT_REJECTED) == [handle]
+        assert scp.get_handlers(evt.EVT_REJECTED) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_REJECTED) == []
 
         assert len(triggered) == 1
@@ -5443,6 +5445,75 @@ class TestEventHandlingAcceptor(object):
             assert msg in caplog.text
             assert "Exception description" in caplog.text
 
+    def test_optional_args(self):
+        """Test passing optional arguments to the handler."""
+        arguments = []
+        def handle(event, *args):
+            arguments.append(args)
+
+        args = ['a', 1, {'test': 1}]
+
+        self.ae = ae = AE()
+        ae.add_supported_context(VerificationSOPClass)
+        ae.add_requested_context(VerificationSOPClass)
+        handlers = [(evt.EVT_ACCEPTED, handle, args)]
+        scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
+
+        assoc = ae.associate('localhost', 11112)
+        assert assoc.is_established
+        assert len(scp.active_associations) == 1
+        assert scp.get_handlers(evt.EVT_ACCEPTED) == [(handle, args)]
+        assert assoc.get_handlers(evt.EVT_ESTABLISHED) == []
+
+        child = scp.active_associations[0]
+        assert child.get_handlers(evt.EVT_ACCEPTED) == [(handle, args)]
+
+        assoc.abort()
+
+        while scp.active_associations:
+            time.sleep(0.05)
+
+        scp.shutdown()
+
+        assert len(arguments) == 1
+        assert args == list(arguments[0])
+
+    def test_optional_args_intervention(self):
+        """Test passing optional arguments to the handler."""
+        arguments = []
+        def handle_echo(event, *args):
+            arguments.append(args)
+            return 0x0000
+
+        args = ['a', 1, {'test': 1}]
+
+        self.ae = ae = AE()
+        ae.add_supported_context(VerificationSOPClass)
+        ae.add_requested_context(VerificationSOPClass)
+        handlers = [(evt.EVT_C_ECHO, handle_echo, args)]
+        scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
+
+        assoc = ae.associate('localhost', 11112)
+        assert assoc.is_established
+        assert len(scp.active_associations) == 1
+        assert scp.get_handlers(evt.EVT_C_ECHO) == (handle_echo, args)
+
+        child = scp.active_associations[0]
+        assert child.get_handlers(evt.EVT_C_ECHO) == (handle_echo, args)
+
+        status = assoc.send_c_echo()
+        assert status.Status == 0x0000
+
+        assoc.abort()
+
+        while scp.active_associations:
+            time.sleep(0.05)
+
+        scp.shutdown()
+
+        assert len(arguments) == 1
+        assert args == list(arguments[0])
+
 
 class TestEventHandlingRequestor(object):
     """Test the transport events and handling as acceptor."""
@@ -5540,9 +5611,9 @@ class TestEventHandlingRequestor(object):
 
         assoc.bind(evt.EVT_DIMSE_SENT, dummy)
 
-        assert assoc.get_handlers(evt.EVT_DIMSE_SENT) == [dummy]
+        assert assoc.get_handlers(evt.EVT_DIMSE_SENT) == [(dummy, None)]
         assoc.unbind(evt.EVT_DIMSE_SENT, dummy2)
-        assert assoc.get_handlers(evt.EVT_DIMSE_SENT) == [dummy]
+        assert assoc.get_handlers(evt.EVT_DIMSE_SENT) == [(dummy, None)]
 
         assoc.release()
 
@@ -5564,10 +5635,12 @@ class TestEventHandlingRequestor(object):
         assert len(scp.active_associations) == 1
 
         assoc.bind(evt.EVT_C_ECHO, dummy)
-        assert assoc.get_handlers(evt.EVT_C_ECHO) == dummy
+        assert assoc.get_handlers(evt.EVT_C_ECHO) == (dummy, None)
         assoc.unbind(evt.EVT_C_ECHO, dummy)
-        assert assoc.get_handlers(evt.EVT_C_ECHO) != dummy
-        assert assoc.get_handlers(evt.EVT_C_ECHO) == evt._c_echo_handler
+        assert assoc.get_handlers(evt.EVT_C_ECHO) != (dummy, None)
+        assert assoc.get_handlers(evt.EVT_C_ECHO) == (
+            evt._c_echo_handler, None
+        )
 
         assoc.release()
 
@@ -5588,7 +5661,7 @@ class TestEventHandlingRequestor(object):
         assert assoc.is_established
         assert len(scp.active_associations) == 1
 
-        assert assoc.get_handlers(evt.EVT_ABORTED) == [handle]
+        assert assoc.get_handlers(evt.EVT_ABORTED) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_ACCEPTED) == []
         assert assoc.get_handlers(evt.EVT_ESTABLISHED) == []
         assert assoc.get_handlers(evt.EVT_REJECTED) == []
@@ -5634,7 +5707,7 @@ class TestEventHandlingRequestor(object):
 
         assoc.bind(evt.EVT_ABORTED, handle)
 
-        assert assoc.get_handlers(evt.EVT_ABORTED) == [handle]
+        assert assoc.get_handlers(evt.EVT_ABORTED) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_ACCEPTED) == []
         assert assoc.get_handlers(evt.EVT_ESTABLISHED) == []
         assert assoc.get_handlers(evt.EVT_REJECTED) == []
@@ -5671,7 +5744,7 @@ class TestEventHandlingRequestor(object):
         assert assoc.is_established
         assert len(scp.active_associations) == 1
 
-        assert assoc.get_handlers(evt.EVT_ABORTED) == [handle]
+        assert assoc.get_handlers(evt.EVT_ABORTED) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_ACCEPTED) == []
         assert assoc.get_handlers(evt.EVT_ESTABLISHED) == []
         assert assoc.get_handlers(evt.EVT_REJECTED) == []
@@ -5771,7 +5844,7 @@ class TestEventHandlingRequestor(object):
         assert len(scp.active_associations) == 1
 
         assert assoc.get_handlers(evt.EVT_ABORTED) == []
-        assert assoc.get_handlers(evt.EVT_ACCEPTED) == [handle]
+        assert assoc.get_handlers(evt.EVT_ACCEPTED) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_ESTABLISHED) == []
         assert assoc.get_handlers(evt.EVT_REJECTED) == []
         assert assoc.get_handlers(evt.EVT_RELEASED) == []
@@ -5839,7 +5912,7 @@ class TestEventHandlingRequestor(object):
         assert assoc.get_handlers(evt.EVT_ACCEPTED) == []
         assert assoc.get_handlers(evt.EVT_ESTABLISHED) == []
         assert assoc.get_handlers(evt.EVT_REJECTED) == []
-        assert assoc.get_handlers(evt.EVT_RELEASED) == [handle]
+        assert assoc.get_handlers(evt.EVT_RELEASED) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_REQUESTED) == []
 
         assoc.release()
@@ -5874,7 +5947,7 @@ class TestEventHandlingRequestor(object):
         assert assoc.get_handlers(evt.EVT_RELEASED) == []
 
         assoc.bind(evt.EVT_RELEASED, handle)
-        assert assoc.get_handlers(evt.EVT_RELEASED) == [handle]
+        assert assoc.get_handlers(evt.EVT_RELEASED) == [(handle, None)]
 
         assoc.release()
 
@@ -5906,7 +5979,7 @@ class TestEventHandlingRequestor(object):
         assert assoc.is_established
         assert len(scp.active_associations) == 1
 
-        assert assoc.get_handlers(evt.EVT_RELEASED) == [handle]
+        assert assoc.get_handlers(evt.EVT_RELEASED) == [(handle, None)]
 
         assoc.unbind(evt.EVT_RELEASED, handle)
 
@@ -5997,7 +6070,7 @@ class TestEventHandlingRequestor(object):
 
         assert assoc.get_handlers(evt.EVT_ABORTED) == []
         assert assoc.get_handlers(evt.EVT_ACCEPTED) == []
-        assert assoc.get_handlers(evt.EVT_ESTABLISHED) == [handle]
+        assert assoc.get_handlers(evt.EVT_ESTABLISHED) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_REJECTED) == []
         assert assoc.get_handlers(evt.EVT_RELEASED) == []
         assert assoc.get_handlers(evt.EVT_REQUESTED) == []
@@ -6064,7 +6137,7 @@ class TestEventHandlingRequestor(object):
         assert assoc.get_handlers(evt.EVT_ESTABLISHED) == []
         assert assoc.get_handlers(evt.EVT_REJECTED) == []
         assert assoc.get_handlers(evt.EVT_RELEASED) == []
-        assert assoc.get_handlers(evt.EVT_REQUESTED) == [handle]
+        assert assoc.get_handlers(evt.EVT_REQUESTED) == [(handle, None)]
 
         assoc.release()
 
@@ -6127,7 +6200,7 @@ class TestEventHandlingRequestor(object):
         assert assoc.get_handlers(evt.EVT_ABORTED) == []
         assert assoc.get_handlers(evt.EVT_ACCEPTED) == []
         assert assoc.get_handlers(evt.EVT_ESTABLISHED) == []
-        assert assoc.get_handlers(evt.EVT_REJECTED) == [handle]
+        assert assoc.get_handlers(evt.EVT_REJECTED) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_RELEASED) == []
         assert assoc.get_handlers(evt.EVT_REQUESTED) == []
 
@@ -6163,3 +6236,32 @@ class TestEventHandlingRequestor(object):
             )
             assert msg in caplog.text
             assert "Exception description" in caplog.text
+
+    def test_optional_args(self):
+        """Test passing optional arguments to the handler."""
+        arguments = []
+        def handle(event, *args):
+            arguments.append(args)
+
+        args = ['a', 1, {'test': 1}]
+
+        self.ae = ae = AE()
+        ae.add_supported_context(VerificationSOPClass)
+        ae.add_requested_context(VerificationSOPClass)
+        handlers = [(evt.EVT_ACCEPTED, handle, args)]
+        scp = ae.start_server(('', 11112), block=False)
+
+        assoc = ae.associate('localhost', 11112, evt_handlers=handlers)
+        assert assoc.is_established
+        assert len(scp.active_associations) == 1
+        assert assoc.get_handlers(evt.EVT_ACCEPTED) == [(handle, args)]
+
+        assoc.abort()
+
+        while scp.active_associations:
+            time.sleep(0.05)
+
+        scp.shutdown()
+
+        assert len(arguments) == 1
+        assert args == list(arguments[0])
diff --git a/pynetdicom/tests/test_assoc_user.py b/pynetdicom/tests/test_assoc_user.py
index 2bf60ad87..066b03c8e 100644
--- a/pynetdicom/tests/test_assoc_user.py
+++ b/pynetdicom/tests/test_assoc_user.py
@@ -8,7 +8,7 @@ import pytest
 
 from pynetdicom import (
     AE, VerificationPresentationContexts, PYNETDICOM_IMPLEMENTATION_UID,
-    PYNETDICOM_IMPLEMENTATION_VERSION, build_context
+    PYNETDICOM_IMPLEMENTATION_VERSION, build_context, debug_logger
 )
 from pynetdicom.association import ServiceUser, Association
 from pynetdicom.pdu_primitives import (
@@ -22,9 +22,7 @@ from pynetdicom.sop_class import VerificationSOPClass
 from .dummy_c_scp import DummyVerificationSCP, DummyBaseSCP
 
 
-LOGGER = logging.getLogger('pynetdicom')
-LOGGER.setLevel(logging.CRITICAL)
-#LOGGER.setLevel(logging.DEBUG)
+#debug_logger()
 
 
 class TestServiceUserAcceptor(object):
diff --git a/pynetdicom/tests/test_dimse_provider.py b/pynetdicom/tests/test_dimse_provider.py
index 94803d418..70fcaa312 100644
--- a/pynetdicom/tests/test_dimse_provider.py
+++ b/pynetdicom/tests/test_dimse_provider.py
@@ -242,16 +242,16 @@ class TestEventHandlingAcceptor(object):
         ae.add_requested_context(VerificationSOPClass)
         handlers = [(evt.EVT_DIMSE_SENT, handle)]
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
-        assert scp.get_handlers(evt.EVT_DIMSE_SENT) == [handle]
+        assert scp.get_handlers(evt.EVT_DIMSE_SENT) == [(handle, None)]
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
         assert len(scp.active_associations) == 1
-        assert scp.get_handlers(evt.EVT_DIMSE_SENT) == [handle]
+        assert scp.get_handlers(evt.EVT_DIMSE_SENT) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_DIMSE_SENT) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_DIMSE_SENT) == [handle]
+        assert child.get_handlers(evt.EVT_DIMSE_SENT) == [(handle, None)]
 
         assoc.send_c_echo()
 
@@ -292,11 +292,11 @@ class TestEventHandlingAcceptor(object):
         scp.bind(evt.EVT_DIMSE_SENT, handle)
 
         assert len(scp.active_associations) == 1
-        assert scp.get_handlers(evt.EVT_DIMSE_SENT) == [handle]
+        assert scp.get_handlers(evt.EVT_DIMSE_SENT) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_DIMSE_SENT) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_DIMSE_SENT) == [handle]
+        assert child.get_handlers(evt.EVT_DIMSE_SENT) == [(handle, None)]
 
         assoc.send_c_echo(msg_id=21)
 
@@ -328,13 +328,13 @@ class TestEventHandlingAcceptor(object):
         ae.add_requested_context(VerificationSOPClass)
         handlers = [(evt.EVT_DIMSE_SENT, handle)]
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
-        assert scp.get_handlers(evt.EVT_DIMSE_SENT) == [handle]
+        assert scp.get_handlers(evt.EVT_DIMSE_SENT) == [(handle, None)]
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_DIMSE_SENT) == [handle]
+        assert child.get_handlers(evt.EVT_DIMSE_SENT) == [(handle, None)]
 
         assert assoc.get_handlers(evt.EVT_DIMSE_SENT) == []
 
@@ -407,16 +407,16 @@ class TestEventHandlingAcceptor(object):
         ae.add_requested_context(VerificationSOPClass)
         handlers = [(evt.EVT_DIMSE_RECV, handle)]
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
-        assert scp.get_handlers(evt.EVT_DIMSE_RECV) == [handle]
+        assert scp.get_handlers(evt.EVT_DIMSE_RECV) == [(handle, None)]
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
         assert len(scp.active_associations) == 1
-        assert scp.get_handlers(evt.EVT_DIMSE_RECV) == [handle]
+        assert scp.get_handlers(evt.EVT_DIMSE_RECV) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_DIMSE_RECV) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_DIMSE_RECV) == [handle]
+        assert child.get_handlers(evt.EVT_DIMSE_RECV) == [(handle, None)]
 
         assoc.send_c_echo()
 
@@ -455,11 +455,11 @@ class TestEventHandlingAcceptor(object):
 
         scp.bind(evt.EVT_DIMSE_RECV, handle)
 
-        assert scp.get_handlers(evt.EVT_DIMSE_RECV) == [handle]
+        assert scp.get_handlers(evt.EVT_DIMSE_RECV) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_DIMSE_RECV) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_DIMSE_RECV) == [handle]
+        assert child.get_handlers(evt.EVT_DIMSE_RECV) == [(handle, None)]
 
         assoc.send_c_echo(msg_id=21)
 
@@ -490,14 +490,14 @@ class TestEventHandlingAcceptor(object):
         ae.add_requested_context(VerificationSOPClass)
         handlers = [(evt.EVT_DIMSE_RECV, handle)]
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
-        assert scp.get_handlers(evt.EVT_DIMSE_RECV) == [handle]
+        assert scp.get_handlers(evt.EVT_DIMSE_RECV) == [(handle, None)]
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
         assert len(scp.active_associations) == 1
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_DIMSE_RECV) == [handle]
+        assert child.get_handlers(evt.EVT_DIMSE_RECV) == [(handle, None)]
 
         assoc.send_c_echo(msg_id=12)
 
@@ -610,7 +610,7 @@ class TestEventHandlingRequestor(object):
         assert assoc.is_established
         assert len(scp.active_associations) == 1
         assert scp.get_handlers(evt.EVT_DIMSE_SENT) == []
-        assert assoc.get_handlers(evt.EVT_DIMSE_SENT) == [handle]
+        assert assoc.get_handlers(evt.EVT_DIMSE_SENT) == [(handle, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_DIMSE_SENT) == []
@@ -654,7 +654,7 @@ class TestEventHandlingRequestor(object):
 
         assert len(scp.active_associations) == 1
         assert scp.get_handlers(evt.EVT_DIMSE_SENT) == []
-        assert assoc.get_handlers(evt.EVT_DIMSE_SENT) == [handle]
+        assert assoc.get_handlers(evt.EVT_DIMSE_SENT) == [(handle, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_DIMSE_SENT) == []
@@ -696,7 +696,7 @@ class TestEventHandlingRequestor(object):
         assoc.send_c_echo(msg_id=12)
         assert len(scp.active_associations) == 1
         assert scp.get_handlers(evt.EVT_DIMSE_SENT) == []
-        assert assoc.get_handlers(evt.EVT_DIMSE_SENT) == [handle]
+        assert assoc.get_handlers(evt.EVT_DIMSE_SENT) == [(handle, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_DIMSE_SENT) == []
@@ -763,7 +763,7 @@ class TestEventHandlingRequestor(object):
         assert assoc.is_established
         assert len(scp.active_associations) == 1
         assert scp.get_handlers(evt.EVT_DIMSE_RECV) == []
-        assert assoc.get_handlers(evt.EVT_DIMSE_RECV) == [handle]
+        assert assoc.get_handlers(evt.EVT_DIMSE_RECV) == [(handle, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_DIMSE_RECV) == []
@@ -806,7 +806,7 @@ class TestEventHandlingRequestor(object):
         assoc.bind(evt.EVT_DIMSE_RECV, handle)
 
         assert scp.get_handlers(evt.EVT_DIMSE_RECV) == []
-        assert assoc.get_handlers(evt.EVT_DIMSE_RECV) == [handle]
+        assert assoc.get_handlers(evt.EVT_DIMSE_RECV) == [(handle, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_DIMSE_RECV) == []
@@ -844,7 +844,7 @@ class TestEventHandlingRequestor(object):
 
         assoc = ae.associate('localhost', 11112, evt_handlers=handlers)
         assert assoc.is_established
-        assert assoc.get_handlers(evt.EVT_DIMSE_RECV) == [handle]
+        assert assoc.get_handlers(evt.EVT_DIMSE_RECV) == [(handle, None)]
         assoc.send_c_echo(msg_id=12)
 
         assoc.unbind(evt.EVT_DIMSE_RECV, handle)
diff --git a/pynetdicom/tests/test_fsm.py b/pynetdicom/tests/test_fsm.py
index 2715ad47f..926fa2fc7 100644
--- a/pynetdicom/tests/test_fsm.py
+++ b/pynetdicom/tests/test_fsm.py
@@ -9860,14 +9860,14 @@ class TestEventHandling(object):
         ae.add_requested_context('1.2.840.10008.1.1')
         handlers = [(evt.EVT_FSM_TRANSITION, handle)]
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
-        assert scp.get_handlers(evt.EVT_FSM_TRANSITION) == [handle]
+        assert scp.get_handlers(evt.EVT_FSM_TRANSITION) == [(handle, None)]
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
         assert assoc.get_handlers(evt.EVT_FSM_TRANSITION) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_FSM_TRANSITION) == [handle]
+        assert child.get_handlers(evt.EVT_FSM_TRANSITION) == [(handle, None)]
 
         assoc.release()
         while scp.active_associations:
@@ -9907,9 +9907,9 @@ class TestEventHandling(object):
         assert child.get_handlers(evt.EVT_FSM_TRANSITION) == []
 
         scp.bind(evt.EVT_FSM_TRANSITION, handle)
-        assert scp.get_handlers(evt.EVT_FSM_TRANSITION) == [handle]
+        assert scp.get_handlers(evt.EVT_FSM_TRANSITION) == [(handle, None)]
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_FSM_TRANSITION) == [handle]
+        assert child.get_handlers(evt.EVT_FSM_TRANSITION) == [(handle, None)]
 
         assoc.release()
         while scp.active_associations:
@@ -9937,12 +9937,12 @@ class TestEventHandling(object):
         ae.add_requested_context('1.2.840.10008.1.1')
         handlers = [(evt.EVT_FSM_TRANSITION, handle)]
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
-        assert scp.get_handlers(evt.EVT_FSM_TRANSITION) == [handle]
+        assert scp.get_handlers(evt.EVT_FSM_TRANSITION) == [(handle, None)]
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_FSM_TRANSITION) == [handle]
+        assert child.get_handlers(evt.EVT_FSM_TRANSITION) == [(handle, None)]
 
         scp.unbind(evt.EVT_FSM_TRANSITION, handle)
         assert scp.get_handlers(evt.EVT_FSM_TRANSITION) == []
@@ -9979,7 +9979,7 @@ class TestEventHandling(object):
         scp = ae.start_server(('', 11112), block=False)
 
         assoc = ae.associate('localhost', 11112, evt_handlers=handlers)
-        assert assoc.get_handlers(evt.EVT_FSM_TRANSITION) == [handle]
+        assert assoc.get_handlers(evt.EVT_FSM_TRANSITION) == [(handle, None)]
         assert assoc.is_established
         assert scp.get_handlers(evt.EVT_FSM_TRANSITION) == []
         child = scp.active_associations[0]
@@ -10017,7 +10017,7 @@ class TestEventHandling(object):
         assert assoc.get_handlers(evt.EVT_FSM_TRANSITION) == []
 
         assoc.bind(evt.EVT_FSM_TRANSITION, handle)
-        assert assoc.get_handlers(evt.EVT_FSM_TRANSITION) == [handle]
+        assert assoc.get_handlers(evt.EVT_FSM_TRANSITION) == [(handle, None)]
 
         assert scp.get_handlers(evt.EVT_FSM_TRANSITION) == []
         child = scp.active_associations[0]
@@ -10054,7 +10054,7 @@ class TestEventHandling(object):
 
         assoc = ae.associate('localhost', 11112, evt_handlers=handlers)
         assert assoc.is_established
-        assert assoc.get_handlers(evt.EVT_FSM_TRANSITION) == [handle]
+        assert assoc.get_handlers(evt.EVT_FSM_TRANSITION) == [(handle, None)]
 
         assoc.unbind(evt.EVT_FSM_TRANSITION, handle)
         assert assoc.get_handlers(evt.EVT_FSM_TRANSITION) == []
diff --git a/pynetdicom/tests/test_pdu.py b/pynetdicom/tests/test_pdu.py
index ca64ece17..c23277238 100644
--- a/pynetdicom/tests/test_pdu.py
+++ b/pynetdicom/tests/test_pdu.py
@@ -1396,16 +1396,16 @@ class TestEventHandlingAcceptor(object):
         ae.add_requested_context(VerificationSOPClass)
         handlers = [(evt.EVT_PDU_SENT, handle)]
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
-        assert scp.get_handlers(evt.EVT_PDU_SENT) == [handle]
+        assert scp.get_handlers(evt.EVT_PDU_SENT) == [(handle, None)]
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
         assert len(scp.active_associations) == 1
-        assert scp.get_handlers(evt.EVT_PDU_SENT) == [handle]
+        assert scp.get_handlers(evt.EVT_PDU_SENT) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_PDU_SENT) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_PDU_SENT) == [handle]
+        assert child.get_handlers(evt.EVT_PDU_SENT) == [(handle, None)]
 
         assoc.release()
 
@@ -1443,11 +1443,11 @@ class TestEventHandlingAcceptor(object):
         scp.bind(evt.EVT_PDU_SENT, handle)
 
         assert len(scp.active_associations) == 1
-        assert scp.get_handlers(evt.EVT_PDU_SENT) == [handle]
+        assert scp.get_handlers(evt.EVT_PDU_SENT) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_PDU_SENT) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_PDU_SENT) == [handle]
+        assert child.get_handlers(evt.EVT_PDU_SENT) == [(handle, None)]
 
         assoc.release()
 
@@ -1476,16 +1476,16 @@ class TestEventHandlingAcceptor(object):
         ae.add_requested_context(VerificationSOPClass)
         handlers = [(evt.EVT_PDU_SENT, handle)]
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
-        assert scp.get_handlers(evt.EVT_PDU_SENT) == [handle]
+        assert scp.get_handlers(evt.EVT_PDU_SENT) == [(handle, None)]
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
         assert len(scp.active_associations) == 1
-        assert scp.get_handlers(evt.EVT_PDU_SENT) == [handle]
+        assert scp.get_handlers(evt.EVT_PDU_SENT) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_PDU_SENT) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_PDU_SENT) == [handle]
+        assert child.get_handlers(evt.EVT_PDU_SENT) == [(handle, None)]
 
         scp.unbind(evt.EVT_PDU_SENT, handle)
 
@@ -1538,16 +1538,16 @@ class TestEventHandlingAcceptor(object):
         ae.add_requested_context(VerificationSOPClass)
         handlers = [(evt.EVT_PDU_RECV, handle)]
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
-        assert scp.get_handlers(evt.EVT_PDU_RECV) == [handle]
+        assert scp.get_handlers(evt.EVT_PDU_RECV) == [(handle, None)]
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
         assert len(scp.active_associations) == 1
-        assert scp.get_handlers(evt.EVT_PDU_RECV) == [handle]
+        assert scp.get_handlers(evt.EVT_PDU_RECV) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_PDU_RECV) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_PDU_RECV) == [handle]
+        assert child.get_handlers(evt.EVT_PDU_RECV) == [(handle, None)]
 
         assoc.release()
 
@@ -1583,11 +1583,11 @@ class TestEventHandlingAcceptor(object):
 
         scp.bind(evt.EVT_PDU_RECV, handle)
 
-        assert scp.get_handlers(evt.EVT_PDU_RECV) == [handle]
+        assert scp.get_handlers(evt.EVT_PDU_RECV) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_PDU_RECV) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_PDU_RECV) == [handle]
+        assert child.get_handlers(evt.EVT_PDU_RECV) == [(handle, None)]
 
         assoc.release()
 
@@ -1615,7 +1615,7 @@ class TestEventHandlingAcceptor(object):
         ae.add_requested_context(VerificationSOPClass)
         handlers = [(evt.EVT_PDU_RECV, handle)]
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
-        assert scp.get_handlers(evt.EVT_PDU_RECV) == [handle]
+        assert scp.get_handlers(evt.EVT_PDU_RECV) == [(handle, None)]
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
@@ -1726,7 +1726,7 @@ class TestEventHandlingRequestor(object):
         assert assoc.is_established
         assert len(scp.active_associations) == 1
         assert scp.get_handlers(evt.EVT_PDU_SENT) == []
-        assert assoc.get_handlers(evt.EVT_PDU_SENT) == [handle]
+        assert assoc.get_handlers(evt.EVT_PDU_SENT) == [(handle, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_PDU_SENT) == []
@@ -1799,7 +1799,7 @@ class TestEventHandlingRequestor(object):
 
         assert len(scp.active_associations) == 1
         assert scp.get_handlers(evt.EVT_PDU_SENT) == []
-        assert assoc.get_handlers(evt.EVT_PDU_SENT) == [handle]
+        assert assoc.get_handlers(evt.EVT_PDU_SENT) == [(handle, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_PDU_SENT) == []
@@ -1837,7 +1837,7 @@ class TestEventHandlingRequestor(object):
         assert assoc.is_established
         assert len(scp.active_associations) == 1
         assert scp.get_handlers(evt.EVT_PDU_SENT) == []
-        assert assoc.get_handlers(evt.EVT_PDU_SENT) == [handle]
+        assert assoc.get_handlers(evt.EVT_PDU_SENT) == [(handle, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_PDU_SENT) == []
@@ -1899,7 +1899,7 @@ class TestEventHandlingRequestor(object):
         assert assoc.is_established
         assert len(scp.active_associations) == 1
         assert scp.get_handlers(evt.EVT_PDU_RECV) == []
-        assert assoc.get_handlers(evt.EVT_PDU_RECV) == [handle]
+        assert assoc.get_handlers(evt.EVT_PDU_RECV) == [(handle, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_PDU_RECV) == []
@@ -1969,7 +1969,7 @@ class TestEventHandlingRequestor(object):
         assoc.bind(evt.EVT_PDU_RECV, handle)
 
         assert scp.get_handlers(evt.EVT_PDU_RECV) == []
-        assert assoc.get_handlers(evt.EVT_PDU_RECV) == [handle]
+        assert assoc.get_handlers(evt.EVT_PDU_RECV) == [(handle, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_PDU_RECV) == []
@@ -2004,7 +2004,7 @@ class TestEventHandlingRequestor(object):
 
         assoc = ae.associate('localhost', 11112, evt_handlers=handlers)
         assert assoc.is_established
-        assert assoc.get_handlers(evt.EVT_PDU_RECV) == [handle]
+        assert assoc.get_handlers(evt.EVT_PDU_RECV) == [(handle, None)]
 
         assoc.unbind(evt.EVT_PDU_RECV, handle)
 
diff --git a/pynetdicom/tests/test_transport.py b/pynetdicom/tests/test_transport.py
index e2f0cae3c..2c0a22ffb 100644
--- a/pynetdicom/tests/test_transport.py
+++ b/pynetdicom/tests/test_transport.py
@@ -470,7 +470,7 @@ class TestAssociationServer(object):
         # Multiples allowed
         assert len(scp._handlers[evt.EVT_DATA_SENT]) == 3
         # Only a single handler allowed
-        assert scp._handlers[evt.EVT_C_ECHO] == handle_echo_b
+        assert scp._handlers[evt.EVT_C_ECHO] == (handle_echo_b, None)
 
     def test_get_events(self):
         """Test AssociationServer.get_events()."""
@@ -529,11 +529,11 @@ class TestAssociationServer(object):
         ae.add_supported_context(VerificationSOPClass)
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
 
-        assert scp.get_handlers(evt.EVT_DATA_RECV) == [handle]
-        assert handle in scp.get_handlers(evt.EVT_DATA_SENT)
-        assert handle_echo in scp.get_handlers(evt.EVT_DATA_SENT)
-        assert handle_echo_b in scp.get_handlers(evt.EVT_DATA_SENT)
-        assert scp.get_handlers(evt.EVT_C_ECHO) == handle_echo_b
+        assert scp.get_handlers(evt.EVT_DATA_RECV) == [(handle, None)]
+        assert (handle, None) in scp.get_handlers(evt.EVT_DATA_SENT)
+        assert (handle_echo, None) in scp.get_handlers(evt.EVT_DATA_SENT)
+        assert (handle_echo_b, None) in scp.get_handlers(evt.EVT_DATA_SENT)
+        assert scp.get_handlers(evt.EVT_C_ECHO) == (handle_echo_b, None)
         assert scp.get_handlers(evt.EVT_PDU_SENT) == []
 
         scp.shutdown()
@@ -621,19 +621,19 @@ class TestEventHandlingAcceptor(object):
             block=False,
             evt_handlers=[(evt.EVT_CONN_OPEN, on_conn_open)]
         )
-        assert scp.get_handlers(evt.EVT_CONN_OPEN) == [on_conn_open]
+        assert scp.get_handlers(evt.EVT_CONN_OPEN) == [(on_conn_open, None)]
         assert scp.get_handlers(evt.EVT_CONN_CLOSE) == []
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
         assert len(scp.active_associations) == 1
-        assert scp.get_handlers(evt.EVT_CONN_OPEN) == [on_conn_open]
+        assert scp.get_handlers(evt.EVT_CONN_OPEN) == [(on_conn_open, None)]
         assert scp.get_handlers(evt.EVT_CONN_CLOSE) == []
         assert assoc.get_handlers(evt.EVT_CONN_OPEN) == []
         assert assoc.get_handlers(evt.EVT_CONN_CLOSE) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_CONN_OPEN) == [on_conn_open]
+        assert child.get_handlers(evt.EVT_CONN_OPEN) == [(on_conn_open, None)]
         assert child.get_handlers(evt.EVT_CONN_CLOSE) == []
 
         assert len(triggered_events) == 1
@@ -679,22 +679,22 @@ class TestEventHandlingAcceptor(object):
         # Bind
         scp.bind(evt.EVT_CONN_OPEN, on_conn_open)
 
-        assert scp.get_handlers(evt.EVT_CONN_OPEN) == [on_conn_open]
+        assert scp.get_handlers(evt.EVT_CONN_OPEN) == [(on_conn_open, None)]
         assert scp.get_handlers(evt.EVT_CONN_CLOSE) == []
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_CONN_OPEN) == [on_conn_open]
+        assert child.get_handlers(evt.EVT_CONN_OPEN) == [(on_conn_open, None)]
         assert child.get_handlers(evt.EVT_CONN_CLOSE) == []
 
         assoc2 = ae.associate('localhost', 11112)
         assert assoc2.is_established
         assert len(scp.active_associations) == 2
-        assert scp.get_handlers(evt.EVT_CONN_OPEN) == [on_conn_open]
+        assert scp.get_handlers(evt.EVT_CONN_OPEN) == [(on_conn_open, None)]
         assert scp.get_handlers(evt.EVT_CONN_CLOSE) == []
         assert assoc2.get_handlers(evt.EVT_CONN_OPEN) == []
         assert assoc2.get_handlers(evt.EVT_CONN_CLOSE) == []
 
         child2 = scp.active_associations[1]
-        assert child2.get_handlers(evt.EVT_CONN_OPEN) == [on_conn_open]
+        assert child2.get_handlers(evt.EVT_CONN_OPEN) == [(on_conn_open, None)]
         assert child2.get_handlers(evt.EVT_CONN_CLOSE) == []
 
         assert len(triggered_events) == 1
@@ -724,19 +724,19 @@ class TestEventHandlingAcceptor(object):
             block=False,
             evt_handlers=[(evt.EVT_CONN_OPEN, on_conn_open)]
         )
-        assert scp.get_handlers(evt.EVT_CONN_OPEN) == [on_conn_open]
+        assert scp.get_handlers(evt.EVT_CONN_OPEN) == [(on_conn_open, None)]
         assert scp.get_handlers(evt.EVT_CONN_CLOSE) == []
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
         assert len(scp.active_associations) == 1
-        assert scp.get_handlers(evt.EVT_CONN_OPEN) == [on_conn_open]
+        assert scp.get_handlers(evt.EVT_CONN_OPEN) == [(on_conn_open, None)]
         assert scp.get_handlers(evt.EVT_CONN_CLOSE) == []
         assert assoc.get_handlers(evt.EVT_CONN_OPEN) == []
         assert assoc.get_handlers(evt.EVT_CONN_CLOSE) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_CONN_OPEN) == [on_conn_open]
+        assert child.get_handlers(evt.EVT_CONN_OPEN) == [(on_conn_open, None)]
         assert child.get_handlers(evt.EVT_CONN_CLOSE) == []
 
         assert len(triggered_events) == 1
@@ -799,7 +799,7 @@ class TestEventHandlingAcceptor(object):
         ae.add_requested_context(VerificationSOPClass)
         scp = ae.start_server(('', 11112), block=False)
         scp.bind(evt.EVT_CONN_CLOSE, dummy)
-        assert scp.get_handlers(evt.EVT_CONN_CLOSE) == [dummy]
+        assert scp.get_handlers(evt.EVT_CONN_CLOSE) == [(dummy, None)]
 
         scp.unbind(evt.EVT_CONN_CLOSE, dummy)
         assert scp.get_handlers(evt.EVT_CONN_CLOSE) == []
@@ -851,19 +851,19 @@ class TestEventHandlingAcceptor(object):
             evt_handlers=[(evt.EVT_CONN_CLOSE, on_conn_close)]
         )
         assert scp.get_handlers(evt.EVT_CONN_OPEN) == []
-        assert scp.get_handlers(evt.EVT_CONN_CLOSE) == [on_conn_close]
+        assert scp.get_handlers(evt.EVT_CONN_CLOSE) == [(on_conn_close, None)]
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
         assert len(scp.active_associations) == 1
         assert scp.get_handlers(evt.EVT_CONN_OPEN) == []
-        assert scp.get_handlers(evt.EVT_CONN_CLOSE) == [on_conn_close]
+        assert scp.get_handlers(evt.EVT_CONN_CLOSE) == [(on_conn_close, None)]
         assert assoc.get_handlers(evt.EVT_CONN_OPEN) == []
         assert assoc.get_handlers(evt.EVT_CONN_CLOSE) == []
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_CONN_OPEN) == []
-        assert child.get_handlers(evt.EVT_CONN_CLOSE) == [on_conn_close]
+        assert child.get_handlers(evt.EVT_CONN_CLOSE) == [(on_conn_close, None)]
 
         assoc.release()
 
@@ -918,13 +918,13 @@ class TestEventHandlingAcceptor(object):
         scp.bind(evt.EVT_CONN_CLOSE, on_conn_close)
 
         assert scp.get_handlers(evt.EVT_CONN_OPEN) == []
-        assert scp.get_handlers(evt.EVT_CONN_CLOSE) == [on_conn_close]
+        assert scp.get_handlers(evt.EVT_CONN_CLOSE) == [(on_conn_close, None)]
         assert assoc.get_handlers(evt.EVT_CONN_OPEN) == []
         assert assoc.get_handlers(evt.EVT_CONN_CLOSE) == []
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_CONN_OPEN) == []
-        assert child.get_handlers(evt.EVT_CONN_CLOSE) == [on_conn_close]
+        assert child.get_handlers(evt.EVT_CONN_CLOSE) == [(on_conn_close, None)]
 
         assoc.release()
         assert assoc.is_released
@@ -954,19 +954,19 @@ class TestEventHandlingAcceptor(object):
             evt_handlers=[(evt.EVT_CONN_CLOSE, on_conn_close)]
         )
         assert scp.get_handlers(evt.EVT_CONN_OPEN) == []
-        assert scp.get_handlers(evt.EVT_CONN_CLOSE) == [on_conn_close]
+        assert scp.get_handlers(evt.EVT_CONN_CLOSE) == [(on_conn_close, None)]
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
         assert len(scp.active_associations) == 1
         assert scp.get_handlers(evt.EVT_CONN_OPEN) == []
-        assert scp.get_handlers(evt.EVT_CONN_CLOSE) == [on_conn_close]
+        assert scp.get_handlers(evt.EVT_CONN_CLOSE) == [(on_conn_close, None)]
         assert assoc.get_handlers(evt.EVT_CONN_OPEN) == []
         assert assoc.get_handlers(evt.EVT_CONN_CLOSE) == []
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_CONN_OPEN) == []
-        assert child.get_handlers(evt.EVT_CONN_CLOSE) == [on_conn_close]
+        assert child.get_handlers(evt.EVT_CONN_CLOSE) == [(on_conn_close, None)]
 
         scp.unbind(evt.EVT_CONN_CLOSE, on_conn_close)
         assert scp.get_handlers(evt.EVT_CONN_OPEN) == []
@@ -1022,16 +1022,16 @@ class TestEventHandlingAcceptor(object):
         ae.add_requested_context(VerificationSOPClass)
         handlers = [(evt.EVT_DATA_SENT, handle)]
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
-        assert scp.get_handlers(evt.EVT_DATA_SENT) == [handle]
+        assert scp.get_handlers(evt.EVT_DATA_SENT) == [(handle, None)]
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
         assert len(scp.active_associations) == 1
-        assert scp.get_handlers(evt.EVT_DATA_SENT) == [handle]
+        assert scp.get_handlers(evt.EVT_DATA_SENT) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_DATA_SENT) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_DATA_SENT) == [handle]
+        assert child.get_handlers(evt.EVT_DATA_SENT) == [(handle, None)]
 
         assoc.release()
 
@@ -1070,11 +1070,11 @@ class TestEventHandlingAcceptor(object):
         scp.bind(evt.EVT_DATA_SENT, handle)
 
         assert len(scp.active_associations) == 1
-        assert scp.get_handlers(evt.EVT_DATA_SENT) == [handle]
+        assert scp.get_handlers(evt.EVT_DATA_SENT) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_DATA_SENT) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_DATA_SENT) == [handle]
+        assert child.get_handlers(evt.EVT_DATA_SENT) == [(handle, None)]
 
         assoc.release()
 
@@ -1104,16 +1104,16 @@ class TestEventHandlingAcceptor(object):
         ae.add_requested_context(VerificationSOPClass)
         handlers = [(evt.EVT_DATA_SENT, handle)]
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
-        assert scp.get_handlers(evt.EVT_DATA_SENT) == [handle]
+        assert scp.get_handlers(evt.EVT_DATA_SENT) == [(handle, None)]
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
         assert len(scp.active_associations) == 1
-        assert scp.get_handlers(evt.EVT_DATA_SENT) == [handle]
+        assert scp.get_handlers(evt.EVT_DATA_SENT) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_DATA_SENT) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_DATA_SENT) == [handle]
+        assert child.get_handlers(evt.EVT_DATA_SENT) == [(handle, None)]
 
         scp.unbind(evt.EVT_DATA_SENT, handle)
 
@@ -1168,16 +1168,16 @@ class TestEventHandlingAcceptor(object):
         ae.add_requested_context(VerificationSOPClass)
         handlers = [(evt.EVT_DATA_RECV, handle)]
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
-        assert scp.get_handlers(evt.EVT_DATA_RECV) == [handle]
+        assert scp.get_handlers(evt.EVT_DATA_RECV) == [(handle, None)]
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
         assert len(scp.active_associations) == 1
-        assert scp.get_handlers(evt.EVT_DATA_RECV) == [handle]
+        assert scp.get_handlers(evt.EVT_DATA_RECV) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_DATA_RECV) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_DATA_RECV) == [handle]
+        assert child.get_handlers(evt.EVT_DATA_RECV) == [(handle, None)]
 
         assoc.release()
 
@@ -1214,11 +1214,11 @@ class TestEventHandlingAcceptor(object):
 
         scp.bind(evt.EVT_DATA_RECV, handle)
 
-        assert scp.get_handlers(evt.EVT_DATA_RECV) == [handle]
+        assert scp.get_handlers(evt.EVT_DATA_RECV) == [(handle, None)]
         assert assoc.get_handlers(evt.EVT_DATA_RECV) == []
 
         child = scp.active_associations[0]
-        assert child.get_handlers(evt.EVT_DATA_RECV) == [handle]
+        assert child.get_handlers(evt.EVT_DATA_RECV) == [(handle, None)]
 
         assoc.release()
 
@@ -1247,7 +1247,7 @@ class TestEventHandlingAcceptor(object):
         ae.add_requested_context(VerificationSOPClass)
         handlers = [(evt.EVT_DATA_RECV, handle)]
         scp = ae.start_server(('', 11112), block=False, evt_handlers=handlers)
-        assert scp.get_handlers(evt.EVT_DATA_RECV) == [handle]
+        assert scp.get_handlers(evt.EVT_DATA_RECV) == [(handle, None)]
 
         assoc = ae.associate('localhost', 11112)
         assert assoc.is_established
@@ -1346,7 +1346,7 @@ class TestEventHandlingRequestor(object):
             evt_handlers=[(evt.EVT_CONN_OPEN, on_conn_open)]
         )
         assert assoc.is_established
-        assert assoc.get_handlers(evt.EVT_CONN_OPEN) == [on_conn_open]
+        assert assoc.get_handlers(evt.EVT_CONN_OPEN) == [(on_conn_open, None)]
         assert assoc.get_handlers(evt.EVT_CONN_CLOSE) == []
 
         child = scp.active_associations[0]
@@ -1380,7 +1380,7 @@ class TestEventHandlingRequestor(object):
             evt_handlers=[(evt.EVT_CONN_OPEN, on_conn_open)]
         )
         assert assoc.is_established
-        assert assoc.get_handlers(evt.EVT_CONN_OPEN) == [on_conn_open]
+        assert assoc.get_handlers(evt.EVT_CONN_OPEN) == [(on_conn_open, None)]
         assert assoc.get_handlers(evt.EVT_CONN_CLOSE) == []
 
         assoc.unbind(evt.EVT_CONN_OPEN, on_conn_open)
@@ -1415,7 +1415,7 @@ class TestEventHandlingRequestor(object):
         )
         assert assoc.is_established
         assert assoc.get_handlers(evt.EVT_CONN_OPEN) == []
-        assert assoc.get_handlers(evt.EVT_CONN_CLOSE) == [on_conn_close]
+        assert assoc.get_handlers(evt.EVT_CONN_CLOSE) == [(on_conn_close, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_CONN_OPEN) == []
@@ -1459,7 +1459,7 @@ class TestEventHandlingRequestor(object):
 
         assoc.bind(evt.EVT_CONN_CLOSE, on_conn_close)
         assert assoc.get_handlers(evt.EVT_CONN_OPEN) == []
-        assert assoc.get_handlers(evt.EVT_CONN_CLOSE) == [on_conn_close]
+        assert assoc.get_handlers(evt.EVT_CONN_CLOSE) == [(on_conn_close, None)]
 
         assoc.release()
         while scp.active_associations:
@@ -1490,7 +1490,7 @@ class TestEventHandlingRequestor(object):
         )
         assert assoc.is_established
         assert assoc.get_handlers(evt.EVT_CONN_OPEN) == []
-        assert assoc.get_handlers(evt.EVT_CONN_CLOSE) == [on_conn_close]
+        assert assoc.get_handlers(evt.EVT_CONN_CLOSE) == [(on_conn_close, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_CONN_OPEN) == []
@@ -1545,7 +1545,7 @@ class TestEventHandlingRequestor(object):
         assert assoc.is_established
         assert len(scp.active_associations) == 1
         assert scp.get_handlers(evt.EVT_DATA_SENT) == []
-        assert assoc.get_handlers(evt.EVT_DATA_SENT) == [handle]
+        assert assoc.get_handlers(evt.EVT_DATA_SENT) == [(handle, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_DATA_SENT) == []
@@ -1588,7 +1588,7 @@ class TestEventHandlingRequestor(object):
 
         assert len(scp.active_associations) == 1
         assert scp.get_handlers(evt.EVT_DATA_SENT) == []
-        assert assoc.get_handlers(evt.EVT_DATA_SENT) == [handle]
+        assert assoc.get_handlers(evt.EVT_DATA_SENT) == [(handle, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_DATA_SENT) == []
@@ -1627,7 +1627,7 @@ class TestEventHandlingRequestor(object):
         assert assoc.is_established
         assert len(scp.active_associations) == 1
         assert scp.get_handlers(evt.EVT_DATA_SENT) == []
-        assert assoc.get_handlers(evt.EVT_DATA_SENT) == [handle]
+        assert assoc.get_handlers(evt.EVT_DATA_SENT) == [(handle, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_DATA_SENT) == []
@@ -1661,7 +1661,7 @@ class TestEventHandlingRequestor(object):
         assert assoc.is_established
         assert len(scp.active_associations) == 1
         assert scp.get_handlers(evt.EVT_DATA_RECV) == []
-        assert assoc.get_handlers(evt.EVT_DATA_RECV) == [handle]
+        assert assoc.get_handlers(evt.EVT_DATA_RECV) == [(handle, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_DATA_RECV) == []
@@ -1702,7 +1702,7 @@ class TestEventHandlingRequestor(object):
         assoc.bind(evt.EVT_DATA_RECV, handle)
 
         assert scp.get_handlers(evt.EVT_DATA_RECV) == []
-        assert assoc.get_handlers(evt.EVT_DATA_RECV) == [handle]
+        assert assoc.get_handlers(evt.EVT_DATA_RECV) == [(handle, None)]
 
         child = scp.active_associations[0]
         assert child.get_handlers(evt.EVT_DATA_RECV) == []
@@ -1738,7 +1738,7 @@ class TestEventHandlingRequestor(object):
 
         assoc = ae.associate('localhost', 11112, evt_handlers=handlers)
         assert assoc.is_established
-        assert assoc.get_handlers(evt.EVT_DATA_RECV) == [handle]
+        assert assoc.get_handlers(evt.EVT_DATA_RECV) == [(handle, None)]
 
         assoc.unbind(evt.EVT_DATA_RECV, handle)