diff --git a/commands/core/core.drush.inc b/commands/core/core.drush.inc
index 9072410..be6227d 100644
--- a/commands/core/core.drush.inc
+++ b/commands/core/core.drush.inc
@@ -178,6 +178,7 @@ function core_drush_command() {
       'exclude-paths' => 'List of paths to exclude, seperated by : (Unix-based systems) or ; (Windows).',
       'include-paths' => 'List of paths to include, seperated by : (Unix-based systems) or ; (Windows).',
     ),
+    'allow-additional-options' => TRUE,
     'examples' => array(
       'drush rsync @dev @stage' => 'Rsync Drupal root from dev to stage (one of which must be local).',
       'drush rsync ./ @stage:%files/img' => 'Rsync all files in the current directory to the \'img\' directory in the file storage folder on stage.',
diff --git a/commands/core/help.drush.inc b/commands/core/help.drush.inc
index 6474e44..549036b 100644
--- a/commands/core/help.drush.inc
+++ b/commands/core/help.drush.inc
@@ -28,13 +28,7 @@ function drush_show_help($commandstring) {
  *   A fully loaded $command array.
  */
 function drush_print_help($command) {
-  // Merge in engine specific help.
-  foreach ($command['engines'] as $type => $description) {
-    $all_engines = drush_get_engines($type);
-    foreach ($all_engines as $name => $engine) {
-      $command = array_merge_recursive($command, $engine);
-    }
-  }
+  _drush_merge_engine_data($command);
 
   if (!$help = drush_command_invoke_all('drush_help', 'drush:'. $command['command'])) {
     $help = array($command['description']);
diff --git a/includes/command.inc b/includes/command.inc
index 6b5e256..d9b970c 100644
--- a/includes/command.inc
+++ b/includes/command.inc
@@ -198,6 +198,12 @@ function drush_dispatch($command, $arguments = array()) {
     // Add command-specific options, if applicable
     drush_command_default_options($command);
 
+    // Test to see if any of the options in the 'cli' context
+    // are not represented in the command structure.
+    if (_drush_check_cli_options($command) === FALSE) {
+      return FALSE;
+    }
+
     // Print a warning if someone tries to use a deprecated alias.
     if (isset($command['deprecated'])) {
       drush_log(dt('Warning: The command name "!deprecated" is deprecated.  Please use a recommended form instead (!recommended).', array('!deprecated' => $command['deprecated-name'], '!recommended' => implode(',', array_merge(array($command['command']), $command['aliases'])))), 'warning');
@@ -213,6 +219,88 @@ function drush_dispatch($command, $arguments = array()) {
 }
 
 /**
+ * Add command structure info from each engine back into the command.
+ */
+function _drush_merge_engine_data(&$command) {
+  // Merge in engine specific help.
+  foreach ($command['engines'] as $type => $description) {
+    $all_engines = drush_get_engines($type);
+    foreach ($all_engines as $name => $engine) {
+      $command = array_merge_recursive($command, $engine);
+    }
+  }
+}
+
+/**
+ * Fail with an error if the user specified options on the
+ * command line that are not documented in the current command
+ * record.
+ */
+function _drush_check_cli_options($command) {
+  _drush_merge_engine_data($command);
+
+  // Start out with just the options in the current command record.
+  $options = _drush_get_command_options($command);
+  // Skip all tests if the command is marked to allow anything.
+  if ($command['allow-additional-options'] === TRUE) {
+    return TRUE;
+  }
+  // If 'allow-additional-options' contains a list of command names,
+  // then union together all of the options from all of the commands.
+  if (is_array($command['allow-additional-options'])) {
+    $implemented = drush_get_commands();
+    foreach ($command['allow-additional-options'] as $subcommand_name) {
+      if (array_key_exists($subcommand_name, $implemented)) {
+	$options = array_merge($options, _drush_get_command_options($implemented[$subcommand_name])); 
+      }
+    }
+  }
+  // Also add in global options
+  $options = array_merge($options, drush_get_global_options());
+
+  // Now we will figure out which options in the cli context
+  // are not represented in our options list.
+  $cli_options = array_keys(drush_get_context('cli'));
+  $allowed_options = _drush_flatten_options($options);
+  $disallowed_options = array_diff($cli_options, $allowed_options);
+  if (!empty($disallowed_options)) {
+    return drush_set_error(dt("Unknown options: @options", array('@options' => implode(', ', $disallowed_options))));
+  }
+  return TRUE;
+}
+
+/**
+ * Return the list of all of the options for the given
+ * command record by merging the 'options' and 'sub-options'
+ * records.
+ */
+function _drush_get_command_options($command) {
+  $options = $command['options'];
+  foreach ($command['sub-options'] as $group => $suboptions) {
+    $options = array_merge($options, $suboptions);
+  }
+  return $options;
+}
+
+/**
+ * Return the array keys of $options, plus any 'short-form'
+ * representations that may appear in the option's value.
+ */
+function _drush_flatten_options($options) {
+  $flattened_options = array();
+
+  foreach($options as $key => $value) {
+    $flattened_options[] = $key;
+    if (is_array($value)) {
+      if (array_key_exists('short-form', $value)) {
+	$flattened_options[] = $value['short-form'];
+      }
+    }
+  }
+  return $flattened_options;
+}
+
+/**
  * Invoke a command in a new process, targeting the site specified by
  * the provided site alias record.
  *
@@ -599,6 +687,8 @@ function drush_command_defaults($key, $commandfile, $path) {
     ),
     'arguments' => array(),
     'options' => array(),
+    'sub-options' => array(),
+    'allow-additional-options' => FALSE,
     'examples' => array(),
     'aliases' => array(),
     'deprecated-aliases' => array(),
