Index: src/AEInput/SystemInput.py
===================================================================
--- src/AEInput/SystemInput.py	(revision 709)
+++ src/AEInput/SystemInput.py	(working copy)
@@ -70,23 +70,30 @@
   def addModifier(self, code):
     ''' 
     Adds an action code to the modifiers dictionary to identify it as a modifier
-    for other actions.
+    for other actions.  
     
     @param code: Action code to register as a modifier
     @type code: integer
     '''
-    self.modifiers[code] = None
+    try:
+      self.modifiers[code] += 1
+    except KeyError:
+      self.modifiers[code] = 1
     
   def removeModifier(self, code):
     '''
-    Removes an action code from the modifiers dictionary.
+    Removes an action code from the modifiers dictionary if it is no longer
+    in use.  Otherwise, it decrements the reference count.
     
     @param code: Action code to unregister as a modifier
     @type code: integer
-    @raise KeyError: When the action code to remove is not registered as a 
-      modifier
     '''
-    del self.modifiers[code]
+    try:
+      self.modifiers[code] -= 1
+      if self.modifiers[code] <= 0:
+        del self.modifiers[code]
+    except:
+      pass
     
   def clearModifiers(self):
     '''
Index: src/Perk.py
===================================================================
--- src/Perk.py	(revision 709)
+++ src/Perk.py	(working copy)
@@ -110,6 +110,7 @@
     self.before_chains = {}
     self.after_chains = {}
     self.around_chains = {}
+    self.registered_modifiers = {}
 
     # instantiate an instance of the STATE class; it may be filled with data
     # when preInit is called with state already persisted to disk
@@ -149,11 +150,18 @@
     for tasks in (self.named_tasks.values(), self.keyed_tasks.values()):
       map(Task.Task.close, tasks)
       map(Task.Task.postClose, tasks)
+      
+    # unregister modifiers
+    for dev, codes in self.registered_modifiers.iteritems():
+      for code in codes:
+        self.removeInputModifiers(dev, code)
+      
     # throw away all references
     self.named_tasks = {}
     self.keyed_tasks = {}
     self.event_tasks = {}
     self.commands = {}
+    self.registered_modifiers = {}
     
   def setIdealOutput(self, *capabilities):
     '''
Index: src/Task/Tools/Input.py
===================================================================
--- src/Task/Tools/Input.py	(revision 709)
+++ src/Task/Tools/Input.py	(working copy)
@@ -64,7 +64,29 @@
     except AttributeError:
       return
     map(func, codes)
-
+    # add modifiers to device specific list for later removal
+    try:
+      self.registered_modifiers[dev].extend(codes)
+    except KeyError:
+      self.registered_modifiers[dev] = list(codes)
+    
+  def removeInputModifiers(self, dev, *codes):
+    '''
+    Removes the given device code as a modifier on the named L{AEInput} device.
+    If the device doesn't support modifiers, ignores the error since it's a 
+    non-critical operation.
+    
+    @param dev: Reference to an input device
+    @type dev: L{AEInput}
+    @param codes: Action codes to add as modifiers
+    @type codes: integer
+    '''
+    try:
+      func = dev.removeModifier 
+    except AttributeError:
+      return
+    map(func, codes)
+    
   def registerCommand(self, dev, task_ident, propogate, *codes):
     '''
     Registers a L{Task} in this L{Perk} to be executed in response to an 
