diff --git a/docs/source/pavement.rst b/docs/source/pavement.rst
index cf09246..9dae827 100644
--- a/docs/source/pavement.rst
+++ b/docs/source/pavement.rst
@@ -203,6 +203,22 @@ For sharing, following must be fullfilled:
 
 Otherwise, ``PavementError`` is raised.
 
+You can combine both ``@consume_args`` and ``@cmdopts`` together::
+
+    @task
+    @cmdopts([
+        ('username=', 'u', 'Username to use when logging in to the servers')
+    ])
+    @consume_args
+    def exec(options):
+        pass
+
+
+* ``paver exec -u root`` will result in ``options.username = 'root', options.args = []``
+* ``paver exec -u root production`` will result in ``options.username = 'root', options.args = ['production']``
+* ``paver exec production -u root`` will result in ``options.args = ['production', '-u', 'root']`` with no ``options.username`` attribute.
+* ``paver exec -u root production -u other`` will result in ``options.username = 'root', options.args = ['production', '-u', 'other']``
+
 Hiding tasks
 ---------------
 
diff --git a/paver/tasks.py b/paver/tasks.py
index 7300969..09f7d4e 100644
--- a/paver/tasks.py
+++ b/paver/tasks.py
@@ -741,7 +741,8 @@ def _parse_command_line(args):
     if not isinstance(task, Task):
         raise BuildFailure("%s is not a Task" % taskname)
 
-    if task.consume_args != float('inf'):
+    if task.user_options or task.consume_args != float('inf'):
+        # backwards compatibility around mixing of @cmdopts & @consume_args
         args = task.parse_args(args)
     if task.consume_args > 0:
         args = _consume_nargs(task, args)

diff --git a/paver/tests/test_tasks.py b/paver/tests/test_tasks.py
index 7b971f2..1df7c4e 100644
--- a/paver/tests/test_tasks.py
+++ b/paver/tests/test_tasks.py
@@ -404,6 +404,74 @@ def test_consume_args():
     tasks._process_commands("t3 -v 1".split())
     assert t3.called
 
+def test_consume_args_and_options():
+    @tasks.task
+    @tasks.cmdopts([
+        ("foo=", "f", "Help for foo")
+    ])
+    @tasks.consume_args
+    def t1(options):
+        assert options.foo == "1"
+        assert options.t1.foo == "1"
+        assert options.args == ['abc', 'def']
+
+    environment = _set_environment(t1=t1)
+    tasks._process_commands([
+        't1', '--foo', '1', 'abc', 'def',
+    ])
+    assert t1.called
+
+def test_consume_args_and_options_2():
+    @tasks.task
+    @tasks.cmdopts([
+        ("foo=", "f", "Help for foo")
+    ])
+    @tasks.consume_args
+    def t1(options):
+        assert not hasattr(options, 'foo')
+        assert not hasattr(options.t1, 'foo')
+        assert options.args == ['abc', 'def', '--foo', '1']
+
+    environment = _set_environment(t1=t1)
+    tasks._process_commands([
+        't1', 'abc', 'def', '--foo', '1',
+    ])
+    assert t1.called
+
+def test_consume_args_and_options_3():
+    @tasks.task
+    @tasks.cmdopts([
+        ("foo=", "f", "Help for foo")
+    ])
+    @tasks.consume_args
+    def t1(options):
+        assert options.foo == "1"
+        assert options.t1.foo == "1"
+        assert options.args == []
+
+    environment = _set_environment(t1=t1)
+    tasks._process_commands([
+        't1', '--foo', '1',
+    ])
+    assert t1.called
+
+def test_consume_args_and_options_conflict():
+    @tasks.task
+    @tasks.cmdopts([
+        ("foo=", "f", "Help for foo")
+    ])
+    @tasks.consume_args
+    def t1(options):
+        assert options.foo == "1"
+        assert options.t1.foo == "1"
+        assert options.args == ['abc', 'def', '--foo', '2']
+
+    environment = _set_environment(t1=t1)
+    tasks._process_commands([
+        't1', '--foo', '1', 'abc', 'def', '--foo', '2',
+    ])
+    assert t1.called
+
 def test_consume_nargs():
     # consume all args on first task
     @tasks.task

