diff --git a/demos/MMk_shutdown.rb b/demos/MMk_shutdown.rb
new file mode 100644
index 0000000000000000000000000000000000000000..78c24487c2ccf5555b6dacf48014174f15bc183e
--- /dev/null
+++ b/demos/MMk_shutdown.rb
@@ -0,0 +1,80 @@
+#!/usr/bin/env ruby
+
+require_relative '../lib/simplekit'
+
+# Demonstration model of an M/M/k queueing system.  There are k servers
+# and both the arrival and service processes are memoryless (exponential).
+class MMk
+  include SimpleKit
+
+  # Constructor - initializes the model parameters.
+  # param: arrival_rate - The rate at which customers arrive to the system.
+  # param: service_rate - The rate at which individual servers serve.
+  # param: max_servers - The total number of servers in the system.
+  def initialize(arrival_rate, service_rate, max_servers)
+    @arrival_rate = arrival_rate
+    @service_rate = service_rate
+    @max_servers = max_servers
+  end
+
+  # Initialize the model state and schedule any necessary events.
+  # Note that this particular model will terminate based on
+  # time by scheduling a halt 100 time units in the future.
+  def init
+    @num_available_servers = @max_servers
+    @q_length = 0
+    schedule(:arrival, 0.0)
+    schedule(:close_doors, 100.0)
+    dump_state('init')
+  end
+
+  # An arrival event increments the queue length, schedules the next
+  # arrival, and schedules a begin_service event if a server is available.
+  def arrival
+    @q_length += 1
+    schedule(:arrival, exponential(@arrival_rate))
+    schedule(:begin_service, 0.0) if @num_available_servers > 0
+    dump_state('arrival')
+  end
+
+  # Start service for the first customer in line, removing that
+  # customer from the queue and utilizing one of the available servers.
+  # An end_service will be scheduled.
+  def begin_service
+    @q_length -= 1
+    @num_available_servers -= 1
+    schedule(:end_service, exponential(@service_rate))
+    dump_state('begin svc')
+  end
+
+  # Frees up an available server, and schedules a begin_service if
+  # anybody is waiting in line.
+  def end_service
+    @num_available_servers += 1
+    schedule(:begin_service, 0.0) if @q_length > 0
+    dump_state('end svc')
+  end
+
+  def close_doors
+    cancel(:arrival)
+  end
+
+  # Exponential random variate generator.
+  # param: rate - The rate (= 1 / mean) of the distribution.
+  # returns: A realization of the specified distribution.
+  def exponential(rate)
+    -Math.log(rand) / rate
+  end
+
+  # A report mechanism which dumps the time, current event, and values
+  # of the state variables to the console.
+  # param: event - The name of the event which invoked this method.
+  def dump_state(event)
+    printf "Time: %8.3f\t%10s - Q: %d\tServers Available: %d\n",
+           model_time, event, @q_length, @num_available_servers
+  end
+end
+
+# Instantiate an MMk object with a particular parameterization and run it.
+srand 7_654_321
+MMk.new(4.5, 1.0, 5).run
diff --git a/demos/MyModelArgs.rb b/demos/MyModelArgs.rb
index d75ff655a4bbb07f6a8e5a950e03466923e56f07..db78ae0dafacd36f44dac3bd12eddd2a9a9287af 100644
--- a/demos/MyModelArgs.rb
+++ b/demos/MyModelArgs.rb
@@ -12,9 +12,9 @@ class MyModel
 
   def increment(n:, char:)
     @x += n
-    schedule(:increment, 2.0 * rand(2), n: @x, char: char - 1)
+    schedule(:increment, 2.0 * rand(2), n: @x, char: char - 1, priority: 3)
     printf "%f, %f, %c\n", model_time, @x, char
-    schedule(:halt, 0.0) if model_time > 10
+    cancel_all :increment if model_time > 10
   end
 end
 
diff --git a/lib/simplekit.rb b/lib/simplekit.rb
index 96b5fd1afcc8b8ec342435442b12dfbf6f454314..0826328d8ad988147a44b8bc6d017431ea5776b7 100644
--- a/lib/simplekit.rb
+++ b/lib/simplekit.rb
@@ -9,7 +9,9 @@ require_relative 'priority_queue'
 module SimpleKit
   # The set of module methods to be passed to the EventScheduler
   # if not found in the model class.
-  DELEGATED_METHODS = [:model_time, :schedule, :halt].freeze
+  DELEGATED_METHODS = %i[
+    model_time schedule cancel cancel_all halt
+  ].freeze
 
   # Run your model by creating a new +EventScheduler+ and invoking its
   # +run+ method.
@@ -21,11 +23,7 @@ module SimpleKit
   # If a method doesn't exist in the model class, try to delegate it
   # to +EventScheduler+.
   def method_missing(name, *args)
-    if DELEGATED_METHODS.include?(name)
-      @my_sim.send(name, *args)
-    else
-      super
-    end
+    DELEGATED_METHODS.include?(name) ? @my_sim.send(name, *args) : super
   end
 
   # Class +EventScheduler+ provides the computation engine for a
@@ -43,6 +41,7 @@ module SimpleKit
     def initialize(the_model)
       @user_model = the_model
       @event_list = PriorityQueue.new
+      @cancel_set = {}
     end
 
     # Add an event to the pending events list.
@@ -55,7 +54,22 @@ module SimpleKit
     #     at invocation time.
     def schedule(event, delay, **args)
       raise 'Model scheduled event with negative delay.' if delay < 0
-      @event_list.push EventNotice.new(event, @model_time, delay, **args)
+      @event_list.push EventNotice.new(event, @model_time, delay, args)
+    end
+
+    def cancel(event, **args)
+      @cancel_set[event] = args
+    end
+
+    def cancel_all(event)
+      if event
+        PriorityQueue.new.tap do |pq|
+          while (event_notice = @event_list.pop)
+            pq.push event_notice unless event_notice.event == event
+          end
+          @event_list = pq
+        end
+      end
     end
 
     # Start execution of a model. The simulation +model_time+ is initialized
@@ -67,11 +81,16 @@ module SimpleKit
       @model_time = 0.0
       @user_model.init
       while (current_event = @event_list.pop)
+        e = current_event.event
+        if @cancel_set.key? e
+          @cancel_set.delete e # if @cancel_set[e].empty?
+          next
+        end
         @model_time = current_event.time
         if current_event.args.empty?
           @user_model.send(current_event.event)
         else
-          @user_model.send(current_event.event, **current_event.args)
+          @user_model.send(current_event.event, current_event.args)
         end
       end
     end
@@ -83,21 +102,26 @@ module SimpleKit
     end
   end
 
+  private
+
   # This is a private helper class for the EventScheduler class.
   # Users should never try to access this directly.
-  private class EventNotice
-    attr_reader :event, :time, :time_stamp, :args
+  class EventNotice
+    attr_reader :event, :time, :time_stamp, :priority, :args
 
     def initialize(event, time, delay, args)
       @event = event
       @time_stamp = time
       @time = time + delay
       @args = args
+      @priority = (@args && @args.key?(:priority)) ? @args.delete(:priority) : 10
     end
 
     include Comparable
     def <=>(other)
-      time <=> other.time
+      (time <=> other.time).tap do |outcome|
+        return priority <=> other.priority if outcome == 0
+      end
     end
   end
 end