--- ../../../python-bugzilla-up_tests/python-bugzilla-1.0.0/bin/bugzilla	2014-03-25 22:07:36.000000000 +0100
+++ bin/bugzilla	2014-05-20 15:40:28.427255720 +0200
@@ -37,7 +37,8 @@
 default_bz = 'https://bugzilla.redhat.com/xmlrpc.cgi'
 
 _is_unittest = bool(os.getenv("__BUGZILLA_UNITTEST"))
-cmdlist = ['login', 'new', 'query', 'modify', 'attach', 'info']
+cmdlist = ['login', 'new', 'new_component', 'query', 'modify',
+           'modify_component', 'attach', 'info']
 format_field_re = re.compile("%{([a-z0-9_]+)(?::([^}]*))?}")
 
 log = bugzilla.log
@@ -163,6 +164,15 @@
                 metavar='KEYWORD[, KEYWORD, ...]', action="append",
                 help="Set specified keywords on new bugzilla")
 
+    elif action == 'new_component':
+        p.set_usage("%prog new_component [options] PRODUCT COMPONENT DESCRIPTION DEFAULT_ASSIGNEE")
+        p.set_description("Create a new component.")
+        p.add_option('--default_qa_contact',
+                     help="OPTIONAL")
+        p.add_option('--default_cc',
+                     help="OPTIONAL\nis list of email addresses "
+                          "separated by comma.")
+
     elif action == 'query':
         p.set_description("List bug reports that match the given criteria.")
         # General bug metadata
@@ -379,6 +389,17 @@
         p.add_option_group(tgrp)
 
 
+    elif action == 'modify_component':
+        p.set_usage("%prog modify_component [options] PRODUCT COMPONENT [COMPONENT...]")
+        p.set_description("Modify one or more components.")
+        p.add_option('--default_assignee',
+                     help="OPTIONAL")
+        p.add_option('--default_qa_contact',
+                     help="OPTIONAL")
+        p.add_option('--default_cc',
+                     help="OPTIONAL\nis list of email addresses "
+                          "separated by comma.")
+
     elif action == 'attach':
         p.set_usage('''
   %prog attach --file=FILE --desc=DESC [--type=TYPE] BUGID [BUGID...]
@@ -888,6 +909,30 @@
     return [b]
 
 
+def _do_new_component(bz, parser, opt, args):
+    data = {'product': args[0],
+            'component': args[1],
+            'description': args[2],
+            'default_assignee': args[3]}
+
+    allopts = ["default_qa_contact", "default_cc"]
+    for key in allopts:
+        if not hasattr(opt, key) or getattr(opt, key) is None:
+            continue
+
+        data[key] = getattr(opt, key)
+
+    if "default_cc" in data:
+        data["default_cc"] = data["default_cc"].split(",")
+
+    added = bz.addcomponent(data)
+    if not added['id']:
+        print("Component wasn't added.")
+        sys.exit(1)
+    else:
+        print("Component added.")
+
+
 def _do_modify(bz, parser, opt, args):
     bugid_list = [bugid for a in args for bugid in a.split(',')]
 
@@ -1001,6 +1046,28 @@
                 bug.deltag(tag, which=wbtype)
 
 
+def _do_modify_component(bz, parser, opt, args):
+    allopts = ["default_assignee", "default_qa_contact", "default_cc"]
+
+    common_data = {}
+    for key in allopts:
+        if not hasattr(opt, key) or getattr(opt, key) is None:
+            continue
+        common_data[key] = getattr(opt, key)
+    if "default_cc" in data:
+        data["default_cc"] = data["default_cc"].split(",")
+
+    for component in args[1:]:
+        data = {'product': args[0],
+                'component': component}
+        data.update(common_data)
+        updates = bz.editcomponent(data)
+        if not updates['components_updates']:
+            print("Component '%s' wasn't updated." % component)
+        else:
+            print("Component '%s' updated." % component)
+
+
 def _do_get_attach(bz, opt, parser, args):
     if args:
         parser.error("Extra args '%s' not used for getting attachments" %
@@ -1182,6 +1249,13 @@
         if opt.test_return_result:
             return buglist
 
+    elif action == 'new_component':
+        if len(args) < 4:
+            parser.error('Not enough arguments to specify component to modify')
+        elif len(args) > 4:
+            parser.error("Too many arguments for adding new component")
+        _do_new_component(bz, parser, opt, args)
+
     elif action == 'attach':
         if opt.get or opt.getall:
             _do_get_attach(bz, opt, parser, args)
@@ -1196,6 +1270,17 @@
         modout = _do_modify(bz, parser, opt, args)
         if opt.test_return_result:
             return modout
+
+    elif action == 'modify_component':
+        if len(args) < 2:
+            parser.error('Not enough arguments to specify component to modify')
+
+        if not (opt.default_assignee or
+                opt.default_qa_contact or
+                opt.default_cc):
+            parser.error("'modify_component' command requires additional"
+                         " arguments")
+        _do_modify_component(bz, parser, opt, args)
     else:
         raise RuntimeError("Unexpected action '%s'" % action)
 