Define behavior with both @cmdopts and @consume_args set
Latter now overwrites former, which is not what one generally wants.

Parse for cmdopts and remove it from args. 

paver/tests/test_tasks.py::test_consume_args_and_options paver/tests/test_tasks.py::test_consume_args_and_options_2 paver/tests/test_tasks.py::test_consume_args_and_options_3 paver/tests/test_tasks.py::test_consume_args_and_options_conflict
paver/tests/test_tasks.py::test_basic_dependencies paver/tests/test_tasks.py::test_longname_resolution_in_dependencies paver/tests/test_tasks.py::test_chained_dependencies paver/tests/test_tasks.py::test_backwards_compatible_needs paver/tests/test_tasks.py::test_tasks_dont_repeat paver/tests/test_tasks.py::test_basic_command_line paver/tests/test_tasks.py::test_list_tasks paver/tests/test_tasks.py::test_environment_insertion paver/tests/test_tasks.py::test_add_options_to_environment paver/tests/test_tasks.py::test_shortname_access paver/tests/test_tasks.py::test_longname_access paver/tests/test_tasks.py::test_task_command_line_options paver/tests/test_tasks.py::test_setting_of_options_with_equals paver/tests/test_tasks.py::test_options_inherited_via_needs paver/tests/test_tasks.py::test_options_inherited_via_needs_even_from_grandparents paver/tests/test_tasks.py::test_options_shouldnt_overlap paver/tests/test_tasks.py::test_options_shouldnt_overlap_when_bad_task_specified paver/tests/test_tasks.py::test_options_may_overlap_if_explicitly_allowed paver/tests/test_tasks.py::test_exactly_same_parameters_must_be_specified_in_order_to_allow_sharing paver/tests/test_tasks.py::test_dest_parameter_should_map_opt_to_property paver/tests/test_tasks.py::test_dotted_options paver/tests/test_tasks.py::test_dry_run paver/tests/test_tasks.py::test_consume_args paver/tests/test_tasks.py::test_consume_nargs paver/tests/test_tasks.py::test_consume_nargs_and_options paver/tests/test_tasks.py::test_optional_args_in_tasks paver/tests/test_tasks.py::test_debug_logging paver/tests/test_tasks.py::test_base_logging paver/tests/test_tasks.py::test_error_show_up_no_matter_what paver/tests/test_tasks.py::test_all_messages_for_a_task_are_captured paver/tests/test_tasks.py::test_messages_with_formatting_and_no_args_still_work paver/tests/test_tasks.py::test_alternate_pavement_option paver/tests/test_tasks.py::test_captured_output_shows_up_on_exception paver/tests/test_tasks.py::test_calling_subpavement paver/tests/test_tasks.py::test_task_finders paver/tests/test_tasks.py::test_calling_a_function_rather_than_task paver/tests/test_tasks.py::test_depending_on_a_function_rather_than_task paver/tests/test_tasks.py::test_description_retrieval_trial paver/tests/test_tasks.py::test_description_empty_without_docstring paver/tests/test_tasks.py::test_description_retrieval_first_sentence paver/tests/test_tasks.py::test_description_retrieval_first_sentence_even_with_version_numbers paver/tests/test_tasks.py::test_auto_task_is_not_run_with_noauto paver/tests/test_tasks.py::test_auto_task_is_run_when_present paver/tests/test_tasks.py::test_task_can_be_called_repeatedly paver/tests/test_tasks.py::test_options_passed_to_task paver/tests/test_tasks.py::test_calling_task_with_option_arguments paver/tests/test_tasks.py::test_calling_task_with_arguments_do_not_overwrite_it_for_other_tasks paver/tests/test_tasks.py::test_options_might_be_provided_if_task_might_be_called paver/tests/test_tasks.py::test_calling_task_with_arguments paver/tests/test_tasks.py::test_calling_task_with_empty_arguments paver/tests/test_tasks.py::test_calling_nonconsuming_task_with_arguments paver/tests/test_tasks.py::test_options_may_overlap_between_multiple_tasks_even_when_specified_in_reverse_order paver/tests/test_tasks.py::test_options_might_be_shared_both_way paver/tests/test_tasks.py::test_paver_doesnt_crash_on_task_function_with_annotations