+/**
+ * Queue of operations where we can only support a certain
+ * number of concurrent operations of a particular type.
+ */
+struct OperationQueue;
+
+
+/**
+ * The type of operation queue
+ */
+enum OperationQueueType
+{
+ /**
+ * Operation queue which permits a fixed maximum number of operations to be
+ * active at any time
+ */
+ OPERATION_QUEUE_TYPE_FIXED,
+
+ /**
+ * Operation queue which adapts the number of operations to be active based on
+ * the operation completion times of previously executed operation in it
+ */
+ OPERATION_QUEUE_TYPE_ADAPTIVE
+};
+
+
+/**
+ * Create an operation queue.
+ *
+ * @param type the type of operation queue
+ * @param max_active maximum number of operations in this queue that can be
+ * active in parallel at the same time.
+ * @return handle to the queue
+ */
+struct OperationQueue *
+GNUNET_TESTBED_operation_queue_create_ (enum OperationQueueType type,
+ unsigned int max_active);
+
+
+/**
+ * Destroy an operation queue. The queue MUST be empty
+ * at this time.
+ *
+ * @param queue queue to destroy
+ */
+void
+GNUNET_TESTBED_operation_queue_destroy_ (struct OperationQueue *queue);
+
+
+/**
+ * Destroys the operation queue if it is empty. If not empty return GNUNET_NO.
+ *
+ * @param queue the queue to destroy if empty
+ * @return GNUNET_YES if the queue is destroyed. GNUNET_NO if not (because it
+ * is not empty)
+ */
+int
+GNUNET_TESTBED_operation_queue_destroy_empty_ (struct OperationQueue *queue);
+
+
+/**
+ * Function to reset the maximum number of operations in the given queue. If
+ * max_active is lesser than the number of currently active operations, the
+ * active operations are not stopped immediately.
+ *
+ * @param queue the operation queue which has to be modified
+ * @param max_active the new maximum number of active operations
+ */
+void
+GNUNET_TESTBED_operation_queue_reset_max_active_ (struct OperationQueue *queue,
+ unsigned int max_active);
+
+
+/**
+ * Add an operation to a queue. An operation can be in multiple queues at
+ * once. Once the operation is inserted into all the queues
+ * GNUNET_TESTBED_operation_begin_wait_() has to be called to actually start
+ * waiting for the operation to become active.
+ *
+ * @param queue queue to add the operation to
+ * @param op operation to add to the queue
+ * @param nres the number of units of the resources of queue needed by the
+ * operation. Should be greater than 0.
+ */
+void
+GNUNET_TESTBED_operation_queue_insert2_ (struct OperationQueue *queue,
+ struct GNUNET_TESTBED_Operation *op,
+ unsigned int nres);
+
+
+/**
+ * Add an operation to a queue. An operation can be in multiple queues at
+ * once. Once the operation is inserted into all the queues
+ * GNUNET_TESTBED_operation_begin_wait_() has to be called to actually start
+ * waiting for the operation to become active.
+ *
+ * @param queue queue to add the operation to
+ * @param op operation to add to the queue
+ */
+void
+GNUNET_TESTBED_operation_queue_insert_ (struct OperationQueue *queue,
+ struct GNUNET_TESTBED_Operation *op);
+
+
+/**
+ * Marks the given operation as waiting on the queues. Once all queues permit
+ * the operation to become active, the operation will be activated. The actual
+ * activation will occur in a separate task (thus allowing multiple queue
+ * insertions to be made without having the first one instantly trigger the
+ * operation if the first queue has sufficient resources).
+ *
+ * @param op the operation to marks as waiting
+ */
+void
+GNUNET_TESTBED_operation_begin_wait_ (struct GNUNET_TESTBED_Operation *op);
+
+
+/**
+ * Function to call to start an operation once all
+ * queues the operation is part of declare that the
+ * operation can be activated.
+ *
+ * @param cls the closure from GNUNET_TESTBED_operation_create_()
+ */
+typedef void (*OperationStart) (void *cls);
+
+
+/**
+ * Function to call to cancel an operation (release all associated
+ * resources). This can be because of a call to
+ * "GNUNET_TESTBED_operation_cancel" (before the operation generated
+ * an event) or AFTER the operation generated an event due to a call
+ * to "GNUNET_TESTBED_operation_done". Thus it is not guaranteed that
+ * a callback to the 'OperationStart' preceeds the call to
+ * 'OperationRelease'. Implementations of this function are expected
+ * to clean up whatever state is in 'cls' and release all resources
+ * associated with the operation.
+ *
+ * @param cls the closure from GNUNET_TESTBED_operation_create_()
+ */
+typedef void (*OperationRelease) (void *cls);
+
+
+/**
+ * Create an 'operation' to be performed.
+ *
+ * @param cls closure for the callbacks
+ * @param start function to call to start the operation
+ * @param release function to call to close down the operation
+ * @return handle to the operation
+ */
+struct GNUNET_TESTBED_Operation *
+GNUNET_TESTBED_operation_create_ (void *cls, OperationStart start,
+ OperationRelease release);
+
+
+/**
+ * An operation is 'done' (was cancelled or finished); remove
+ * it from the queues and release associated resources.
+ *
+ * @param op operation that finished
+ */
+void
+GNUNET_TESTBED_operation_release_ (struct GNUNET_TESTBED_Operation *op);
+
+
+/**
+ * Marks an active operation as inactive - the operation will be kept in a
+ * ready-to-be-released state and continues to hold resources until another
+ * operation contents for them.
+ *
+ * @param op the operation to be marked as inactive. The operation start
+ * callback should have been called before for this operation to mark
+ * it as inactive.
+ */
+void
+GNUNET_TESTBED_operation_inactivate_ (struct GNUNET_TESTBED_Operation *op);
+
+
+/**
+ * Marks and inactive operation as active. This fuction should be called to
+ * ensure that the oprelease callback will not be called until it is either
+ * marked as inactive or released.
+ *
+ * @param op the operation to be marked as active
+ */
+void
+GNUNET_TESTBED_operation_activate_ (struct GNUNET_TESTBED_Operation *op);
+
+
+/**
+ * Marks an operation as failed
+ *
+ * @param op the operation to be marked as failed
+ */
+void
+GNUNET_TESTBED_operation_mark_failed (struct GNUNET_TESTBED_Operation *op);
+
+