diff --git a/SOURCES/0213-reportclient-honor-ABRT_VERBOSE.patch b/SOURCES/0213-reportclient-honor-ABRT_VERBOSE.patch
new file mode 100644
index 0000000..fedb796
--- /dev/null
+++ b/SOURCES/0213-reportclient-honor-ABRT_VERBOSE.patch
@@ -0,0 +1,136 @@
+From 128490bb35079d77c0fa04f2e254bd6a0acc382a Mon Sep 17 00:00:00 2001
+From: Jakub Filak <jfilak@redhat.com>
+Date: Thu, 24 Nov 2016 07:54:21 +0100
+Subject: [PATCH] reportclient: honor ABRT_VERBOSE
+
+libreport's verbosity can be configured via ABRT_VERBOSE environment
+variable and reportclient must be aware of that.
+
+Related to #1257159
+
+Signed-off-by: Jakub Filak <jfilak@redhat.com>
+---
+ src/client-python/__init__.py |  9 ++++++++
+ tests/Makefile.am             |  1 +
+ tests/client_python.at        | 53 +++++++++++++++++++++++++++++++++++++++++++
+ tests/testsuite.at            |  1 +
+ 4 files changed, 64 insertions(+)
+ create mode 100644 tests/client_python.at
+
+diff --git a/src/client-python/__init__.py b/src/client-python/__init__.py
+index 8966f22..f10f710 100644
+--- a/src/client-python/__init__.py
++++ b/src/client-python/__init__.py
+@@ -31,6 +31,7 @@ from report import EXIT_STOP_EVENT_RUN as RETURN_STOP_EVENT_RUN
+ 
+ 
+ GETTEXT_PROGNAME = "libreport"
++import os
+ import locale
+ import gettext
+ 
+@@ -52,10 +53,18 @@ def init_gettext():
+ init_gettext()
+ 
+ verbose = 0
++ABRT_VERBOSE = os.getenv("ABRT_VERBOSE")
++if ABRT_VERBOSE:
++    try:
++        verbose = int(ABRT_VERBOSE)
++    except:
++        pass
++
+ 
+ def set_verbosity(verbosity):
+     global verbose
+     verbose = verbosity
++    os.environ["ABRT_VERBOSE"] = str(verbose)
+ 
+ def log(fmt, *args):
+     sys.stderr.write("%s\n" % (fmt % args))
+diff --git a/tests/Makefile.am b/tests/Makefile.am
+index b45f2d9..52dfce4 100644
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -40,6 +40,7 @@ TESTSUITE_AT = \
+   libreport_types.at \
+   xml_definition.at \
+   report_python.at \
++  client_python.at \
+   xfuncs.at \
+   string_list.at \
+   ureport.at \
+diff --git a/tests/client_python.at b/tests/client_python.at
+new file mode 100644
+index 0000000..656b1b2
+--- /dev/null
++++ b/tests/client_python.at
+@@ -0,0 +1,53 @@
++# -*- Autotest -*-
++
++AT_BANNER([client_python])
++
++## --------- ##
++## verbosity ##
++## --------- ##
++
++AT_PYTESTFUN([verbosity], [[
++import sys
++import os
++import unittest
++
++sys.path.insert(0, "../../../src/client-python")
++sys.path.insert(0, "../../../src/client-python/.libs")
++
++
++class TestReportClientVerbose(unittest.TestCase):
++    def setUp(self):
++        try:
++            del os.environ["ABRT_VERBOSE"]
++        except:
++            pass
++        os.unsetenv("ABRT_VERBOSE")
++        self.clientpython = __import__("client-python", globals(), locals(), [], -1)
++        reload(self.clientpython)
++        sys.modules["clientpython"] = self.clientpython
++
++    def tearDown(self):
++        del sys.modules["clientpython"]
++
++    def test_default(self):
++        self.assertEquals(self.clientpython.verbose, 0)
++
++    def test_assign(self):
++        self.clientpython.set_verbosity(1)
++        self.assertEquals(self.clientpython.verbose, 1)
++        self.assertEquals(os.environ["ABRT_VERBOSE"], "1")
++
++    def test_load_from_environ(self):
++        os.environ["ABRT_VERBOSE"] = "2"
++        reload(self.clientpython)
++        self.assertEquals(self.clientpython.verbose, 2)
++
++    def test_recover_from_invalid_environ(self):
++        os.environ["ABRT_VERBOSE"] = "foo"
++        reload(self.clientpython)
++        self.assertEquals(self.clientpython.verbose, 0)
++
++
++if __name__ == "__main__":
++    unittest.main()
++]])
+diff --git a/tests/testsuite.at b/tests/testsuite.at
+index ccb37d1..8ded735 100644
+--- a/tests/testsuite.at
++++ b/tests/testsuite.at
+@@ -15,6 +15,7 @@ m4_include([make_description.at])
+ m4_include([libreport_types.at])
+ m4_include([xml_definition.at])
+ m4_include([report_python.at])
++m4_include([client_python.at])
+ m4_include([string_list.at])
+ m4_include([ureport.at])
+ m4_include([problem_report.at])
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0214-tree-wide-introduce-stop_on_not_reportable-option.patch b/SOURCES/0214-tree-wide-introduce-stop_on_not_reportable-option.patch
new file mode 100644
index 0000000..cf2e243
--- /dev/null
+++ b/SOURCES/0214-tree-wide-introduce-stop_on_not_reportable-option.patch
@@ -0,0 +1,303 @@
+From 8ee8cf6d0467241d2886a095be25c2885d3a8666 Mon Sep 17 00:00:00 2001
+From: Jakub Filak <jfilak@redhat.com>
+Date: Wed, 23 Nov 2016 16:22:51 +0100
+Subject: [PATCH] tree-wide: introduce 'stop_on_not_reportable' option
+
+Make it possible to ignore existence of not-reportable file and continue
+in reporting.
+
+The new configuration option is not yet persistent and can be configured
+via an environment variable.
+
+Related to #1257159
+Related to abrt/abrt#1166
+
+Signed-off-by: Jakub Filak <jfilak@redhat.com>
+---
+ src/cli/cli-report.c               |  3 +-
+ src/gui-wizard-gtk/wizard.c        | 21 ++++++++----
+ src/include/global_configuration.h | 28 ++++++++++++++++
+ src/include/internal_libreport.h   |  1 +
+ src/include/report.h               |  3 ++
+ src/lib/global_configuration.c     | 22 +++++++++++++
+ src/lib/report.c                   |  6 ++++
+ src/report-newt/report-newt.c      |  4 ++-
+ src/report-python/reportmodule.c   |  1 +
+ tests/global_config.at             | 67 ++++++++++++++++++++++++++++++++++++++
+ 10 files changed, 148 insertions(+), 8 deletions(-)
+
+diff --git a/src/cli/cli-report.c b/src/cli/cli-report.c
+index 68baa8b..adb58a7 100644
+--- a/src/cli/cli-report.c
++++ b/src/cli/cli-report.c
+@@ -525,7 +525,8 @@ static int is_not_reportable(problem_data_t *problem_data)
+     if (not_reportable)
+     {
+         printf("%s\n", not_reportable);
+-        return 1;
++        if (get_global_stop_on_not_reportable())
++            return 1;
+     }
+     return 0;
+ }
+diff --git a/src/gui-wizard-gtk/wizard.c b/src/gui-wizard-gtk/wizard.c
+index 31861a1..35c6fc3 100644
+--- a/src/gui-wizard-gtk/wizard.c
++++ b/src/gui-wizard-gtk/wizard.c
+@@ -2039,7 +2039,7 @@ static gboolean consume_cmd_output(GIOChannel *source, GIOCondition condition, g
+             dd_sanitize_mode_and_owner(dd);
+     }
+ 
+-    if (retval == 0 && !g_expert_mode)
++    if (retval == 0 && !g_expert_mode && get_global_stop_on_not_reportable())
+     {
+         /* Check whether NOT_REPORTABLE element appeared. If it did, we'll stop
+          * even if exit code is "success".
+@@ -3103,16 +3103,25 @@ static gint select_next_page_no(gint current_page_no, gpointer data)
+ 
+             if (problem_data_get_content_or_NULL(g_cd, FILENAME_NOT_REPORTABLE))
+             {
+-                free(event);
+ 
+                 char *msg = xasprintf(_("This problem should not be reported "
+                                 "(it is likely a known problem). %s"),
+                                 problem_data_get_content_or_NULL(g_cd, FILENAME_NOT_REPORTABLE)
+                 );
+-                cancel_processing(g_lbl_event_log, msg, TERMINATE_NOFLAGS);
+-                free(msg);
+-                current_page_no = pages[PAGENO_EVENT_PROGRESS].page_no - 1;
+-                goto again;
++
++                if (get_global_stop_on_not_reportable())
++                {
++                    free(event);
++                    cancel_processing(g_lbl_event_log, msg, TERMINATE_NOFLAGS);
++                    free(msg);
++                    current_page_no = pages[PAGENO_EVENT_PROGRESS].page_no - 1;
++                    goto again;
++                }
++                else
++                {
++                    log(msg);
++                    free(msg);
++                }
+             }
+ 
+             /* must set g_event_selected otherwise if the event was not
+diff --git a/src/include/global_configuration.h b/src/include/global_configuration.h
+index bc5513d..0eb18c6 100644
+--- a/src/include/global_configuration.h
++++ b/src/include/global_configuration.h
+@@ -53,6 +53,34 @@ bool get_global_create_private_ticket(void);
+ #define set_global_create_private_ticket libreport_set_global_create_private_ticket
+ void set_global_create_private_ticket(bool enabled, int flags);
+ 
++/**
++ * Returns logical true if the reporting process shall not start or contine if
++ * the not-reportable files exists.
++ *
++ * The option can be enabled by ABRT_STOP_ON_NOT_REPORTABLE environment
++ * variable.
++ *
++ * @return true if the process shall stop; otherwise the function returns
++ * false.
++ */
++#define get_global_stop_on_not_reportable libreport_get_global_stop_on_not_reportable
++bool get_global_stop_on_not_reportable(void);
++
++/**
++ * Configures the stop on not reportable global option
++ *
++ * The function changes the configuration only for the current process by
++ * default.
++ *
++ * The option can be enabled by ABRT_STOP_ON_NOT_REPORTABLE environment
++ * variable.
++ *
++ * @param enabled The option's value
++ * @param flags For future needs (enable persistent configuration)
++ */
++#define set_global_stop_on_not_reportable libreport_set_global_stop_on_not_reportable
++void set_global_stop_on_not_reportable(bool enabled, int flags);
++
+ #ifdef __cplusplus
+ }
+ #endif
+diff --git a/src/include/internal_libreport.h b/src/include/internal_libreport.h
+index cf5730c..23cdfa0 100644
+--- a/src/include/internal_libreport.h
++++ b/src/include/internal_libreport.h
+@@ -87,6 +87,7 @@ int vdprintf(int d, const char *format, va_list ap);
+ 
+ /* consts used across whole libreport */
+ #define CREATE_PRIVATE_TICKET "ABRT_CREATE_PRIVATE_TICKET"
++#define STOP_ON_NOT_REPORTABLE "ABRT_STOP_ON_NOT_REPORTABLE"
+ 
+ /* Pull in entire public libreport API */
+ #include "dump_dir.h"
+diff --git a/src/include/report.h b/src/include/report.h
+index d31eb0a..03f3dc6 100644
+--- a/src/include/report.h
++++ b/src/include/report.h
+@@ -35,6 +35,9 @@ enum {
+     LIBREPORT_DEL_DIR     = (1 << 6), /* delete directory after reporting (passes --delete to child) */
+     LIBREPORT_RUN_CLI     = (1 << 7), /* run 'cli' instead of 'gui' */
+     LIBREPORT_RUN_NEWT    = (1 << 8), /* run 'report-newt' */
++    LIBREPORT_IGNORE_NOT_REPORTABLE = (1 << 9), /* do not terminate the
++                                                  reporting process if the
++                                                  not-repotrable file exits. */
+ };
+ 
+ int report_problem_in_dir(const char *dirname, int flags);
+diff --git a/src/lib/global_configuration.c b/src/lib/global_configuration.c
+index ef921e9..46b9a63 100644
+--- a/src/lib/global_configuration.c
++++ b/src/lib/global_configuration.c
+@@ -163,3 +163,25 @@ void set_global_create_private_ticket(bool enabled, int flags/*unused - persiste
+     else
+         safe_unsetenv(CREATE_PRIVATE_TICKET);
+ }
++
++bool get_global_stop_on_not_reportable(void)
++{
++    assert_global_configuration_initialized();
++
++    char *env_create_private = getenv(STOP_ON_NOT_REPORTABLE);
++
++    if (env_create_private == NULL)
++        return true;
++
++    return string_to_bool(env_create_private);
++}
++
++void set_global_stop_on_not_reportable(bool enabled, int flags/*unused - persistent*/)
++{
++    assert_global_configuration_initialized();
++
++    if (enabled)
++        xsetenv(STOP_ON_NOT_REPORTABLE, "1");
++    else
++        xsetenv(STOP_ON_NOT_REPORTABLE, "0");
++}
+diff --git a/src/lib/report.c b/src/lib/report.c
+index 7a655fd..3380a52 100644
+--- a/src/lib/report.c
++++ b/src/lib/report.c
+@@ -26,6 +26,12 @@ int report_problem_in_dir(const char *dirname, int flags)
+     if (prgname)
+         prgname = xasprintf("LIBREPORT_PRGNAME=%s", prgname);
+ 
++    if (flags & LIBREPORT_IGNORE_NOT_REPORTABLE)
++    {
++        load_global_configuration();
++        set_global_stop_on_not_reportable(false, 0);
++    }
++
+     fflush(NULL);
+ 
+     pid_t pid = fork();
+diff --git a/src/report-newt/report-newt.c b/src/report-newt/report-newt.c
+index f5fca76..278cfb7 100644
+--- a/src/report-newt/report-newt.c
++++ b/src/report-newt/report-newt.c
+@@ -336,7 +336,9 @@ static int report(const char *dump_dir_name)
+         dd_close(dd);
+         newtWinMessage(_("Error"), _("Ok"), (char *)"%s", t);
+         free(t);
+-        return -1;
++
++        if (get_global_stop_on_not_reportable())
++            return -1;
+     }
+ 
+     dd_close(dd);
+diff --git a/src/report-python/reportmodule.c b/src/report-python/reportmodule.c
+index b8154ae..4491fd4 100644
+--- a/src/report-python/reportmodule.c
++++ b/src/report-python/reportmodule.c
+@@ -98,6 +98,7 @@ init_pyreport(void)
+     PyModule_AddObject(m, "LIBREPORT_DEL_DIR"    , Py_BuildValue("i", LIBREPORT_DEL_DIR    ));
+     PyModule_AddObject(m, "LIBREPORT_RUN_CLI"    , Py_BuildValue("i", LIBREPORT_RUN_CLI    ));
+     PyModule_AddObject(m, "LIBREPORT_RUN_NEWT"   , Py_BuildValue("i", LIBREPORT_RUN_NEWT  ));
++    PyModule_AddObject(m, "LIBREPORT_IGNORE_NOT_REPORTABLE", Py_BuildValue("i", LIBREPORT_IGNORE_NOT_REPORTABLE));
+     PyModule_AddObject(m, "EXIT_CANCEL_BY_USER", Py_BuildValue("i", EXIT_CANCEL_BY_USER));
+     PyModule_AddObject(m, "EXIT_STOP_EVENT_RUN", Py_BuildValue("i", EXIT_STOP_EVENT_RUN));
+ }
+diff --git a/tests/global_config.at b/tests/global_config.at
+index 05a0ffa..1067128 100644
+--- a/tests/global_config.at
++++ b/tests/global_config.at
+@@ -169,3 +169,70 @@ TS_MAIN
+ }
+ TS_RETURN_MAIN
+ ]])
++
++
++## ---------------------- ##
++## stop_on_not_reportable ##
++## ---------------------- ##
++
++AT_TESTFUN([stop_on_not_reportable], [[
++#include "testsuite.h"
++
++TS_MAIN
++{
++    char cwd_buf[PATH_MAX + 1];
++    static const char *dirs[] = {
++        NULL,
++        NULL,
++    };
++    dirs[0] = getcwd(cwd_buf, sizeof(cwd_buf));
++
++    static int dir_flags[] = {
++        CONF_DIR_FLAG_NONE,
++        -1,
++    };
++
++    unlink("libreport.conf");
++    FILE *lrf = fopen("libreport.conf", "wx");
++    assert(lrf != NULL);
++    fclose(lrf);
++
++    assert(load_global_configuration_from_dirs(dirs, dir_flags));
++
++    TS_ASSERT_TRUE_MESSAGE(get_global_stop_on_not_reportable(), "True by default");
++
++    set_global_stop_on_not_reportable(true, 0);
++
++    TS_ASSERT_TRUE_MESSAGE(get_global_stop_on_not_reportable(), "Still true");
++
++    set_global_stop_on_not_reportable(false, 0);
++
++    TS_ASSERT_FALSE_MESSAGE(get_global_stop_on_not_reportable(), "Configuration accepted");
++    TS_ASSERT_STRING_EQ(getenv(STOP_ON_NOT_REPORTABLE), "0", "Correct ENVIRONMENT value");
++
++    set_global_stop_on_not_reportable(true, 0);
++
++    TS_ASSERT_TRUE_MESSAGE(get_global_stop_on_not_reportable(), "Configuration sanity");
++    TS_ASSERT_STRING_EQ(getenv(STOP_ON_NOT_REPORTABLE), "1", "Correct ENVIRONMENT value");
++
++    set_global_stop_on_not_reportable(false, 0);
++
++    TS_ASSERT_FALSE_MESSAGE(get_global_stop_on_not_reportable(), "Reverted back to False");
++    TS_ASSERT_STRING_EQ(getenv(STOP_ON_NOT_REPORTABLE), "0", "Correct ENVIRONMENT value");
++
++    xsetenv(STOP_ON_NOT_REPORTABLE, "1");
++
++    TS_ASSERT_TRUE_MESSAGE(get_global_stop_on_not_reportable(), "Loaded from environment");
++
++    unsetenv(STOP_ON_NOT_REPORTABLE);
++
++    TS_ASSERT_TRUE_MESSAGE(get_global_stop_on_not_reportable(), "Reflects environment");
++
++    xsetenv(STOP_ON_NOT_REPORTABLE, "0");
++
++    TS_ASSERT_FALSE_MESSAGE(get_global_stop_on_not_reportable(), "Zero is false");
++
++    free_global_configuration();
++}
++TS_RETURN_MAIN
++]])
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0215-rhtsupport-fix-a-double-free-of-config-at-exit.patch b/SOURCES/0215-rhtsupport-fix-a-double-free-of-config-at-exit.patch
new file mode 100644
index 0000000..244f62e
--- /dev/null
+++ b/SOURCES/0215-rhtsupport-fix-a-double-free-of-config-at-exit.patch
@@ -0,0 +1,33 @@
+From 696fcadc7d494fc14ad5ac23f19b7da6a7f98c3b Mon Sep 17 00:00:00 2001
+From: Jakub Filak <jfilak@redhat.com>
+Date: Mon, 5 Sep 2016 10:42:11 +0200
+Subject: [PATCH] rhtsupport: fix a double free of config at exit
+
+Introduced in commit 028b35b where I forgot on the code added in commit
+5ff7f36.
+
+Related: rhbz#1373094
+---
+ src/plugins/reporter-rhtsupport.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+diff --git a/src/plugins/reporter-rhtsupport.c b/src/plugins/reporter-rhtsupport.c
+index 63a24a5..14b3864 100644
+--- a/src/plugins/reporter-rhtsupport.c
++++ b/src/plugins/reporter-rhtsupport.c
+@@ -811,12 +811,7 @@ int main(int argc, char **argv)
+             /* Check for hints and show them if we have something */
+             log(_("Checking for hints"));
+             if (check_for_hints(base_api_url, &login, &password, ssl_verify, tempfile))
+-            {
+-                ureport_server_config_destroy(&urconf);
+-                free_map_string(ursettings);
+-                free(bthash);
+                 goto ret;
+-            }
+         }
+ 
+         log(_("Creating a new case"));
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0216-reportclient-fix-verbosity-test.patch b/SOURCES/0216-reportclient-fix-verbosity-test.patch
new file mode 100644
index 0000000..3f6fb62
--- /dev/null
+++ b/SOURCES/0216-reportclient-fix-verbosity-test.patch
@@ -0,0 +1,33 @@
+From 10fb97f11e27c4ac2144005f0ac28b8beff14733 Mon Sep 17 00:00:00 2001
+From: Matej Habrnal <mhabrnal@redhat.com>
+Date: Wed, 8 Feb 2017 14:50:49 +0100
+Subject: [PATCH] reportclient: fix verbosity test
+
+Imported missing report module.
+
+Related #1257159
+
+Signed-off-by: Matej Habrnal <mhabrnal@redhat.com>
+---
+ tests/client_python.at | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/tests/client_python.at b/tests/client_python.at
+index 656b1b2..9f1c1c1 100644
+--- a/tests/client_python.at
++++ b/tests/client_python.at
+@@ -13,7 +13,11 @@ import unittest
+ 
+ sys.path.insert(0, "../../../src/client-python")
+ sys.path.insert(0, "../../../src/client-python/.libs")
++sys.path.insert(0, "../../../src/report-python")
++sys.path.insert(0, "../../../src/report-python/.libs")
+ 
++report = __import__("report-python", globals(), locals(), [], -1)
++sys.modules["report"] = report
+ 
+ class TestReportClientVerbose(unittest.TestCase):
+     def setUp(self):
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0217-report-newt-free-allocated-variables-don-t-close-dd-.patch b/SOURCES/0217-report-newt-free-allocated-variables-don-t-close-dd-.patch
new file mode 100644
index 0000000..231a615
--- /dev/null
+++ b/SOURCES/0217-report-newt-free-allocated-variables-don-t-close-dd-.patch
@@ -0,0 +1,39 @@
+From 79d5c0352a09fc1bfe8cc491b33a745ac33b7855 Mon Sep 17 00:00:00 2001
+From: Matej Habrnal <mhabrnal@redhat.com>
+Date: Tue, 21 Feb 2017 12:08:13 +0100
+Subject: [PATCH] report-newt: free allocated variables, don't close dd twice
+
+Uncovered by coverity.
+
+Related #1257159
+
+Signed-off-by: Matej Habrnal <mhabrnal@redhat.com>
+---
+ src/report-newt/report-newt.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/src/report-newt/report-newt.c b/src/report-newt/report-newt.c
+index 278cfb7..2427d86 100644
+--- a/src/report-newt/report-newt.c
++++ b/src/report-newt/report-newt.c
+@@ -333,12 +333,16 @@ static int report(const char *dump_dir_name)
+                             not_reportable ? " " : "",
+                             reason ? : _("(no description)"));
+ 
+-        dd_close(dd);
+         newtWinMessage(_("Error"), _("Ok"), (char *)"%s", t);
+         free(t);
++        free(not_reportable);
++        free(reason);
+ 
+         if (get_global_stop_on_not_reportable())
++        {
++            dd_close(dd);
+             return -1;
++        }
+     }
+ 
+     dd_close(dd);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/1000-bugzilla-port-to-Problem-Format-API.patch b/SOURCES/1000-bugzilla-port-to-Problem-Format-API.patch
deleted file mode 100644
index 5ab0a57..0000000
--- a/SOURCES/1000-bugzilla-port-to-Problem-Format-API.patch
+++ /dev/null
@@ -1,781 +0,0 @@
-From ff32b9ee7a7e396e33f1e9aeaa5bafd26ccbb273 Mon Sep 17 00:00:00 2001
-From: Jakub Filak <jfilak@redhat.com>
-Date: Thu, 4 Dec 2014 08:45:07 +0100
-Subject: [PATCH 1000/1015] bugzilla: port to Problem Format API
-
-Related to #303
-
-Signed-off-by: Jakub Filak <jfilak@redhat.com>
----
- src/plugins/reporter-bugzilla.c | 691 ++++------------------------------------
- 1 file changed, 59 insertions(+), 632 deletions(-)
-
-diff --git a/src/plugins/reporter-bugzilla.c b/src/plugins/reporter-bugzilla.c
-index fbe7873..9ff3df3 100644
---- a/src/plugins/reporter-bugzilla.c
-+++ b/src/plugins/reporter-bugzilla.c
-@@ -17,515 +17,11 @@
-     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
- #include "internal_libreport.h"
-+#include "problem_report.h"
- #include "client.h"
- #include "abrt_xmlrpc.h"
- #include "rhbz.h"
- 
--#include <satyr/stacktrace.h>
--#include <satyr/abrt.h>
--
--struct section_t {
--    char *name;
--    GList *items;
--};
--typedef struct section_t section_t;
--
--
--/* Utility functions */
--
--static
--GList* split_string_on_char(const char *str, char ch)
--{
--    GList *list = NULL;
--    for (;;)
--    {
--        const char *delim = strchrnul(str, ch);
--        list = g_list_prepend(list, xstrndup(str, delim - str));
--        if (*delim == '\0')
--            break;
--        str = delim + 1;
--    }
--    return g_list_reverse(list);
--}
--
--static
--int compare_item_name(const char *lookup, const char *name)
--{
--    if (lookup[0] == '-')
--        lookup++;
--    else if (strncmp(lookup, "%bare_", 6) == 0)
--        lookup += 6;
--    return strcmp(lookup, name);
--}
--
--static
--int is_item_name_in_section(const section_t *lookup, const char *name)
--{
--    if (g_list_find_custom(lookup->items, name, (GCompareFunc)compare_item_name))
--        return 0; /* "found it!" */
--    return 1;
--}
--
--static
--bool is_explicit_or_forbidden(const char *name, GList *comment_fmt_spec)
--{
--    return g_list_find_custom(comment_fmt_spec, name, (GCompareFunc)is_item_name_in_section);
--}
--
--static
--GList* load_bzrep_conf_file(const char *path)
--{
--    FILE *fp = stdin;
--    if (strcmp(path, "-") != 0)
--    {
--        fp = fopen(path, "r");
--        if (!fp)
--            return NULL;
--    }
--
--    GList *sections = NULL;
--
--    char *line;
--    while ((line = xmalloc_fgetline(fp)) != NULL)
--    {
--        /* Skip comments */
--        char first = *skip_whitespace(line);
--        if (first == '#')
--            goto free_line;
--
--        /* Handle trailing backslash continuation */
-- check_continuation: ;
--        unsigned len = strlen(line);
--        if (len && line[len-1] == '\\')
--        {
--            line[len-1] = '\0';
--            char *next_line = xmalloc_fgetline(fp);
--            if (next_line)
--            {
--                line = append_to_malloced_string(line, next_line);
--                free(next_line);
--                goto check_continuation;
--            }
--        }
--
--        /* We are reusing line buffer to form temporary
--         * "key\0values\0..." in its beginning
--         */
--        bool summary_line = false;
--        char *value = NULL;
--        char *src;
--        char *dst;
--        for (src = dst = line; *src; src++)
--        {
--            char c = *src;
--            /* did we reach the value list? */
--            if (!value && c == ':' && src[1] == ':')
--            {
--                *dst++ = '\0'; /* terminate key */
--                src += 2;
--                value = dst; /* remember where value starts */
--                summary_line = (strcmp(line, "%summary") == 0);
--                if (summary_line)
--                {
--                    value = src;
--                    break;
--                }
--                continue;
--            }
--            /* skip whitespace in value list */
--            if (value && isspace(c))
--                continue;
--            *dst++ = c; /* store next key or value char */
--        }
--
--        GList *item_list = NULL;
--        if (summary_line)
--        {
--            /* %summary is special */
--            item_list = g_list_append(NULL, xstrdup(skip_whitespace(value)));
--        }
--        else
--        {
--            *dst = '\0'; /* terminate value (or key) */
--            if (value)
--                item_list = split_string_on_char(value, ',');
--        }
--
--        section_t *sec = xzalloc(sizeof(*sec));
--        sec->name = xstrdup(line);
--        sec->items = item_list;
--        sections = g_list_prepend(sections, sec);
--
-- free_line:
--        free(line);
--    }
--
--    if (fp != stdin)
--        fclose(fp);
--
--    return g_list_reverse(sections);
--}
--
--
--/* Summary generation */
--
--#define MAX_OPT_DEPTH 10
--static
--char *format_percented_string(const char *str, problem_data_t *pd)
--{
--    size_t old_pos[MAX_OPT_DEPTH] = { 0 };
--    int okay[MAX_OPT_DEPTH] = { 1 };
--    int opt_depth = 1;
--    struct strbuf *result = strbuf_new();
--
--    while (*str) {
--        switch (*str) {
--        default:
--            strbuf_append_char(result, *str);
--            str++;
--            break;
--        case '\\':
--            if (str[1])
--                str++;
--            strbuf_append_char(result, *str);
--            str++;
--            break;
--        case '[':
--            if (str[1] == '[' && opt_depth < MAX_OPT_DEPTH)
--            {
--                old_pos[opt_depth] = result->len;
--                okay[opt_depth] = 1;
--                opt_depth++;
--                str += 2;
--            } else {
--                strbuf_append_char(result, *str);
--                str++;
--            }
--            break;
--        case ']':
--            if (str[1] == ']' && opt_depth > 1)
--            {
--                opt_depth--;
--                if (!okay[opt_depth])
--                {
--                    result->len = old_pos[opt_depth];
--                    result->buf[result->len] = '\0';
--                }
--                str += 2;
--            } else {
--                strbuf_append_char(result, *str);
--                str++;
--            }
--            break;
--        case '%': ;
--            char *nextpercent = strchr(++str, '%');
--            if (!nextpercent)
--            {
--                error_msg_and_die("Unterminated %%element%%: '%s'", str - 1);
--            }
--
--            *nextpercent = '\0';
--            const problem_item *item = problem_data_get_item_or_NULL(pd, str);
--            *nextpercent = '%';
--
--            if (item && (item->flags & CD_FLAG_TXT))
--                strbuf_append_str(result, item->content);
--            else
--                okay[opt_depth - 1] = 0;
--            str = nextpercent + 1;
--            break;
--        }
--    }
--
--    if (opt_depth > 1)
--    {
--        error_msg_and_die("Unbalanced [[ ]] bracket");
--    }
--
--    if (!okay[0])
--    {
--        error_msg("Undefined variable outside of [[ ]] bracket");
--    }
--
--    return strbuf_free_nobuf(result);
--}
--
--static
--char *create_summary_string(problem_data_t *pd, GList *comment_fmt_spec)
--{
--    GList *l = comment_fmt_spec;
--    while (l)
--    {
--        section_t *sec = l->data;
--        l = l->next;
--
--        /* Find %summary" */
--        if (strcmp(sec->name, "%summary") != 0)
--            continue;
--
--        GList *item = sec->items;
--        if (!item)
--            /* not supposed to happen, there will be at least "" */
--            error_msg_and_die("BUG in %%summary parser");
--
--        const char *str = item->data;
--        return format_percented_string(str, pd);
--    }
--
--    return format_percented_string("%reason%", pd);
--}
--
--
--/* BZ comment generation */
--
--static
--int append_text(struct strbuf *result, const char *item_name, const char *content, bool print_item_name)
--{
--    char *eol = strchrnul(content, '\n');
--    if (eol[0] == '\0' || eol[1] == '\0')
--    {
--        /* one-liner */
--        int pad = 16 - (strlen(item_name) + 2);
--        if (pad < 0)
--            pad = 0;
--        if (print_item_name)
--            strbuf_append_strf(result,
--                    eol[0] == '\0' ? "%s: %*s%s\n" : "%s: %*s%s",
--                    item_name, pad, "", content
--            );
--        else
--            strbuf_append_strf(result,
--                    eol[0] == '\0' ? "%s\n" : "%s",
--                    content
--            );
--    }
--    else
--    {
--        /* multi-line item */
--        if (print_item_name)
--            strbuf_append_strf(result, "%s:\n", item_name);
--        for (;;)
--        {
--            eol = strchrnul(content, '\n');
--            strbuf_append_strf(result,
--                    /* For %bare_multiline_item, we don't want to print colons */
--                    (print_item_name ? ":%.*s\n" : "%.*s\n"),
--                    (int)(eol - content), content
--            );
--            if (eol[0] == '\0' || eol[1] == '\0')
--                break;
--            content = eol + 1;
--        }
--    }
--    return 1;
--}
--
--static
--int append_short_backtrace(struct strbuf *result, problem_data_t *problem_data, size_t max_text_size, bool print_item_name)
--{
--    const problem_item *item = problem_data_get_item_or_NULL(problem_data,
--                                                             FILENAME_BACKTRACE);
--    if (!item)
--        return 0; /* "I did not print anything" */
--    if (!(item->flags & CD_FLAG_TXT))
--        return 0; /* "I did not print anything" */
--
--    char *truncated = NULL;
--
--    if (strlen(item->content) >= max_text_size)
--    {
--        char *error_msg = NULL;
--        const char *analyzer = problem_data_get_content_or_NULL(problem_data, FILENAME_ANALYZER);
--        if (!analyzer)
--            return 0;
--
--        /* For CCpp crashes, use the GDB-produced backtrace which should be
--         * available by now. sr_abrt_type_from_analyzer returns SR_REPORT_CORE
--         * by default for CCpp crashes.
--         */
--        enum sr_report_type report_type = sr_abrt_type_from_analyzer(analyzer);
--        if (strcmp(analyzer, "CCpp") == 0)
--            report_type = SR_REPORT_GDB;
--
--        struct sr_stacktrace *backtrace = sr_stacktrace_parse(report_type,
--                item->content, &error_msg);
--
--        if (!backtrace)
--        {
--            log(_("Can't parse backtrace: %s"), error_msg);
--            free(error_msg);
--            return 0;
--        }
--
--        /* Get optimized thread stack trace for 10 top most frames */
--        truncated = sr_stacktrace_to_short_text(backtrace, 10);
--        sr_stacktrace_free(backtrace);
--
--        if (!truncated)
--        {
--            log(_("Can't generate stacktrace description (no crash thread?)"));
--            return 0;
--        }
--    }
--
--    append_text(result,
--                /*item_name:*/ truncated ? "truncated_backtrace" : FILENAME_BACKTRACE,
--                /*content:*/   truncated ? truncated             : item->content,
--                print_item_name
--    );
--    free(truncated);
--    return 1;
--}
--
--static
--int append_item(struct strbuf *result, const char *item_name, problem_data_t *pd, GList *comment_fmt_spec)
--{
--    bool print_item_name = (strncmp(item_name, "%bare_", strlen("%bare_")) != 0);
--    if (!print_item_name)
--        item_name += strlen("%bare_");
--
--    if (item_name[0] != '%')
--    {
--        struct problem_item *item = problem_data_get_item_or_NULL(pd, item_name);
--        if (!item)
--            return 0; /* "I did not print anything" */
--        if (!(item->flags & CD_FLAG_TXT))
--            return 0; /* "I did not print anything" */
--
--        char *formatted = problem_item_format(item);
--        char *content = formatted ? formatted : item->content;
--        append_text(result, item_name, content, print_item_name);
--        free(formatted);
--        return 1; /* "I printed something" */
--    }
--
--    /* Special item name */
--
--    /* Compat with previously-existed ad-hockery: %short_backtrace */
--    if (strcmp(item_name, "%short_backtrace") == 0)
--        return append_short_backtrace(result, pd, CD_TEXT_ATT_SIZE_BZ, print_item_name);
--
--    /* Compat with previously-existed ad-hockery: %reporter */
--    if (strcmp(item_name, "%reporter") == 0)
--        return append_text(result, "reporter", PACKAGE"-"VERSION, print_item_name);
--
--    /* %oneline,%multiline,%text */
--    bool oneline   = (strcmp(item_name+1, "oneline"  ) == 0);
--    bool multiline = (strcmp(item_name+1, "multiline") == 0);
--    bool text      = (strcmp(item_name+1, "text"     ) == 0);
--    if (!oneline && !multiline && !text)
--    {
--        log("Unknown or unsupported element specifier '%s'", item_name);
--        return 0; /* "I did not print anything" */
--    }
--
--    int printed = 0;
--
--    /* Iterate over _sorted_ items */
--    GList *sorted_names = g_hash_table_get_keys(pd);
--    sorted_names = g_list_sort(sorted_names, (GCompareFunc)strcmp);
--
--    /* %text => do as if %oneline, then repeat as if %multiline */
--    if (text)
--        oneline = 1;
--
-- again: ;
--    GList *l = sorted_names;
--    while (l)
--    {
--        const char *name = l->data;
--        l = l->next;
--        struct problem_item *item = g_hash_table_lookup(pd, name);
--        if (!item)
--            continue; /* paranoia, won't happen */
--
--        if (!(item->flags & CD_FLAG_TXT))
--            continue;
--
--        if (is_explicit_or_forbidden(name, comment_fmt_spec))
--            continue;
--
--        char *formatted = problem_item_format(item);
--        char *content = formatted ? formatted : item->content;
--        char *eol = strchrnul(content, '\n');
--        bool is_oneline = (eol[0] == '\0' || eol[1] == '\0');
--        if (oneline == is_oneline)
--            printed |= append_text(result, name, content, print_item_name);
--        free(formatted);
--    }
--    if (text && oneline)
--    {
--        /* %text, and we just did %oneline. Repeat as if %multiline */
--        oneline = 0;
--        /*multiline = 1; - not checked in fact, so why bother setting? */
--        goto again;
--    }
--
--    g_list_free(sorted_names); /* names themselves are not freed */
--
--    return printed;
--}
--
--static
--void generate_bz_comment(struct strbuf *result, problem_data_t *pd, GList *comment_fmt_spec)
--{
--    bool last_line_is_empty = true;
--    GList *l = comment_fmt_spec;
--    while (l)
--    {
--        section_t *sec = l->data;
--        l = l->next;
--
--        /* Skip special sections such as "%attach" */
--        if (sec->name[0] == '%')
--            continue;
--
--        if (sec->items)
--        {
--            /* "Text: item[,item]..." */
--            struct strbuf *output = strbuf_new();
--            GList *item = sec->items;
--            while (item)
--            {
--                const char *str = item->data;
--                item = item->next;
--                if (str[0] == '-') /* "-name", ignore it */
--                    continue;
--                append_item(output, str, pd, comment_fmt_spec);
--            }
--
--            if (output->len != 0)
--            {
--                strbuf_append_strf(result,
--                            sec->name[0] ? "%s:\n%s" : "%s%s",
--                            sec->name,
--                            output->buf
--                );
--                last_line_is_empty = false;
--            }
--            strbuf_free(output);
--        }
--        else
--        {
--            /* Just "Text" (can be "") */
--
--            /* Filter out consecutive empty lines */
--            if (sec->name[0] != '\0' || !last_line_is_empty)
--                strbuf_append_strf(result, "%s\n", sec->name);
--            last_line_is_empty = (sec->name[0] == '\0');
--        }
--    }
--
--    /* Nuke any trailing empty lines */
--    while (result->len >= 1
--     && result->buf[result->len-1] == '\n'
--     && (result->len == 1 || result->buf[result->len-2] == '\n')
--    ) {
--        result->buf[--result->len] = '\0';
--    }
--}
--
--
- /* BZ attachments */
- 
- static
-@@ -573,104 +69,6 @@ int attach_file_item(struct abrt_xmlrpc *ax, const char *bug_id,
-     return (r == 0);
- }
- 
--static
--int attach_item(struct abrt_xmlrpc *ax, const char *bug_id,
--                const char *item_name, problem_data_t *pd, GList *comment_fmt_spec)
--{
--    if (item_name[0] != '%')
--    {
--        struct problem_item *item = problem_data_get_item_or_NULL(pd, item_name);
--        if (!item)
--            return 0;
--        if (item->flags & CD_FLAG_TXT)
--            return attach_text_item(ax, bug_id, item_name, item);
--        if (item->flags & CD_FLAG_BIN)
--            return attach_file_item(ax, bug_id, item_name, item);
--        return 0;
--    }
--
--    /* Special item name */
--
--    /* %oneline,%multiline,%text,%binary */
--    bool oneline   = (strcmp(item_name+1, "oneline"  ) == 0);
--    bool multiline = (strcmp(item_name+1, "multiline") == 0);
--    bool text      = (strcmp(item_name+1, "text"     ) == 0);
--    bool binary    = (strcmp(item_name+1, "binary"   ) == 0);
--    if (!oneline && !multiline && !text && !binary)
--    {
--        log("Unknown or unsupported element specifier '%s'", item_name);
--        return 0;
--    }
--
--    log_debug("Special item_name '%s', iterating for attach...", item_name);
--    int done = 0;
--
--    /* Iterate over _sorted_ items */
--    GList *sorted_names = g_hash_table_get_keys(pd);
--    sorted_names = g_list_sort(sorted_names, (GCompareFunc)strcmp);
--
--    GList *l = sorted_names;
--    while (l)
--    {
--        const char *name = l->data;
--        l = l->next;
--        struct problem_item *item = g_hash_table_lookup(pd, name);
--        if (!item)
--            continue; /* paranoia, won't happen */
--
--        if (is_explicit_or_forbidden(name, comment_fmt_spec))
--            continue;
--
--        if ((item->flags & CD_FLAG_TXT) && !binary)
--        {
--            char *content = item->content;
--            char *eol = strchrnul(content, '\n');
--            bool is_oneline = (eol[0] == '\0' || eol[1] == '\0');
--            if (text || oneline == is_oneline)
--                done |= attach_text_item(ax, bug_id, name, item);
--        }
--        if ((item->flags & CD_FLAG_BIN) && binary)
--            done |= attach_file_item(ax, bug_id, name, item);
--    }
--
--    g_list_free(sorted_names); /* names themselves are not freed */
--
--
--    log_debug("...Done iterating over '%s' for attach", item_name);
--
--    return done;
--}
--
--static
--int attach_files(struct abrt_xmlrpc *ax, const char *bug_id,
--                problem_data_t *pd, GList *comment_fmt_spec)
--{
--    int done = 0;
--    GList *l = comment_fmt_spec;
--    while (l)
--    {
--        section_t *sec = l->data;
--        l = l->next;
--
--        /* Find %attach" */
--        if (strcmp(sec->name, "%attach") != 0)
--            continue;
--
--        GList *item = sec->items;
--        while (item)
--        {
--            const char *str = item->data;
--            item = item->next;
--            if (str[0] == '-') /* "-name", ignore it */
--                continue;
--            done |= attach_item(ax, bug_id, str, pd, comment_fmt_spec);
--        }
--    }
--
--    return done;
--}
--
--
- /* Main */
- 
- struct bugzilla_struct {
-@@ -1103,18 +501,29 @@ int main(int argc, char **argv)
- 
-     if (opts & OPT_D)
-     {
--        GList *comment_fmt_spec = load_bzrep_conf_file(fmt_file);
--        struct strbuf *bzcomment_buf = strbuf_new();
--        generate_bz_comment(bzcomment_buf, problem_data, comment_fmt_spec);
--        char *bzcomment = strbuf_free_nobuf(bzcomment_buf);
--        char *summary = create_summary_string(problem_data, comment_fmt_spec);
-+        problem_formatter_t *pf = problem_formatter_new();
-+
-+        if (problem_formatter_load_file(pf, fmt_file))
-+            error_msg_and_die("Invalid format file: %s", fmt_file);
-+
-+        problem_report_t *pr = NULL;
-+        if (problem_formatter_generate_report(pf, problem_data, &pr))
-+            error_msg_and_die("Failed to format bug report from problem data");
-+
-         printf("summary: %s\n"
-                 "\n"
-                 "%s"
--                , summary, bzcomment
-+                "\n"
-+                , problem_report_get_summary(pr)
-+                , problem_report_get_description(pr)
-         );
--        free(bzcomment);
--        free(summary);
-+
-+        puts("attachments:");
-+        for (GList *a = problem_report_get_attachments(pr); a != NULL; a = g_list_next(a))
-+            printf(" %s\n", (const char *)a->data);
-+
-+        problem_report_free(pr);
-+        problem_formatter_free(pf);
-         exit(0);
-     }
- 
-@@ -1227,22 +636,29 @@ int main(int argc, char **argv)
-             /* Create new bug */
-             log(_("Creating a new bug"));
- 
--            GList *comment_fmt_spec = load_bzrep_conf_file(fmt_file);
-+            problem_formatter_t *pf = problem_formatter_new();
-+
-+            if (problem_formatter_load_file(pf, fmt_file))
-+                error_msg_and_die("Invalid format file: %s", fmt_file);
-+
-+            problem_report_t *pr = NULL;
-+            if (problem_formatter_generate_report(pf, problem_data, &pr))
-+                error_msg_and_die("Failed to format problem data");
- 
--            struct strbuf *bzcomment_buf = strbuf_new();
--            generate_bz_comment(bzcomment_buf, problem_data, comment_fmt_spec);
-             if (crossver_id >= 0)
--                strbuf_append_strf(bzcomment_buf, "\nPotential duplicate: bug %u\n", crossver_id);
--            char *bzcomment = strbuf_free_nobuf(bzcomment_buf);
--            char *summary = create_summary_string(problem_data, comment_fmt_spec);
-+                problem_report_buffer_printf(
-+                        problem_report_get_buffer(pr, PR_SEC_DESCRIPTION),
-+                        "\nPotential duplicate: bug %u\n", crossver_id);
-+
-+            problem_formatter_free(pf);
-+
-             int new_id = rhbz_new_bug(client,
-                     problem_data, rhbz.b_product, rhbz.b_product_version,
--                    summary, bzcomment,
-+                    problem_report_get_summary(pr),
-+                    problem_report_get_description(pr),
-                     rhbz.b_create_private,
-                     rhbz.b_private_groups
-                     );
--            free(bzcomment);
--            free(summary);
- 
-             if (new_id == -1)
-             {
-@@ -1267,9 +683,17 @@ int main(int argc, char **argv)
-             char new_id_str[sizeof(int)*3 + 2];
-             sprintf(new_id_str, "%i", new_id);
- 
--            attach_files(client, new_id_str, problem_data, comment_fmt_spec);
--
--//TODO: free_comment_fmt_spec(comment_fmt_spec);
-+            for (GList *a = problem_report_get_attachments(pr); a != NULL; a = g_list_next(a))
-+            {
-+                const char *item_name = (const char *)a->data;
-+                struct problem_item *item = problem_data_get_item_or_NULL(problem_data, item_name);
-+                if (!item)
-+                    continue;
-+                else if (item->flags & CD_FLAG_TXT)
-+                    attach_text_item(client, new_id_str, item_name, item);
-+                else if (item->flags & CD_FLAG_BIN)
-+                    attach_file_item(client, new_id_str, item_name, item);
-+            }
- 
-             bz = new_bug_info();
-             bz->bi_status = xstrdup("NEW");
-@@ -1340,18 +764,21 @@ int main(int argc, char **argv)
-     const char *comment = problem_data_get_content_or_NULL(problem_data, FILENAME_COMMENT);
-     if (comment && comment[0])
-     {
--        GList *comment_fmt_spec = load_bzrep_conf_file(fmt_file2);
--        struct strbuf *bzcomment_buf = strbuf_new();
--        generate_bz_comment(bzcomment_buf, problem_data, comment_fmt_spec);
--        char *bzcomment = strbuf_free_nobuf(bzcomment_buf);
--//TODO: free_comment_fmt_spec(comment_fmt_spec);
-+        problem_formatter_t *pf = problem_formatter_new();
-+        if (problem_formatter_load_file(pf, fmt_file2))
-+            error_msg_and_die("Invalid duplicate format file: '%s", fmt_file2);
-+
-+        problem_report_t *pr;
-+        if (problem_formatter_generate_report(pf, problem_data, &pr))
-+            error_msg_and_die("Failed to format duplicate comment from problem data");
-+
-+        const char *bzcomment = problem_report_get_description(pr);
- 
-         int dup_comment = is_comment_dup(bz->bi_comments, bzcomment);
-         if (!dup_comment)
-         {
-             log(_("Adding new comment to bug %d"), bz->bi_id);
-             rhbz_add_comment(client, bz->bi_id, bzcomment, 0);
--            free(bzcomment);
- 
-             const char *bt = problem_data_get_content_or_NULL(problem_data, FILENAME_BACKTRACE);
-             unsigned rating = 0;
-@@ -1369,10 +796,10 @@ int main(int argc, char **argv)
-             }
-         }
-         else
--        {
--            free(bzcomment);
-             log(_("Found the same comment in the bug history, not adding a new one"));
--        }
-+
-+        problem_report_free(pr);
-+        problem_formatter_free(pf);
-     }
- 
-  log_out:
--- 
-1.8.3.1
-
diff --git a/SOURCES/1001-lib-created-a-new-lib-file-for-reporters.patch b/SOURCES/1001-lib-created-a-new-lib-file-for-reporters.patch
deleted file mode 100644
index d0e74f9..0000000
--- a/SOURCES/1001-lib-created-a-new-lib-file-for-reporters.patch
+++ /dev/null
@@ -1,405 +0,0 @@
-From 8d9f7ba8a42ec1cfd39e6c249aef15e9295fe0a1 Mon Sep 17 00:00:00 2001
-From: Matej Habrnal <mhabrnal@redhat.com>
-Date: Tue, 13 Jan 2015 19:23:08 -0500
-Subject: [PATCH 1001/1015] lib: created a new lib file for reporters
-
-Moved some functions from rhbz.c to src/lib/reporters.c and src/lib/strbuf.c.
-
-Related to #272
-
-Signed-off-by: Matej Habrnal <mhabrnal@redhat.com>
----
- po/POTFILES.in                   |  1 +
- src/include/Makefile.am          |  3 +-
- src/include/internal_libreport.h |  5 +++
- src/include/reporters.h          | 36 ++++++++++++++++++
- src/lib/Makefile.am              |  3 +-
- src/lib/reporters.c              | 80 ++++++++++++++++++++++++++++++++++++++++
- src/lib/strbuf.c                 | 60 ++++++++++++++++++++++++++++++
- src/plugins/rhbz.c               | 78 +--------------------------------------
- src/plugins/rhbz.h               |  2 -
- 9 files changed, 188 insertions(+), 80 deletions(-)
- create mode 100644 src/include/reporters.h
- create mode 100644 src/lib/reporters.c
-
-diff --git a/po/POTFILES.in b/po/POTFILES.in
-index 4246e06..003e686 100644
---- a/po/POTFILES.in
-+++ b/po/POTFILES.in
-@@ -27,6 +27,7 @@ src/lib/parse_options.c
- src/lib/problem_data.c
- src/lib/problem_report.c
- src/lib/reported_to.c
-+src/lib/reporters.c
- src/lib/run_event.c
- src/plugins/abrt_rh_support.c
- src/plugins/report_Bugzilla.xml.in
-diff --git a/src/include/Makefile.am b/src/include/Makefile.am
-index 87e5e60..4d8c6a5 100644
---- a/src/include/Makefile.am
-+++ b/src/include/Makefile.am
-@@ -15,7 +15,8 @@ libreport_include_HEADERS = \
-     file_obj.h \
-     internal_libreport.h \
-     internal_abrt_dbus.h \
--    xml_parser.h
-+    xml_parser.h \
-+    reporters.h
- 
- if BUILD_UREPORT
- libreport_include_HEADERS += ureport.h
-diff --git a/src/include/internal_libreport.h b/src/include/internal_libreport.h
-index cf5730c..a867649 100644
---- a/src/include/internal_libreport.h
-+++ b/src/include/internal_libreport.h
-@@ -98,6 +98,7 @@ int vdprintf(int d, const char *format, va_list ap);
- #include "workflow.h"
- #include "file_obj.h"
- #include "libreport_types.h"
-+#include "reporters.h"
- 
- #ifdef __cplusplus
- extern "C" {
-@@ -107,6 +108,10 @@ extern "C" {
- int prefixcmp(const char *str, const char *prefix);
- #define suffixcmp libreport_suffixcmp
- int suffixcmp(const char *str, const char *suffix);
-+#define trim_all_whitespace libreport_trim_all_whitespace
-+char *trim_all_whitespace(const char *str);
-+#define shorten_string_to_length libreport_shorten_string_to_length
-+char *shorten_string_to_length(const char *str, unsigned length);
- #define strtrim libreport_strtrim
- char *strtrim(char *str);
- #define strtrimch libreport_strtrimch
-diff --git a/src/include/reporters.h b/src/include/reporters.h
-new file mode 100644
-index 0000000..d415b7f
---- /dev/null
-+++ b/src/include/reporters.h
-@@ -0,0 +1,36 @@
-+/*
-+    Copyright (C) 2014  ABRT team
-+    Copyright (C) 2014  RedHat Inc
-+
-+    This program is free software; you can redistribute it and/or modify
-+    it under the terms of the GNU General Public License as published by
-+    the Free Software Foundation; either version 2 of the License, or
-+    (at your option) any later version.
-+
-+    This program is distributed in the hope that it will be useful,
-+    but WITHOUT ANY WARRANTY; without even the implied warranty of
-+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+    GNU General Public License for more details.
-+
-+    You should have received a copy of the GNU General Public License along
-+    with this program; if not, write to the Free Software Foundation, Inc.,
-+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-+*/
-+
-+#ifndef REPORTERS_H
-+#define REPORTERS_H
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#define is_comment_dup libreport_is_comment_dup
-+int is_comment_dup(GList *comments, const char *comment);
-+#define comments_find_best_bt_rating libreport_comments_find_best_bt_rating
-+unsigned comments_find_best_bt_rating(GList *comments);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif
-diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
-index c11a42d..d41e543 100644
---- a/src/lib/Makefile.am
-+++ b/src/lib/Makefile.am
-@@ -58,7 +58,8 @@ libreport_la_SOURCES = \
-     xml_parser.c \
-     libreport_init.c \
-     global_configuration.c \
--    uriparser.c
-+    uriparser.c \
-+    reporters.c
- 
- libreport_la_CPPFLAGS = \
-     -I$(srcdir)/../include \
-diff --git a/src/lib/reporters.c b/src/lib/reporters.c
-new file mode 100644
-index 0000000..e3305ca
---- /dev/null
-+++ b/src/lib/reporters.c
-@@ -0,0 +1,80 @@
-+/*
-+    String buffer implementation
-+
-+    Copyright (C) 2015  RedHat inc.
-+
-+    This program is free software; you can redistribute it and/or modify
-+    it under the terms of the GNU General Public License as published by
-+    the Free Software Foundation; either version 2 of the License, or
-+    (at your option) any later version.
-+
-+    This program is distributed in the hope that it will be useful,
-+    but WITHOUT ANY WARRANTY; without even the implied warranty of
-+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+    GNU General Public License for more details.
-+
-+    You should have received a copy of the GNU General Public License along
-+    with this program; if not, write to the Free Software Foundation, Inc.,
-+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-+*/
-+
-+#include "internal_libreport.h"
-+
-+int
-+is_comment_dup(GList *comments, const char *comment)
-+{
-+    char * const trim_comment = trim_all_whitespace(comment);
-+    bool same_comments = false;
-+
-+    for (GList *l = comments; l && !same_comments; l = l->next)
-+    {
-+        const char * const comment_body = (const char *) l->data;
-+        char * const trim_comment_body = trim_all_whitespace(comment_body);
-+        same_comments = (strcmp(trim_comment_body, trim_comment) == 0);
-+        free(trim_comment_body);
-+    }
-+
-+    free(trim_comment);
-+    return same_comments;
-+}
-+
-+unsigned
-+comments_find_best_bt_rating(GList *comments)
-+{
-+    if (comments == NULL)
-+        return 0;
-+
-+    unsigned best_rating = 0;
-+    for (GList *l = comments; l; l = l->next)
-+    {
-+        char *comment_body = (char *) l->data;
-+
-+        char *start_rating_line = strstr(comment_body, FILENAME_RATING": ");
-+        if (!start_rating_line)
-+        {
-+            log_debug(_("Note does not contain rating"));
-+            continue;
-+        }
-+
-+        start_rating_line += strlen(FILENAME_RATING": ");
-+
-+        errno = 0;
-+        char *e;
-+        long rating = strtoul(start_rating_line, &e, 10);
-+        /*
-+         * Note: we intentionally check for '\n'. Any other terminator
-+         * (even '\0') is not ok in this case.
-+         */
-+        if (errno || e == start_rating_line || (*e != '\n' && *e != '\r') || (unsigned long)rating > UINT_MAX)
-+        {
-+            /* error / no digits / illegal trailing chars */
-+            continue;
-+        }
-+
-+        if (rating > best_rating)
-+            best_rating = rating;
-+    }
-+
-+    return best_rating;
-+}
-+
-diff --git a/src/lib/strbuf.c b/src/lib/strbuf.c
-index ef8bda8..f0cd1b8 100644
---- a/src/lib/strbuf.c
-+++ b/src/lib/strbuf.c
-@@ -37,6 +37,66 @@ int suffixcmp(const char *str, const char *suffix)
-         return strcmp(str + len_minus_suflen, suffix);
- }
- 
-+char *trim_all_whitespace(const char *str)
-+{
-+    char *trim = xzalloc(sizeof(char) * strlen(str) + 1);
-+    int i = 0;
-+    while (*str)
-+    {
-+        if (!isspace(*str))
-+            trim[i++] = *str;
-+        str++;
-+    }
-+
-+    return trim;
-+}
-+
-+/* If str is longer than max allowed length then
-+ * try to find first ' ' from the end of acceptable long str string
-+ *
-+ * If ' ' is found replace string after that by "..."
-+ *
-+ * If ' ' is NOT found in maximal allowed range, cut str string on
-+ * lenght (MAX_SUMMARY_LENGTH - strlen("...")) and append "..."
-+ *
-+ * If MAX_LENGTH is 15 and max allowed cut is 5:
-+ *
-+ *   0123456789ABCDEF -> 0123456789AB...
-+ *   0123456789 BCDEF -> 0123456789 ...
-+ *   012345 789ABCDEF -> 012345 789AB...
-+ */
-+char *
-+shorten_string_to_length(const char *str, unsigned length)
-+{
-+    char *dup_str = xstrdup(str);
-+    if (strlen(str) > length)
-+    {
-+        char *max_end = dup_str + (length - strlen("..."));
-+
-+        /* maximal number of characters to cut due to attempt cut dup_str
-+         * string after last ' '
-+         */
-+        int max_cut = 16;
-+
-+        /* start looking for ' ' one char before the last possible character */
-+        char *buf = max_end - 1;
-+        while (buf[0] != ' ' && max_cut--)
-+            --buf;
-+
-+        if (buf[0] != ' ')
-+            buf = max_end;
-+        else
-+            ++buf;
-+
-+        buf[0] = '.';
-+        buf[1] = '.';
-+        buf[2] = '.';
-+        buf[3] = '\0';
-+    }
-+
-+    return dup_str;
-+}
-+
- /*
-  * Trims whitespace characters both from left and right side of a string.
-  * Modifies the string in-place. Returns the trimmed string.
-diff --git a/src/plugins/rhbz.c b/src/plugins/rhbz.c
-index a227c62..fdcfff9 100644
---- a/src/plugins/rhbz.c
-+++ b/src/plugins/rhbz.c
-@@ -133,41 +133,6 @@ static GList *rhbz_comments(struct abrt_xmlrpc *ax, int bug_id)
-     return g_list_reverse(comments);
- }
- 
--static char *trim_all_whitespace(const char *str)
--{
--    func_entry();
--
--    char *trim = xzalloc(sizeof(char) * strlen(str) + 1);
--    int i = 0;
--    while (*str)
--    {
--        if (!isspace(*str))
--            trim[i++] = *str;
--        str++;
--    }
--
--    return trim;
--}
--
--int is_comment_dup(GList *comments, const char *comment)
--{
--    func_entry();
--
--    char * const trim_comment = trim_all_whitespace(comment);
--    bool same_comments = false;
--
--    for (GList *l = comments; l && !same_comments; l = l->next)
--    {
--        const char * const comment_body = (const char *) l->data;
--        char * const trim_comment_body = trim_all_whitespace(comment_body);
--        same_comments = (strcmp(trim_comment_body, trim_comment) == 0);
--        free(trim_comment_body);
--    }
--
--    free(trim_comment);
--    return same_comments;
--}
--
- static unsigned find_best_bt_rating_in_comments(GList *comments)
- {
-     func_entry();
-@@ -553,46 +518,7 @@ int rhbz_new_bug(struct abrt_xmlrpc *ax,
-     if (!duphash) duphash    = problem_data_get_content_or_NULL(problem_data,
-                                                                 "global_uuid");
- 
--    /* If summary is longer than max allowed summary length then
--     * try to find first ' ' from the end of acceptable long summary string
--     *
--     * If ' ' is found replace string after that by "..."
--     *
--     * If ' ' is NOT found in maximal allowed range, cut summary string on
--     * lenght (MAX_SUMMARY_LENGTH - strlen("...")) and append "..."
--     *
--     * If MAX_SUMMARY_LENGTH is 15 and max allowed cut is 5:
--     *
--     *   0123456789ABCDEF -> 0123456789AB...
--     *   0123456789 BCDEF -> 0123456789 ...
--     *   012345 789ABCDEF -> 012345 789AB...
--     */
--    char *summary = NULL;
--    if (strlen(bzsummary) > MAX_SUMMARY_LENGTH)
--    {
--        summary = xstrdup(bzsummary);
--        char *max_end = summary + (MAX_SUMMARY_LENGTH - strlen("..."));
--
--        /* maximal number of characters to cut due to attempt cut summary
--         * string after last ' '
--         */
--        int max_cut = 16;
--
--        /* start looking for ' ' one char before the last possible character */
--        char *buf = max_end - 1;
--        while (buf[0] != ' ' && max_cut--)
--            --buf;
--
--        if (buf[0] != ' ')
--            buf = max_end;
--        else
--            ++buf;
--
--        buf[0] = '.';
--        buf[1] = '.';
--        buf[2] = '.';
--        buf[3] = '\0';
--    }
-+    char *summary = shorten_string_to_length(bzsummary, MAX_SUMMARY_LENGTH);
- 
-     char *status_whiteboard = xasprintf("abrt_hash:%s", duphash);
- 
-@@ -604,7 +530,7 @@ int rhbz_new_bug(struct abrt_xmlrpc *ax,
-     abrt_xmlrpc_params_add_string(&env, params, "product", product);
-     abrt_xmlrpc_params_add_string(&env, params, "component", component);
-     abrt_xmlrpc_params_add_string(&env, params, "version", version);
--    abrt_xmlrpc_params_add_string(&env, params, "summary", (summary ? summary : bzsummary));
-+    abrt_xmlrpc_params_add_string(&env, params, "summary", summary);
-     abrt_xmlrpc_params_add_string(&env, params, "description", bzcomment);
-     abrt_xmlrpc_params_add_string(&env, params, "status_whiteboard", status_whiteboard);
- 
-diff --git a/src/plugins/rhbz.h b/src/plugins/rhbz.h
-index 15e7699..86632a3 100644
---- a/src/plugins/rhbz.h
-+++ b/src/plugins/rhbz.h
-@@ -105,8 +105,6 @@ int rhbz_attach_blob(struct abrt_xmlrpc *ax, const char *bug_id,
- int rhbz_attach_fd(struct abrt_xmlrpc *ax, const char *bug_id,
-                 const char *att_name, int fd, int flags);
- 
--int is_comment_dup(GList *comments, const char *comment);
--
- GList *rhbz_bug_cc(xmlrpc_value *result_xml);
- 
- struct bug_info *rhbz_bug_info(struct abrt_xmlrpc *ax, int bug_id);
--- 
-1.8.3.1
-
diff --git a/SOURCES/1003-ureport-set-url-to-public-faf-server.patch b/SOURCES/1003-ureport-set-url-to-public-faf-server.patch
deleted file mode 100644
index ee9a33c..0000000
--- a/SOURCES/1003-ureport-set-url-to-public-faf-server.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 2221fee2d3b930f171fa5181439ded9a1748ff00 Mon Sep 17 00:00:00 2001
-From: Matej Habrnal <mhabrnal@redhat.com>
-Date: Mon, 2 Feb 2015 16:31:51 +0100
-Subject: [PATCH 1003/1015] ureport: set url to public faf server
-
-Set url to public faf server because the private one doesn't return URL to
-known issues, bthash, possible solution etc.
-
-Signed-off-by: Matej Habrnal <mhabrnal@redhat.com>
----
- src/plugins/ureport.conf | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/plugins/ureport.conf b/src/plugins/ureport.conf
-index 2256a7f..b82b0e1 100644
---- a/src/plugins/ureport.conf
-+++ b/src/plugins/ureport.conf
-@@ -1,5 +1,5 @@
- # Base URL to uReport server
--# URL = http://bug-report.itos.redhat.com
-+URL = https://retrace.fedoraproject.org/faf
- 
- # no means that ssl certificates will not be checked
- # SSLVerify = no
--- 
-1.8.3.1
-
diff --git a/SOURCES/1004-conf-changed-URL-for-sending-uReport.patch b/SOURCES/1004-conf-changed-URL-for-sending-uReport.patch
deleted file mode 100644
index f0386e8..0000000
--- a/SOURCES/1004-conf-changed-URL-for-sending-uReport.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From e8bb90e42d0356cdcf91d22c9deb6635d1d3c376 Mon Sep 17 00:00:00 2001
-From: Matej Habrnal <mhabrnal@redhat.com>
-Date: Mon, 2 Feb 2015 21:41:36 +0100
-Subject: [PATCH 1004/1015] conf: changed URL for sending uReport
-
-Changed faf server url in report_uReport.xml.in.
-uReports are sending to https://retrace.fedoraproject.org/faf by default.
-
-Signed-off-by: Matej Habrnal <mhabrnal@redhat.com>
----
- src/plugins/report_uReport.xml.in | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/plugins/report_uReport.xml.in b/src/plugins/report_uReport.xml.in
-index b997851..eca30e0 100644
---- a/src/plugins/report_uReport.xml.in
-+++ b/src/plugins/report_uReport.xml.in
-@@ -12,7 +12,7 @@
-             <_label>uReport Server URL</_label>
-             <allow-empty>no</allow-empty>
-             <_description>Address of uReport webservice</_description>
--            <default-value>http://bug-report.itos.redhat.com</default-value>
-+            <default-value>https://retrace.fedoraproject.org/faf</default-value>
-         </option>
-         <option type="text" name="uReport_ContactEmail">
-             <_label>Contact email address</_label>
--- 
-1.8.3.1
-
diff --git a/SOURCES/1005-reporter-mantisbt-first-version-of-the-reporter-mant.patch b/SOURCES/1005-reporter-mantisbt-first-version-of-the-reporter-mant.patch
deleted file mode 100644
index b267fe4..0000000
--- a/SOURCES/1005-reporter-mantisbt-first-version-of-the-reporter-mant.patch
+++ /dev/null
@@ -1,2659 +0,0 @@
-From be6691dc649962cad24ad7d7a89451b2c43de606 Mon Sep 17 00:00:00 2001
-From: Matej Habrnal <mhabrnal@redhat.com>
-Date: Tue, 13 Jan 2015 19:30:27 -0500
-Subject: [PATCH 1005/1015] reporter-mantisbt: first version of the
- reporter-mantisbt
-
-Related to #272
-
-Signed-off-by: Matej Habrnal <mhabrnal@redhat.com>
----
- configure.ac                                   |   33 +
- po/POTFILES.in                                 |   11 +
- src/plugins/Makefile.am                        |   43 +-
- src/plugins/centos_report_event.conf           |   37 +
- src/plugins/mantisbt.c                         | 1111 ++++++++++++++++++++++++
- src/plugins/mantisbt.conf                      |    8 +
- src/plugins/mantisbt.h                         |  140 +++
- src/plugins/mantisbt_format.conf               |   59 ++
- src/plugins/mantisbt_formatdup.conf            |   65 ++
- src/plugins/report_CentOSBugTracker.conf       |    4 +
- src/plugins/report_CentOSBugTracker.xml.in     |   65 ++
- src/plugins/reporter-mantisbt.c                |  696 +++++++++++++++
- src/workflows/Makefile.am                      |   15 +-
- src/workflows/report_centos.conf               |   31 +
- src/workflows/workflow_CentOSCCpp.xml.in       |   12 +
- src/workflows/workflow_CentOSJava.xml.in       |   11 +
- src/workflows/workflow_CentOSKerneloops.xml.in |   11 +
- src/workflows/workflow_CentOSLibreport.xml.in  |    9 +
- src/workflows/workflow_CentOSPython.xml.in     |   11 +
- src/workflows/workflow_CentOSPython3.xml.in    |   11 +
- src/workflows/workflow_CentOSVmcore.xml.in     |   12 +
- src/workflows/workflow_CentOSXorg.xml.in       |    9 +
- 22 files changed, 2402 insertions(+), 2 deletions(-)
- create mode 100644 src/plugins/centos_report_event.conf
- create mode 100644 src/plugins/mantisbt.c
- create mode 100644 src/plugins/mantisbt.conf
- create mode 100644 src/plugins/mantisbt.h
- create mode 100644 src/plugins/mantisbt_format.conf
- create mode 100644 src/plugins/mantisbt_formatdup.conf
- create mode 100644 src/plugins/report_CentOSBugTracker.conf
- create mode 100644 src/plugins/report_CentOSBugTracker.xml.in
- create mode 100644 src/plugins/reporter-mantisbt.c
- create mode 100644 src/workflows/report_centos.conf
- create mode 100644 src/workflows/workflow_CentOSCCpp.xml.in
- create mode 100644 src/workflows/workflow_CentOSJava.xml.in
- create mode 100644 src/workflows/workflow_CentOSKerneloops.xml.in
- create mode 100644 src/workflows/workflow_CentOSLibreport.xml.in
- create mode 100644 src/workflows/workflow_CentOSPython.xml.in
- create mode 100644 src/workflows/workflow_CentOSPython3.xml.in
- create mode 100644 src/workflows/workflow_CentOSVmcore.xml.in
- create mode 100644 src/workflows/workflow_CentOSXorg.xml.in
-
-diff --git a/configure.ac b/configure.ac
-index a7f67c9..83c1a52 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -144,6 +144,39 @@ do
- done
- fi dnl end NO_BUGZILLA
- 
-+AC_ARG_WITH(mantisbt,
-+AS_HELP_STRING([--with-mantisbt],[use MantisBT plugin (default is YES)]),
-+LIBREPORT_PARSE_WITH([mantisbt]))
-+
-+if test -z "$NO_MANTISBT"; then
-+AM_CONDITIONAL(BUILD_MANTISBT, true)
-+
-+# enable mantisbt & deps translations
-+for FILE in `grep -e "#.*antisbt.*" -e "#.*naconda.*" po/POTFILES.in`
-+do
-+  sed -ie "s,$FILE,${FILE:1}," po/POTFILES.in
-+  sed -ie "\,^${FILE:1}$,d" po/POTFILES.skip
-+done
-+else
-+AM_CONDITIONAL(BUILD_MANTISBT, false)
-+
-+# disablie mantisbt & deps translations
-+for FILE in `grep -e "antisbt" -e "naconda" po/POTFILES.in`
-+do
-+  if test "${FILE:0:1}" = "#"
-+  then
-+    continue
-+  fi
-+
-+  sed -ie "s,$FILE,#$FILE," po/POTFILES.in
-+  grep "$FILE" po/POTFILES.skip > /dev/null 2>&1
-+  if test $?
-+  then
-+    echo "$FILE" >> po/POTFILES.skip
-+  fi
-+done
-+fi dnl end NO_MANTISBT
-+
- AC_PATH_PROG([PYTHON_CONFIG], [python-config], [no])
- [if test "$PYTHON_CONFIG" = "no"]
- [then]
-diff --git a/po/POTFILES.in b/po/POTFILES.in
-index 003e686..9cf8f72 100644
---- a/po/POTFILES.in
-+++ b/po/POTFILES.in
-@@ -39,6 +39,8 @@ src/plugins/reporter-print.c
- src/plugins/reporter-rhtsupport.c
- src/plugins/reporter-rhtsupport-parse.c
- src/plugins/reporter-upload.c
-+src/plugins/reporter-mantisbt.c
-+src/plugins/report_CentOSBugTracker.xml.in
- src/plugins/report_Kerneloops.xml.in
- src/plugins/report_Logger.xml.in
- src/plugins/report_Mailx.xml.in
-@@ -47,12 +49,21 @@ src/plugins/report_Uploader.xml.in
- src/plugins/report_uReport.xml.in
- src/plugins/report_EmergencyAnalysis.xml.in
- src/plugins/rhbz.c
-+src/plugins/mantisbt.c
- src/plugins/reporter-ureport.c
- src/report-newt/report-newt.c
- src/workflows/workflow_AnacondaFedora.xml.in
- src/workflows/workflow_AnacondaRHEL.xml.in
- src/workflows/workflow_AnacondaRHELBugzilla.xml.in
- src/workflows/workflow_AnacondaUpload.xml.in
-+src/workflows/workflow_CentOSCCpp.xml.in
-+src/workflows/workflow_CentOSJava.xml.in
-+src/workflows/workflow_CentOSKerneloops.xml.in
-+src/workflows/workflow_CentOSLibreport.xml.in
-+src/workflows/workflow_CentOSPython.xml.in
-+src/workflows/workflow_CentOSPython3.xml.in
-+src/workflows/workflow_CentOSVmcore.xml.in
-+src/workflows/workflow_CentOSXorg.xml.in
- src/workflows/workflow_FedoraCCpp.xml.in
- src/workflows/workflow_FedoraKerneloops.xml.in
- src/workflows/workflow_FedoraPython.xml.in
-diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
-index 8e1a166..fd3f477 100644
---- a/src/plugins/Makefile.am
-+++ b/src/plugins/Makefile.am
-@@ -7,6 +7,11 @@ reporters_bin += \
-     report
- endif
- 
-+if BUILD_MANTISBT
-+reporters_bin += \
-+    reporter-mantisbt
-+endif
-+
- if BUILD_UREPORT
- reporters_bin +=  reporter-ureport
- endif
-@@ -34,6 +39,12 @@ reporters_plugin_format_conf += bugzilla_format.conf \
-     bugzilla_formatdup_anaconda.conf
- endif
- 
-+if BUILD_MANTISBT
-+reporters_plugin_conf += mantisbt.conf
-+reporters_plugin_format_conf += mantisbt_format.conf \
-+    mantisbt_formatdup.conf
-+endif
-+
- defaultreportpluginsconfdir = $(DEFAULT_REPORT_PLUGINS_CONF_DIR)
- dist_defaultreportpluginsconf_DATA = $(reporters_plugin_conf) \
-     rhtsupport.conf \
-@@ -54,6 +65,12 @@ reporters_events += report_Bugzilla.xml
- reporters_events_conf += report_Bugzilla.conf
- endif
- 
-+if BUILD_MANTISBT
-+reporters_events += report_CentOSBugTracker.xml
-+
-+reporters_events_conf += report_CentOSBugTracker.conf
-+endif
-+
- if BUILD_UREPORT
- reporters_events += report_uReport.xml
- endif
-@@ -79,7 +96,8 @@ dist_eventsdef_DATA = \
-     print_event.conf \
-     rhtsupport_event.conf \
-     uploader_event.conf \
--    emergencyanalysis_event.conf
-+    emergencyanalysis_event.conf \
-+    centos_report_event.conf
- 
- reporters_extra_dist =
- if BUILD_BUGZILLA
-@@ -127,6 +145,29 @@ reporter_bugzilla_LDADD = \
-     ../lib/libreport.la
- endif
- 
-+if BUILD_MANTISBT
-+reporter_mantisbt_SOURCES = \
-+    reporter-mantisbt.c mantisbt.c mantisbt.h
-+reporter_mantisbt_CPPFLAGS = \
-+    -I$(srcdir)/../include \
-+    -I$(srcdir)/../lib \
-+    -DBIN_DIR=\"$(bindir)\" \
-+    -DCONF_DIR=\"$(CONF_DIR)\" \
-+    -DLOCALSTATEDIR='"$(localstatedir)"' \
-+    -DDEBUG_DUMPS_DIR=\"$(DEBUG_DUMPS_DIR)\" \
-+    -DDEBUG_INFO_DIR=\"$(DEBUG_INFO_DIR)\" \
-+    -DPLUGINS_LIB_DIR=\"$(PLUGINS_LIB_DIR)\" \
-+    -DPLUGINS_CONF_DIR=\"$(REPORT_PLUGINS_CONF_DIR)\" \
-+    $(GLIB_CFLAGS) \
-+    $(LIBREPORT_CFLAGS) \
-+    $(LIBXML_CFLAGS) \
-+    -D_GNU_SOURCE
-+reporter_mantisbt_LDADD = \
-+    $(GLIB_LIBS) \
-+    ../lib/libreport-web.la \
-+    ../lib/libreport.la
-+endif
-+
- reporter_rhtsupport_SOURCES = \
-     abrt_rh_support.h abrt_rh_support.c \
-     reporter-rhtsupport.h \
-diff --git a/src/plugins/centos_report_event.conf b/src/plugins/centos_report_event.conf
-new file mode 100644
-index 0000000..53f12d8
---- /dev/null
-+++ b/src/plugins/centos_report_event.conf
-@@ -0,0 +1,37 @@
-+EVENT=report_CentOSBugTracker analyzer=xorg
-+    reporter-mantisbt
-+
-+EVENT=report_CentOSBugTracker analyzer=Kerneloops
-+    reporter-mantisbt
-+
-+EVENT=report_CentOSBugTracker analyzer=vmcore
-+        reporter-mantisbt
-+
-+EVENT=report_CentOSBugTracker analyzer=Python component!=anaconda
-+        test -f component || abrt-action-save-package-data
-+        reporter-mantisbt \
-+                -c /etc/libreport/plugins/mantisbt.conf \
-+                -F /etc/libreport/plugins/mantisbt_format.conf \
-+                -A /etc/libreport/plugins/mantisbt_formatdup.conf
-+
-+EVENT=report_CentOSBugTracker analyzer=Python3 component!=anaconda
-+        test -f component || abrt-action-save-package-data
-+        reporter-mantisbt \
-+                -c /etc/libreport/plugins/mantisbt.conf \
-+                -F /etc/libreport/plugins/mantisbt_format.conf \
-+                -A /etc/libreport/plugins/mantisbt_formatdup.conf
-+
-+EVENT=report_CentOSBugTracker analyzer=CCpp duphash!=
-+        test -f component || abrt-action-save-package-data
-+        component="`cat component`"
-+        format="mantisbt_format.conf"
-+        test -f "/etc/libreport/plugins/mantisbt_format_$component.conf" \
-+                && format="mantisbt_format_$component.conf"
-+        formatdup="mantisbt_formatdup.conf"
-+        test -f "/etc/libreport/plugins/mantisbt_formatdup_$component.conf" \
-+                && formatdup="mantisbt_formatdup_$component.conf"
-+        reporter-mantisbt \
-+                -c /etc/libreport/plugins/mantisbt.conf \
-+                -F "/etc/libreport/plugins/$format" \
-+                -A "/etc/libreport/plugins/$formatdup"
-+
-diff --git a/src/plugins/mantisbt.c b/src/plugins/mantisbt.c
-new file mode 100644
-index 0000000..1c496b4
---- /dev/null
-+++ b/src/plugins/mantisbt.c
-@@ -0,0 +1,1111 @@
-+/*
-+    Copyright (C) 2014  ABRT team
-+    Copyright (C) 2014  RedHat Inc
-+
-+    This program is free software; you can redistribute it and/or modify
-+    it under the terms of the GNU General Public License as published by
-+    the Free Software Foundation; either version 2 of the License, or
-+    (at your option) any later version.
-+
-+    This program is distributed in the hope that it will be useful,
-+    but WITHOUT ANY WARRANTY; without even the implied warranty of
-+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+    GNU General Public License for more details.
-+
-+    You should have received a copy of the GNU General Public License along
-+    with this program; if not, write to the Free Software Foundation, Inc.,
-+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-+*/
-+
-+#include <curl/curl.h>
-+
-+#include <libxml/xmlreader.h>
-+
-+#include "internal_libreport.h"
-+#include "libreport_curl.h"
-+#include "mantisbt.h"
-+#include "client.h"
-+
-+/*
-+ * SOAP
-+*/
-+
-+#define XML_VERSION "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-+
-+/* fprint string */
-+#define SOAP_TEMPLATE \
-+    "<SOAP-ENV:Envelope xmlns:ns3=\"http://schemas.xmlsoap.org/soap/encoding/\" " \
-+        "xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" " \
-+        "xmlns:ns0=\"http://schemas.xmlsoap.org/soap/encoding/\" " \
-+        "xmlns:ns1=\"http://schemas.xmlsoap.org/soap/envelope/\" " \
-+        "xmlns:ns2=\"http://www.w3.org/2001/XMLSchema\" " \
-+        "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " \
-+        "xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" " \
-+        "SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" \
-+    "<SOAP-ENV:Header/>" \
-+    "<ns1:Body>" \
-+        "<ns3:%s>" \
-+        "</ns3:%s>" \
-+    "</ns1:Body>" \
-+    "</SOAP-ENV:Envelope>"
-+
-+#define MAX_SUMMARY_LENGTH  128
-+#define CUSTOMFIELD_DUPHASH "abrt_hash"
-+#define CUSTOMFIELD_URL "URL"
-+#define MAX_HOPS 5
-+
-+/* MantisBT limit is 2MB by default
-+ */
-+#define MANTISBT_MAX_FILE_UPLOAD_SIZE (2 * 1024 * 1024)
-+
-+typedef struct mantisbt_custom_fields
-+{
-+    char *cf_abrt_hash_id;
-+    char *cf_url_id;
-+} mantisbt_custom_fields_t;
-+
-+/*
-+ * MantisBT settings issue info
-+ */
-+void
-+mantisbt_settings_free(mantisbt_settings_t *s)
-+{
-+    if (s == NULL)
-+        return;
-+
-+    free(s->m_login);
-+    free(s->m_password);
-+    free(s->m_project);
-+    free(s->m_project_id);
-+    free(s->m_project_version);
-+}
-+
-+/*
-+ * MantisBT issue info
-+ */
-+mantisbt_issue_info_t *
-+mantisbt_issue_info_new()
-+{
-+    mantisbt_issue_info_t *info = xzalloc(sizeof(mantisbt_issue_info_t));
-+    info->mii_id = -1;
-+    info->mii_dup_id = -1;
-+
-+    return info;
-+}
-+
-+void
-+mantisbt_issue_info_free(mantisbt_issue_info_t *info)
-+{
-+    if (info == NULL)
-+        return;
-+
-+    free(info->mii_status);
-+    free(info->mii_resolution);
-+    free(info->mii_reporter);
-+    free(info->mii_project);
-+
-+    list_free_with_free(info->mii_notes);
-+    list_free_with_free(info->mii_attachments);
-+
-+    free(info);
-+}
-+
-+mantisbt_issue_info_t *
-+mantisbt_find_origin_bug_closed_duplicate(mantisbt_settings_t *settings, mantisbt_issue_info_t *info)
-+{
-+    mantisbt_issue_info_t *info_tmp = mantisbt_issue_info_new();
-+    info_tmp->mii_id = info->mii_id;
-+    info_tmp->mii_dup_id = info->mii_dup_id;
-+
-+    for (int ii = 0; ii <= MAX_HOPS; ii++)
-+    {
-+        if (ii == MAX_HOPS)
-+            error_msg_and_die(_("MantisBT couldn't find parent of issue %d"), info->mii_id);
-+
-+        log("Issue %d is a duplicate, using parent issue %d", info_tmp->mii_id, info_tmp->mii_dup_id);
-+        int issue_id = info_tmp->mii_dup_id;
-+
-+        mantisbt_issue_info_free(info_tmp);
-+        info_tmp = mantisbt_get_issue_info(settings, issue_id);
-+
-+        // found a issue which is not CLOSED as DUPLICATE
-+        if (info_tmp->mii_dup_id == -1)
-+            break;
-+    }
-+
-+    return info_tmp;
-+}
-+
-+/*
-+ * SOAP request
-+ */
-+static soap_request_t *
-+soap_request_new()
-+{
-+    soap_request_t *req = xzalloc(sizeof(*req));
-+
-+    return req;
-+}
-+
-+void
-+soap_request_free(soap_request_t *req)
-+{
-+    if (req == NULL)
-+        return;
-+
-+    if (req->sr_root != NULL)
-+        xmlFreeDoc(req->sr_root->doc);
-+
-+    free(req);
-+
-+    return;
-+}
-+
-+static xmlNodePtr
-+soap_node_get_next_element_node(xmlNodePtr node)
-+{
-+    for (; node != NULL; node = node->next)
-+        if (node->type == XML_ELEMENT_NODE)
-+            break;
-+
-+    return node;
-+}
-+
-+static xmlNodePtr
-+soap_node_get_child_element(xmlNodePtr node)
-+{
-+    if (node == NULL)
-+        error_msg_and_die(_("SOAP: Failed to get child element because of no parent."));
-+
-+    return soap_node_get_next_element_node(node->xmlChildrenNode);
-+}
-+
-+static xmlNodePtr
-+soap_node_get_next_sibling(xmlNodePtr node)
-+{
-+    if (node == NULL)
-+        error_msg_and_die(_("SOAP: Failed to get next element because of no node."));
-+
-+    return soap_node_get_next_element_node(node->next);
-+}
-+
-+static xmlNodePtr
-+soap_node_get_child_node(xmlNodePtr parent, const char *name)
-+{
-+    if (parent == NULL)
-+        error_msg_and_die(_("SOAP: Failed to get child node because of no parent."));
-+
-+    xmlNodePtr node;
-+    for (node = soap_node_get_child_element(parent); node != NULL; node = soap_node_get_next_sibling(node))
-+    {
-+        if (xmlStrcmp(node->name, BAD_CAST name) == 0)
-+            return node;
-+    }
-+
-+    return NULL;
-+}
-+
-+soap_request_t *
-+soap_request_new_for_method(const char *method)
-+{
-+    char *xml_str = xasprintf(SOAP_TEMPLATE, method, method);
-+
-+    xmlDocPtr doc = xmlParseDoc(BAD_CAST xml_str);
-+    free(xml_str);
-+
-+    if (doc == NULL)
-+        error_msg_and_die(_("SOAP: Failed to parse xml during creating request."));
-+
-+    soap_request_t *req = soap_request_new();
-+
-+    req->sr_root = xmlDocGetRootElement(doc);
-+    if (req->sr_root == NULL)
-+    {
-+        soap_request_free(req);
-+        error_msg_and_die(_("SOAP: Failed to get xml root element."));
-+    }
-+
-+    req->sr_body = soap_node_get_child_node(req->sr_root, "Body");
-+    req->sr_method = soap_node_get_child_node(req->sr_body, method);
-+
-+    return req;
-+}
-+
-+static xmlNodePtr
-+soap_node_add_child_node(xmlNodePtr node, const char *name, const char *type, const char *value)
-+{
-+    if (node == NULL || name == NULL)
-+        error_msg_and_die(_("SOAP: Failed to add a new child node because of no node or no child name."));
-+
-+    xmlNodePtr new_node = xmlNewTextChild(node, /* namespace */ NULL, BAD_CAST name, BAD_CAST value);
-+
-+    if (new_node == NULL)
-+        error_msg_and_die(_("SOAP: Failed to create a new xml child item."));
-+
-+    if (type != NULL)
-+    {
-+        if (xmlNewProp(new_node, BAD_CAST "xsi:type", BAD_CAST type) == NULL)
-+            error_msg_and_die(_("SOAP: Failed to create a new property."));
-+    }
-+
-+    return new_node;
-+}
-+
-+void
-+soap_request_add_method_parameter(soap_request_t *req, const char *name, const char *type, const char *value)
-+{
-+    if (req == NULL || req->sr_method == NULL)
-+        error_msg_and_die(_("SOAP: Failed to add method parametr."));
-+
-+    soap_node_add_child_node(req->sr_method, name, type, value);
-+    return;
-+}
-+
-+void
-+soap_request_add_credentials_parameter(soap_request_t *req, const mantisbt_settings_t *settings)
-+{
-+    soap_request_add_method_parameter(req, "username", SOAP_STRING, settings->m_login);
-+    soap_request_add_method_parameter(req, "password", SOAP_STRING, settings->m_password);
-+
-+    return;
-+}
-+
-+static void
-+soap_add_new_issue_parameters(soap_request_t *req,
-+                               const char *project,
-+                               const char *version,
-+                               const char *category,
-+                               const char *summary,
-+                               const char *description,
-+                               const char *additional_information,
-+                               bool private,
-+                               mantisbt_custom_fields_t *fields,
-+                               const char *duphash,
-+                               const char *tracker_url)
-+{
-+    if (req == NULL || req->sr_method == NULL)
-+        error_msg_and_die(_("SOAP: Failed to add new issue parametrs."));
-+
-+    if (project == NULL || category == NULL || summary == NULL || description == NULL)
-+        error_msg_and_die(_("SOAP: Failed to add new issue parameters because the required items are missing."));
-+
-+    xmlNodePtr issue_node = soap_node_add_child_node(req->sr_method, "issue", SOAP_ISSUEDATA, /* content */ NULL);
-+
-+    // project
-+    xmlNodePtr project_node = soap_node_add_child_node(issue_node, "project", SOAP_OBJECTREF, /* content */ NULL);
-+    soap_node_add_child_node(project_node, "name", SOAP_STRING, project);
-+
-+    // view status
-+    xmlNodePtr view_node = soap_node_add_child_node(issue_node, "view_state", SOAP_OBJECTREF, /* content */ NULL);
-+    soap_node_add_child_node(view_node, "name", SOAP_STRING, (private) ? "private" : "public");
-+
-+    /* if any custom field exists */
-+    int custom_fields_count = 0;
-+    xmlNodePtr duphash_node;
-+    if (fields->cf_abrt_hash_id != NULL || fields->cf_url_id != NULL)
-+        duphash_node = soap_node_add_child_node(issue_node, "custom_fields", SOAP_CUSTOMFIELD_ARRAY, /* content */ NULL);
-+
-+    // custom fields (duphash and URL to tracker)
-+    xmlNodePtr item_node, field_node;
-+    if (fields->cf_abrt_hash_id != NULL)
-+    {
-+        item_node = soap_node_add_child_node(duphash_node, "item", SOAP_CUSTOMFIELD, /* content */ NULL);
-+        field_node = soap_node_add_child_node(item_node, "field", SOAP_OBJECTREF, /* content */ NULL);
-+        soap_node_add_child_node(field_node, "id", SOAP_INTEGER, /* custom_field id */ fields->cf_abrt_hash_id);
-+        soap_node_add_child_node(item_node, "value", SOAP_STRING, duphash);
-+        ++custom_fields_count;
-+    }
-+
-+    // if tracker url exists, attach it to the issue
-+    if (tracker_url != NULL && fields->cf_url_id != NULL)
-+    {
-+        item_node = soap_node_add_child_node(duphash_node, "item", SOAP_CUSTOMFIELD, /* content */ NULL);
-+        field_node = soap_node_add_child_node(item_node, "field", SOAP_OBJECTREF, /* content */ NULL);
-+        soap_node_add_child_node(field_node, "id", SOAP_INTEGER, /* custom_field */ fields->cf_url_id);
-+        soap_node_add_child_node(item_node, "value", SOAP_STRING, tracker_url);
-+        ++custom_fields_count;
-+    }
-+
-+    if (custom_fields_count > 0)
-+    {
-+        char *type = xasprintf("%s[%i]", SOAP_CUSTOMFIELD, custom_fields_count);
-+
-+        if (xmlNewProp(duphash_node, BAD_CAST "ns3:arrayType", BAD_CAST type) == NULL)
-+            error_msg_and_die(_("SOAP: Failed to create a new property in custom fields."));
-+
-+        free(type);
-+    }
-+
-+    soap_node_add_child_node(issue_node, "os_build", SOAP_STRING, version);
-+    soap_node_add_child_node(issue_node, "category", SOAP_STRING, category);
-+    soap_node_add_child_node(issue_node, "summary", SOAP_STRING, summary);
-+    soap_node_add_child_node(issue_node, "description", SOAP_STRING, description);
-+    soap_node_add_child_node(issue_node, "additional_information", SOAP_STRING, additional_information);
-+
-+    return;
-+}
-+
-+char *
-+soap_request_to_str(const soap_request_t *req)
-+{
-+    if (req == NULL || req->sr_root == NULL || req->sr_root->doc == NULL)
-+        error_msg_and_die(_("SOAP: Failed to create SOAP string because of invalid function arguments."));
-+
-+    xmlBufferPtr buffer = xmlBufferCreate();
-+    int err = xmlNodeDump(buffer, req->sr_root->doc, req->sr_root, 1, /* formatting */ 0);
-+    if (err == -1)
-+    {
-+        xmlBufferFree(buffer);
-+        error_msg_and_die(_("SOAP: Failed to dump xml node."));
-+    }
-+
-+    char *ret = xasprintf("%s%s", XML_VERSION, (const char *) xmlBufferContent(buffer));
-+    xmlBufferFree(buffer);
-+
-+    return ret;
-+}
-+
-+#if 0
-+void
-+soap_request_print(soap_request_t *req)
-+{
-+    if (req == NULL || req->sr_root == NULL || req->sr_root->doc == NULL)
-+        error_msg_and_die(_("SOAP: Failed to print SOAP string."));
-+
-+    xmlBufferPtr buffer = xmlBufferCreate();
-+    int err = xmlNodeDump(buffer, req->sr_root->doc, req->sr_root, 1, /* formatting */ 0);
-+    if (err == -1)
-+    {
-+        xmlBufferFree(buffer);
-+        error_msg_and_die(_("Failed to dump xml node."));
-+    }
-+
-+    puts((const char *) xmlBufferContent(buffer));
-+
-+    xmlBufferFree(buffer);
-+    return;
-+}
-+#endif
-+
-+static bool
-+reader_move_reader_if_node_type_is_element_with_name_and_verify_its_value(xmlTextReaderPtr reader, const char *name)
-+{
-+    /* is not element node */
-+    if (xmlTextReaderNodeType(reader) != XML_ELEMENT_NODE)
-+        return false;
-+
-+    /* is not required name */
-+    if (xmlStrcmp(xmlTextReaderConstName(reader), BAD_CAST name) != 0)
-+        return false;
-+
-+    /* read next node */
-+    if (xmlTextReaderRead(reader) != 1)
-+        return false;
-+
-+    /* no value node */
-+    if (xmlTextReaderHasValue(reader) == 0)
-+        return false;
-+
-+    /* no text node */
-+    if (xmlTextReaderNodeType(reader) != XML_TEXT_NODE)
-+        return false;
-+
-+    return true;
-+}
-+
-+static void
-+reader_find_element_by_name(xmlTextReaderPtr reader, const char *name)
-+{
-+    while (xmlTextReaderRead(reader) == 1)
-+    {
-+        /* is not element node */
-+        if (xmlTextReaderNodeType(reader) != XML_ELEMENT_NODE)
-+            continue;
-+
-+        /* is not required name */
-+        if (xmlStrcmp(xmlTextReaderConstName(reader), BAD_CAST name) != 0)
-+            continue;
-+
-+        break;
-+    }
-+
-+    return;
-+}
-+
-+/* It is not possible to search only by name because the response contains
-+ * different node with the same name. (e.g. id - user id, project id, issue id etc.)
-+ * We are interested in only about issues id which is located at a different depth than others.
-+ * ...
-+ *   <item xsi:type="ns1:IssueData">
-+ *      <id xsi:type="xsd:integer">10</id>      <-- This is issue ID (required)
-+ *      <view_state xsi:type="ns1:ObjectRef">
-+ *          <id xsi:type="xsd:integer">10</id>  <-- This is view_state ID (not required)
-+ *          <name xsi:type="xsd:string">public</name>
-+ *      </view_state>
-+ *      <project xsi:type="ns1:ObjectRef">
-+ *          <id xsi:type="xsd:integer">1</id>   <-- This is project ID (not required)
-+ *          <name xsi:type="xsd:string">test</name>
-+ *      </project>
-+ * ...
-+ */
-+static GList *
-+response_values_at_depth_by_name(const char *xml, const char *name, int depth)
-+{
-+    xmlDocPtr doc = xmlParseDoc(BAD_CAST xml);
-+    if (doc == NULL)
-+        error_msg_and_die(_("SOAP: Failed to parse xml (searching value at depth by name)."));
-+
-+    xmlTextReaderPtr reader = xmlReaderWalker(doc);
-+    if (reader == NULL)
-+        error_msg_and_die(_("SOAP: Failed to create xml text reader."));
-+
-+    GList *result = NULL;
-+
-+    const xmlChar *value;
-+    while (xmlTextReaderRead(reader) == 1)
-+    {
-+        /* is not right depth */
-+        if (depth != -1 && xmlTextReaderDepth(reader) != depth)
-+            continue;
-+
-+        if (reader_move_reader_if_node_type_is_element_with_name_and_verify_its_value(reader, name) == false)
-+            continue;
-+
-+        if ((value = xmlTextReaderConstValue(reader)) != NULL)
-+            result = g_list_append(result, xstrdup((const char *) value));
-+    }
-+    xmlFreeTextReader(reader);
-+
-+    return result;
-+}
-+
-+/*
-+ * Finds an element named 'elem' and returns a text of a child named 'name'
-+ *
-+ * Example:
-+ *  For
-+ *  <elem>
-+ *      <id>1</id>
-+ *      <name>foo</name>
-+ *  </elem>
-+ *
-+ *  returns "foo"
-+ */
-+static char *
-+response_get_name_value_of_element(const char *xml, const char *element)
-+{
-+    xmlDocPtr doc = xmlParseDoc(BAD_CAST xml);
-+    if (doc == NULL)
-+        error_msg_and_die(_("SOAP: Failed to parse xml."));
-+
-+    xmlTextReaderPtr reader = xmlReaderWalker(doc);
-+    if (reader == NULL)
-+        error_msg_and_die(_("SOAP: Failed to create xml text reader."));
-+
-+    const xmlChar *value = NULL;
-+
-+    reader_find_element_by_name(reader, element);
-+
-+    /* find 'name' element and return its text */
-+    while (xmlTextReaderRead(reader) == 1)
-+    {
-+        if (reader_move_reader_if_node_type_is_element_with_name_and_verify_its_value(reader, "name") == false)
-+            continue;
-+
-+        if ((value = xmlTextReaderConstValue(reader)) != NULL)
-+            break;
-+    }
-+    xmlFreeTextReader(reader);
-+
-+    return (char *) value;
-+}
-+
-+static int
-+response_get_id_of_relatedto_issue(const char *xml)
-+{
-+    xmlDocPtr doc = xmlParseDoc(BAD_CAST xml);
-+    if (doc == NULL)
-+        error_msg_and_die(_("SOAP: Failed to parse xml (get related to issue)."));
-+
-+    xmlTextReaderPtr reader = xmlReaderWalker(doc);
-+    if (reader == NULL)
-+        error_msg_and_die(_("SOAP: Failed to create xml text reader."));
-+
-+    const xmlChar *value = NULL;
-+    const xmlChar *id = NULL;
-+
-+    /* find relationships section */
-+    reader_find_element_by_name(reader, "relationships");
-+
-+    /* find "name" value of 'name' element */
-+    while (xmlTextReaderRead(reader) == 1)
-+    {
-+        /* find type of relattionship */
-+        if (reader_move_reader_if_node_type_is_element_with_name_and_verify_its_value(reader, "name") == false)
-+            continue;
-+
-+        if ((value = xmlTextReaderConstValue(reader)) == NULL)
-+            continue;
-+
-+        /* we need 'duplicate of' realtionship type */
-+        if (xmlStrcmp(value, BAD_CAST "duplicate of") != 0)
-+            continue;
-+
-+        /* find id of duplicate issues */
-+        reader_find_element_by_name(reader, "target_id");
-+
-+        /* verify target_id node */
-+        if (reader_move_reader_if_node_type_is_element_with_name_and_verify_its_value(reader, "target_id") == false)
-+            continue;
-+
-+        /* get its value */
-+        if ((id = xmlTextReaderConstValue(reader)) != NULL)
-+            break;
-+    }
-+    xmlFreeTextReader(reader);
-+
-+    return (id == NULL) ? -1 : atoi((const char *) id);
-+}
-+
-+GList *
-+response_get_main_ids_list(const char *xml)
-+{
-+    return response_values_at_depth_by_name(xml, "id", 5);
-+}
-+
-+int
-+response_get_main_id(const char *xml)
-+{
-+    GList *l = response_values_at_depth_by_name(xml, "id", 5);
-+    return (l != NULL) ? atoi(l->data) : -1;
-+}
-+
-+static int
-+response_get_return_value(const char *xml)
-+{
-+    GList *l = response_values_at_depth_by_name(xml, "return", 3);
-+    return (l != NULL) ? atoi(l->data) : -1;
-+}
-+
-+static char*
-+response_get_return_value_as_string(const char *xml)
-+{
-+    GList *l = response_values_at_depth_by_name(xml, "return", 3);
-+    return (l != NULL) ? l->data : NULL;
-+}
-+
-+static char *
-+response_get_error_msg(const char *xml)
-+{
-+    GList *l = response_values_at_depth_by_name(xml, "faultstring", 3);
-+    return (l != NULL) ? xstrdup(l->data) : NULL;
-+}
-+
-+static char *
-+response_get_additioanl_information(const char *xml)
-+{
-+    GList *l = response_values_at_depth_by_name(xml, "additional_information", -1);
-+    return (l != NULL) ? xstrdup(l->data) : NULL;
-+}
-+
-+void
-+response_values_free(GList *values)
-+{
-+    g_list_free_full(values, free);
-+}
-+
-+/*
-+ * POST
-+ */
-+
-+void
-+mantisbt_result_free(mantisbt_result_t *result)
-+{
-+    if (result == NULL)
-+        return;
-+
-+    free(result->mr_url);
-+    free(result->mr_msg);
-+    free(result->mr_body);
-+    free(result);
-+}
-+
-+mantisbt_result_t *
-+mantisbt_soap_call(const mantisbt_settings_t *settings, const soap_request_t *req)
-+{
-+    char *request = soap_request_to_str(req);
-+
-+    const char *url = settings->m_mantisbt_soap_url;
-+
-+    mantisbt_result_t *result = xzalloc(sizeof(*result));
-+
-+    if (url == NULL || request == NULL)
-+    {
-+        result->mr_error = -2;
-+        result->mr_msg = xasprintf(_("Url or request isn't specified."));
-+        free(request);
-+
-+        return result;
-+    }
-+
-+    char *url_copy = NULL;
-+
-+    int redirect_count = 0;
-+    char *errmsg;
-+    post_state_t *post_state;
-+
-+redirect:
-+    post_state = new_post_state(0
-+            + POST_WANT_HEADERS
-+            + POST_WANT_BODY
-+            + POST_WANT_ERROR_MSG
-+            + (settings->m_ssl_verify ? POST_WANT_SSL_VERIFY : 0)
-+    );
-+
-+    post_string(post_state, settings->m_mantisbt_soap_url, "text/xml", NULL, request);
-+
-+    char *location = find_header_in_post_state(post_state, "Location:");
-+
-+    switch (post_state->http_resp_code)
-+    {
-+    case 404:
-+        result->mr_error = -1;
-+        result->mr_msg = xasprintf(_("Error in HTTP POST, "
-+                        "HTTP code: 404 (Not found), URL:'%s'"), url);
-+        break;
-+    case 500:
-+        result->mr_error = -1;
-+        result->mr_msg = response_get_error_msg(post_state->body);
-+
-+        break;
-+    case 301: /* "301 Moved Permanently" (for example, used to move http:// to https://) */
-+    case 302: /* "302 Found" (just in case) */
-+    case 305: /* "305 Use Proxy" */
-+        if (++redirect_count < 10 && location)
-+        {
-+            free(url_copy);
-+            url = url_copy = xstrdup(location);
-+            free_post_state(post_state);
-+            goto redirect;
-+        }
-+        /* fall through */
-+
-+    default:
-+        result->mr_error = -1;
-+        errmsg = post_state->curl_error_msg;
-+        if (errmsg && errmsg[0])
-+            result->mr_msg = xasprintf(_("Error in MantisBT request at '%s': %s"), url, errmsg);
-+        else
-+            result->mr_msg = xasprintf(_("Error in MantisBT request at '%s'"), url);
-+        break;
-+
-+    case 200:
-+    case 201:
-+        /* sent successfully */
-+        result->mr_url = xstrdup(location); /* note: xstrdup(NULL) returns NULL */
-+    } /* switch (HTTP code) */
-+
-+    result->mr_http_resp_code = post_state->http_resp_code;
-+    result->mr_body = post_state->body;
-+    post_state->body = NULL;
-+
-+    free_post_state(post_state);
-+    free(url_copy);
-+    free(request);
-+
-+    return result;
-+}
-+
-+int
-+mantisbt_attach_data(const mantisbt_settings_t *settings, const char *bug_id,
-+                    const char *att_name, const char *data, int size)
-+{
-+    soap_request_t *req = soap_request_new_for_method("mc_issue_attachment_add");
-+    soap_request_add_credentials_parameter(req, settings);
-+
-+    soap_request_add_method_parameter(req, "issue_id", SOAP_INTEGER, bug_id);
-+    soap_request_add_method_parameter(req, "name", SOAP_STRING, att_name);
-+
-+    soap_request_add_method_parameter(req, "file_type", SOAP_STRING, "text");
-+    soap_request_add_method_parameter(req, "content", SOAP_BASE64, encode_base64(data, size));
-+
-+    mantisbt_result_t *result = mantisbt_soap_call(settings, req);
-+    soap_request_free(req);
-+
-+    if (result->mr_http_resp_code != 200)
-+    {
-+        int ret = -1;
-+        if (strcmp(result->mr_msg, "Duplicate filename.") == 0)
-+            ret = -2;
-+
-+        error_msg(_("Failed to attach file: '%s'"), result->mr_msg);
-+        mantisbt_result_free(result);
-+        return ret;
-+    }
-+
-+    int id = response_get_return_value(result->mr_body);
-+
-+    mantisbt_result_free(result);
-+
-+    return id;
-+}
-+
-+static int
-+mantisbt_attach_fd(const mantisbt_settings_t *settings, const char *bug_id,
-+                const char *att_name, int fd)
-+{
-+    off_t size = lseek(fd, 0, SEEK_END);
-+    if (size < 0)
-+    {
-+        perror_msg(_("Can't lseek '%s'"), att_name);
-+        return -1;
-+    }
-+
-+    if (size >= MANTISBT_MAX_FILE_UPLOAD_SIZE)
-+    {
-+        error_msg(_("Can't upload '%s', it's too large (%llu bytes)"), att_name, (long long)size);
-+        return -1;
-+    }
-+    lseek(fd, 0, SEEK_SET);
-+
-+    char *data = xmalloc(size + 1);
-+    ssize_t r = full_read(fd, data, size);
-+    if (r < 0)
-+    {
-+        free(data);
-+        perror_msg(_("Can't read '%s'"), att_name);
-+        return -1;
-+    }
-+
-+    int res = mantisbt_attach_data(settings, bug_id, att_name, data, size);
-+    free(data);
-+    return res;
-+}
-+
-+int
-+mantisbt_attach_file(const mantisbt_settings_t *settings, const char *bug_id,
-+                    const char *att_name, const char *path)
-+{
-+    int fd = open(path, O_RDONLY);
-+    if (fd < 0)
-+    {
-+        perror_msg(_("Can't open '%s'"), path);
-+        return 0;
-+    }
-+    errno = 0;
-+    struct stat st;
-+    if (fstat(fd, &st) != 0 || !S_ISREG(st.st_mode))
-+    {
-+        perror_msg("'%s': not a regular file", path);
-+        close(fd);
-+        return 0;
-+    }
-+    log_debug("attaching '%s' as file", att_name);
-+    int ret = mantisbt_attach_fd(settings, bug_id, att_name, fd);
-+    close(fd);
-+    return ret;
-+}
-+
-+static void
-+soap_filter_add_new_array_parameter(xmlNodePtr filter_node, const char *name, const char *type, const char *value)
-+{
-+    const char *array_type = NULL;
-+    if( strcmp(type, SOAP_INTEGER) == 0 )
-+        array_type = SOAP_INTEGERARRAY;
-+    else
-+        array_type = SOAP_STRINGARRAY;
-+
-+    xmlNodePtr filter_item = soap_node_add_child_node(filter_node, name, array_type, /* content */ NULL);
-+    soap_node_add_child_node(filter_item, "item", type, value);
-+}
-+
-+static void
-+soap_filter_custom_fields_add_new_item(xmlNodePtr filter_node, const char *custom_field_name, const char *value)
-+{
-+    xmlNodePtr item_node = soap_node_add_child_node(filter_node, "item", SOAP_FILTER_CUSTOMFIELD, /* content */ NULL);
-+
-+    xmlNodePtr field_node = soap_node_add_child_node(item_node, "field", SOAP_OBJECTREF, /* content */ NULL);
-+    soap_node_add_child_node(field_node, "name", SOAP_STRING, custom_field_name);
-+
-+    xmlNodePtr value_node = soap_node_add_child_node(item_node, "value", SOAP_STRINGARRAY, /* content */ NULL);
-+    soap_node_add_child_node(value_node, "item", SOAP_STRING, value);
-+}
-+
-+GList *
-+mantisbt_search_by_abrt_hash(mantisbt_settings_t *settings, const char *abrt_hash)
-+{
-+    soap_request_t *req = soap_request_new_for_method("mc_filter_search_issues");
-+    soap_request_add_credentials_parameter(req, settings);
-+
-+    xmlNodePtr filter_node = soap_node_add_child_node(req->sr_method, "filter", SOAP_FILTER_SEARCH_DATA, /* content */ NULL);
-+
-+    /* 'hide_status_is : -2' means, searching within all status */
-+    soap_filter_add_new_array_parameter(filter_node, "hide_status_id", SOAP_INTEGERARRAY, "-2");
-+
-+    // custom fields
-+    xmlNodePtr custom_fields_node = soap_node_add_child_node(filter_node, "custom_fields", SOAP_FILTER_CUSTOMFIELD_ARRAY, /* content */ NULL);
-+
-+    // custom field 'abrt_hash'
-+    soap_filter_custom_fields_add_new_item(custom_fields_node, "abrt_hash", abrt_hash);
-+
-+    soap_request_add_method_parameter(req, "page_number", SOAP_INTEGER, "1");
-+    soap_request_add_method_parameter(req, "per_page", SOAP_INTEGER, /* -1 means get all issues */ "-1");
-+
-+    mantisbt_result_t *result = mantisbt_soap_call(settings, req);
-+    soap_request_free(req);
-+
-+    if (result->mr_error == -1)
-+    {
-+        error_msg(_("Failed to search MantisBT issue by duphash: '%s'"), result->mr_msg);
-+        mantisbt_result_free(result);
-+        return NULL;
-+    }
-+
-+    GList *ids = response_get_main_ids_list(result->mr_body);
-+
-+    return ids;
-+}
-+
-+GList *
-+mantisbt_search_duplicate_issues(mantisbt_settings_t *settings, const char *category,
-+                                     const char *version, const char *abrt_hash)
-+{
-+    soap_request_t *req = soap_request_new_for_method("mc_filter_search_issues");
-+    soap_request_add_credentials_parameter(req, settings);
-+
-+    xmlNodePtr filter_node = soap_node_add_child_node(req->sr_method, "filter", SOAP_FILTER_SEARCH_DATA, /* content */ NULL);
-+
-+    soap_filter_add_new_array_parameter(filter_node, "project_id", SOAP_INTEGERARRAY, settings->m_project_id);
-+
-+    /* 'hide_status_is : -2' means, searching within all status */
-+    soap_filter_add_new_array_parameter(filter_node, "hide_status_id", SOAP_INTEGERARRAY, "-2");
-+
-+    soap_filter_add_new_array_parameter(filter_node, "category", SOAP_STRINGARRAY, category);
-+
-+    // custom fields
-+    xmlNodePtr custom_fields_node = soap_node_add_child_node(filter_node, "custom_fields", SOAP_FILTER_CUSTOMFIELD_ARRAY, /* content */ NULL);
-+
-+    // custom field 'abrt_hash'
-+    soap_filter_custom_fields_add_new_item(custom_fields_node, "abrt_hash", abrt_hash);
-+
-+    // version
-+    if (version != NULL)
-+        soap_filter_add_new_array_parameter(filter_node, "os_build", SOAP_STRINGARRAY, version);
-+
-+    soap_request_add_method_parameter(req, "page_number", SOAP_INTEGER, "1");
-+    soap_request_add_method_parameter(req, "per_page", SOAP_INTEGER, /* -1 means get all issues */ "-1");
-+
-+    mantisbt_result_t *result = mantisbt_soap_call(settings, req);
-+    soap_request_free(req);
-+
-+    if (result->mr_error == -1)
-+    {
-+        error_msg(_("Failed to search MantisBT duplicate issue: '%s'"), result->mr_msg);
-+        mantisbt_result_free(result);
-+        return NULL;
-+    }
-+
-+    GList *ids = response_get_main_ids_list(result->mr_body);
-+
-+    return ids;
-+}
-+
-+static char *
-+custom_field_get_id_from_name(GList *ids, GList *names, const char *name)
-+{
-+    GList *i = ids;
-+    GList *n = names;
-+    for (; i != NULL; i = i->next, n = n->next)
-+    {
-+        if (strcmp(n->data, name) == 0)
-+            return i->data;
-+    }
-+
-+    return NULL;
-+}
-+
-+static void
-+custom_field_ask(const char *name)
-+{
-+    char *msg = xasprintf(_("CentOS Bug Tracker doesn't contain custom field '%s', which is required for full functionality of the reporter. Do you still want to create a new issue?"), name);
-+    int yes = ask_yes_no(msg);
-+    free(msg);
-+
-+    if (!yes)
-+    {
-+        set_xfunc_error_retval(EXIT_CANCEL_BY_USER);
-+        xfunc_die();
-+    }
-+
-+    return;
-+}
-+
-+static void
-+mantisbt_get_custom_fields(const mantisbt_settings_t *settings, mantisbt_custom_fields_t *fields, const char *project_id)
-+{
-+    soap_request_t *req = soap_request_new_for_method("mc_project_get_custom_fields");
-+    soap_request_add_credentials_parameter(req, settings);
-+    soap_request_add_method_parameter(req, "project_id", SOAP_INTEGER, project_id);
-+
-+    mantisbt_result_t *result = mantisbt_soap_call(settings, req);
-+    soap_request_free(req);
-+
-+    if (result->mr_http_resp_code != 200)
-+        error_msg_and_die(_("Failed to get custom fields for '%s' project"), settings->m_project);
-+
-+    GList *ids = response_values_at_depth_by_name(result->mr_body, "id", -1);
-+    GList *names = response_values_at_depth_by_name(result->mr_body, "name", -1);
-+
-+    mantisbt_result_free(result);
-+
-+    if ((fields->cf_abrt_hash_id = custom_field_get_id_from_name(ids, names, CUSTOMFIELD_DUPHASH)) == NULL)
-+        custom_field_ask(CUSTOMFIELD_DUPHASH);
-+
-+    if ((fields->cf_url_id = custom_field_get_id_from_name(ids, names, CUSTOMFIELD_URL)) == NULL)
-+        custom_field_ask(CUSTOMFIELD_URL);
-+
-+    return;
-+}
-+
-+int
-+mantisbt_create_new_issue(const mantisbt_settings_t *settings,
-+                   problem_data_t *problem_data,
-+                   const problem_report_t *pr,
-+                   const char *tracker_url)
-+{
-+
-+    const char *category = problem_data_get_content_or_NULL(problem_data, FILENAME_COMPONENT);
-+    const char *duphash = problem_data_get_content_or_NULL(problem_data, FILENAME_DUPHASH);
-+
-+    char *summary = shorten_string_to_length(problem_report_get_summary(pr), MAX_SUMMARY_LENGTH);
-+
-+    const char *description = problem_report_get_description(pr);
-+    const char *additional_information = problem_report_get_section(pr, PR_SEC_ADDITIONAL_INFO);
-+
-+    mantisbt_custom_fields_t fields;
-+    mantisbt_get_custom_fields(settings, &fields, settings->m_project_id);
-+
-+    soap_request_t *req = soap_request_new_for_method("mc_issue_add");
-+    soap_request_add_credentials_parameter(req, settings);
-+    soap_add_new_issue_parameters(req, settings->m_project, settings->m_project_version, category, summary, description, additional_information, settings->m_create_private, &fields, duphash, tracker_url);
-+
-+    mantisbt_result_t *result = mantisbt_soap_call(settings, req);
-+    soap_request_free(req);
-+    free(summary);
-+
-+    if (result->mr_error == -1)
-+    {
-+        error_msg(_("Failed to create a new issue: '%s'"), result->mr_msg);
-+        mantisbt_result_free(result);
-+        return -1;
-+    }
-+
-+    int id = response_get_return_value(result->mr_body);
-+
-+    mantisbt_result_free(result);
-+    return id;
-+}
-+
-+mantisbt_issue_info_t *
-+mantisbt_get_issue_info(const mantisbt_settings_t *settings, int issue_id)
-+{
-+    soap_request_t *req = soap_request_new_for_method("mc_issue_get");
-+    soap_request_add_credentials_parameter(req, settings);
-+
-+    char *issue_id_str = xasprintf("%d", issue_id);
-+    soap_request_add_method_parameter(req, "issue_id", SOAP_INTEGER, issue_id_str);
-+    free(issue_id_str);
-+
-+    mantisbt_result_t *result = mantisbt_soap_call(settings, req);
-+    soap_request_free(req);
-+
-+    if (result->mr_error == -1)
-+    {
-+        error_msg(_("Failed to get MantisBT issue: '%s'"), result->mr_msg);
-+        mantisbt_result_free(result);
-+        return NULL;
-+    }
-+
-+    mantisbt_issue_info_t *issue_info = mantisbt_issue_info_new();
-+
-+    issue_info->mii_id = issue_id;
-+    issue_info->mii_status = response_get_name_value_of_element(result->mr_body, "status");
-+    issue_info->mii_resolution = response_get_name_value_of_element(result->mr_body, "resolution");
-+    issue_info->mii_reporter = response_get_name_value_of_element(result->mr_body, "reporter");
-+    issue_info->mii_project = response_get_name_value_of_element(result->mr_body, "project");
-+
-+    if (strcmp(issue_info->mii_status, "closed") == 0 && !issue_info->mii_resolution)
-+        error_msg(_("Issue %i is CLOSED, but it has no RESOLUTION"), issue_info->mii_id);
-+
-+    issue_info->mii_dup_id = response_get_id_of_relatedto_issue(result->mr_body);
-+
-+    if (strcmp(issue_info->mii_status, "closed") == 0
-+        && strcmp(issue_info->mii_resolution, "duplicate") == 0
-+        && issue_info->mii_dup_id == -1 )
-+    {
-+        error_msg(_("Issue %i is CLOSED as DUPLICATE, but it has no DUPLICATE_ID"),
-+                            issue_info->mii_id);
-+    }
-+
-+    /* notes are stored in <text> element */
-+    issue_info->mii_notes = response_values_at_depth_by_name(result->mr_body, "text", -1);
-+
-+    /* looking for bt rating in additional information too */
-+    char *add_info = response_get_additioanl_information(result->mr_body);
-+    if (add_info != NULL)
-+        issue_info->mii_notes = g_list_append (issue_info->mii_notes, add_info);
-+    issue_info->mii_attachments = response_values_at_depth_by_name(result->mr_body, "filename", -1);
-+    issue_info->mii_best_bt_rating = comments_find_best_bt_rating(issue_info->mii_notes);
-+
-+    mantisbt_result_free(result);
-+    return issue_info;
-+}
-+
-+int
-+mantisbt_add_issue_note(const mantisbt_settings_t *settings, int issue_id, const char *note)
-+{
-+    soap_request_t *req = soap_request_new_for_method("mc_issue_note_add");
-+    soap_request_add_credentials_parameter(req, settings);
-+
-+    char *issue_id_str = xasprintf("%i", issue_id);
-+    soap_node_add_child_node(req->sr_method, "issue_id", SOAP_INTEGER, issue_id_str);
-+
-+    xmlNodePtr note_node = soap_node_add_child_node(req->sr_method, "note", SOAP_ISSUENOTE, /* content */ NULL);
-+    soap_node_add_child_node(note_node, "text", SOAP_STRING, note);
-+
-+    mantisbt_result_t *result = mantisbt_soap_call(settings, req);
-+
-+    free(issue_id_str);
-+    soap_request_free(req);
-+
-+    if (result->mr_error == -1)
-+    {
-+        error_msg(_("Failed to add MantisBT issue note: '%s'"), result->mr_msg);
-+        mantisbt_result_free(result);
-+        return -1;
-+    }
-+    int id = response_get_return_value(result->mr_body);
-+
-+    mantisbt_result_free(result);
-+    return id;
-+}
-+
-+void
-+mantisbt_get_project_id_from_name(mantisbt_settings_t *settings)
-+{
-+    if (settings->m_project == NULL)
-+        error_msg_and_die(_("The MantisBT project has not been deretmined."));
-+
-+    soap_request_t *req = soap_request_new_for_method("mc_project_get_id_from_name");
-+    soap_request_add_credentials_parameter(req, settings);
-+    soap_node_add_child_node(req->sr_method, "project_name", SOAP_STRING, settings->m_project);
-+
-+    mantisbt_result_t *result = mantisbt_soap_call(settings, req);
-+
-+    if (result->mr_http_resp_code != 200)
-+        error_msg_and_die(_("Failed to get project id from name"));
-+
-+    settings->m_project_id = response_get_return_value_as_string(result->mr_body);
-+
-+    return;
-+}
-diff --git a/src/plugins/mantisbt.conf b/src/plugins/mantisbt.conf
-new file mode 100644
-index 0000000..15a1065
---- /dev/null
-+++ b/src/plugins/mantisbt.conf
-@@ -0,0 +1,8 @@
-+# MantisBT URL
-+MantisbtURL = https://bugs.centos.org/
-+# yes means that ssl certificates will be checked
-+SSLVerify = yes
-+# your login has to exist, if you don have any, please create one
-+Login =
-+# your password
-+Password =
-diff --git a/src/plugins/mantisbt.h b/src/plugins/mantisbt.h
-new file mode 100644
-index 0000000..c31c174
---- /dev/null
-+++ b/src/plugins/mantisbt.h
-@@ -0,0 +1,140 @@
-+/*
-+    Copyright (C) 2014  ABRT team
-+    Copyright (C) 2014  RedHat Inc
-+
-+    This program is free software; you can redistribute it and/or modify
-+    it under the terms of the GNU General Public License as published by
-+    the Free Software Foundation; either version 2 of the License, or
-+    (at your option) any later version.
-+
-+    This program is distributed in the hope that it will be useful,
-+    but WITHOUT ANY WARRANTY; without even the implied warranty of
-+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+    GNU General Public License for more details.
-+
-+    You should have received a copy of the GNU General Public License along
-+    with this program; if not, write to the Free Software Foundation, Inc.,
-+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-+*/
-+
-+#ifndef MANTISBT_H
-+#define MANTISBT_H
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#include <libxml/encoding.h>
-+#include "problem_report.h"
-+
-+#define SOAP_STRING "ns2:string"
-+#define SOAP_INTEGER "ns2:integer"
-+#define SOAP_INTEGERARRAY "ns2:IntegerArray"
-+#define SOAP_STRINGARRAY "ns2:StringArray"
-+#define SOAP_ISSUEDATA "ns3:IssueData"
-+#define SOAP_OBJECTREF "ns3:ObjectRef"
-+#define SOAP_CUSTOMFIELD_ARRAY "ns2:CustomFieldValueForIssueDataArray"
-+#define SOAP_FILTER_CUSTOMFIELD "ns2:FilterCustomField"
-+#define SOAP_FILTER_CUSTOMFIELD_ARRAY "ns2:FilterCustomFieldArray"
-+#define SOAP_FILTER_SEARCH_DATA "ns2:FilterSearchData"
-+#define SOAP_CUSTOMFIELD "ns2:CustomFieldValueForIssueData"
-+#define SOAP_BASE64 "SOAP-ENC:base64"
-+#define SOAP_ISSUENOTE "ns3:IssueNoteData"
-+
-+#define PR_SEC_ADDITIONAL_INFO "Additional info"
-+
-+typedef struct soap_request
-+{
-+    xmlNodePtr sr_root;
-+    xmlNodePtr sr_body;
-+    xmlNodePtr sr_method;
-+} soap_request_t;
-+
-+typedef struct mantisbt_settings
-+{
-+    char *m_login;
-+    char *m_password;
-+    const char *m_mantisbt_url;
-+    const char *m_mantisbt_soap_url;
-+    char *m_project;
-+    char *m_project_id;
-+    char *m_project_version;
-+    const char *m_DontMatchComponents;
-+    int         m_ssl_verify;
-+    int         m_create_private;
-+} mantisbt_settings_t;
-+
-+typedef struct mantisbt_result
-+{
-+    int mr_http_resp_code;
-+    int mr_error;
-+    char *mr_msg;
-+    char *mr_url;
-+    char *mr_body;
-+} mantisbt_result_t;
-+
-+typedef struct mantisbt_issue_info
-+{
-+    int mii_id;
-+    int mii_dup_id;
-+    unsigned mii_best_bt_rating;
-+
-+    char *mii_status;
-+    char *mii_resolution;
-+    char *mii_reporter;
-+    char *mii_project;
-+
-+    GList *mii_notes;
-+    GList *mii_attachments;
-+} mantisbt_issue_info_t;
-+
-+void mantisbt_settings_free(mantisbt_settings_t *settings);
-+
-+mantisbt_issue_info_t * mantisbt_issue_info_new();
-+void mantisbt_issue_info_free(mantisbt_issue_info_t *info);
-+mantisbt_issue_info_t * mantisbt_find_origin_bug_closed_duplicate(mantisbt_settings_t *settings, mantisbt_issue_info_t *info);
-+
-+void soap_request_free(soap_request_t *req);
-+
-+soap_request_t *soap_request_new_for_method(const char *method);
-+
-+void soap_request_add_method_parameter(soap_request_t *req, const char *name, const char *type, const char *value);
-+void soap_request_add_credentials_parameter(soap_request_t *req, const mantisbt_settings_t *settings);
-+
-+char *soap_request_to_str(const soap_request_t *req);
-+
-+#if 0
-+void soap_request_print(soap_request_t *req);
-+#endif
-+
-+GList * response_get_main_ids_list(const char *xml);
-+int response_get_main_id(const char *xml);
-+void response_values_free(GList *values);
-+
-+void mantisbt_result_free(mantisbt_result_t *result);
-+mantisbt_result_t *mantisbt_soap_call(const mantisbt_settings_t *settings, const soap_request_t *req);
-+
-+int mantisbt_attach_data(const mantisbt_settings_t *settings, const char *bug_id,
-+                         const char *att_name, const char *data, int size);
-+
-+int mantisbt_attach_file(const mantisbt_settings_t *settings, const char *bug_id,
-+                    const char *att_name, const char *data);
-+
-+GList * mantisbt_search_by_abrt_hash(mantisbt_settings_t *settings, const char *abrt_hash);
-+GList * mantisbt_search_duplicate_issues(mantisbt_settings_t *settings, const char *category,
-+                    const char *version, const char *abrt_hash);
-+
-+int mantisbt_create_new_issue(const mantisbt_settings_t *settings, problem_data_t *problem_data,
-+                       const problem_report_t *pr, const char *tracker_url);
-+
-+mantisbt_issue_info_t * mantisbt_get_issue_info(const mantisbt_settings_t *settings, int issue_id);
-+int mantisbt_add_issue_note(const mantisbt_settings_t *settings, int issue_id, const char *note);
-+
-+void mantisbt_get_project_id_from_name(mantisbt_settings_t *settings);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif
-+
-diff --git a/src/plugins/mantisbt_format.conf b/src/plugins/mantisbt_format.conf
-new file mode 100644
-index 0000000..da08aa6
---- /dev/null
-+++ b/src/plugins/mantisbt_format.conf
-@@ -0,0 +1,59 @@
-+# Lines starting with # are ignored.
-+# Lines can be continued on the next line using trailing backslash.
-+#
-+# Format:
-+# %summary:: summary format
-+# section:: element1[,element2]...
-+# The literal text line to be added to Bugzilla comment. Can be empty.
-+# (IOW: empty lines are NOT ignored!)
-+#
-+# Summary format is a line of text, where %element% is replaced by
-+# text element's content, and [[...%element%...]] block is used only if
-+# %element% exists. [[...]] blocks can nest.
-+#
-+# Sections can be:
-+# - %summary: bug summary format string.
-+# - %attach: a list of elements to attach.
-+# - text, double colon (::) and the list of comma-separated elements.
-+#   Text can be empty (":: elem1, elem2, elem3" works),
-+#   in this case "Text:" header line will be omitted.
-+#
-+# Elements can be:
-+# - problem directory element names, which get formatted as
-+#   <element_name>: <contents>
-+#   or
-+#   <element_name>:
-+#   :<contents>
-+#   :<contents>
-+#   :<contents>
-+# - problem directory element names prefixed by "%bare_",
-+#   which is formatted as-is, without "<element_name>:" and colons
-+# - %oneline, %multiline, %text wildcards, which select all corresponding
-+#   elements for output or attachment
-+# - %binary wildcard, valid only for %attach section, instructs to attach
-+#   binary elements
-+# - problem directory element names prefixed by "-",
-+#   which excludes given element from all wildcards
-+#
-+#   Nonexistent elements are silently ignored.
-+#   If none of elements exists, the section will not be created.
-+
-+%summary:: [abrt] %pkg_name%[[: %crash_function%()]][[: %reason%]][[: TAINTED %tainted_short%]]
-+
-+Description of problem:: %bare_comment
-+
-+Version-Release number of selected component:: %bare_package
-+
-+Truncated backtrace:: %bare_%short_backtrace
-+
-+%Additional info::
-+:: -pkg_arch,-pkg_epoch,-pkg_name,-pkg_release,-pkg_version,\
-+		-component,-architecture,\
-+	-analyzer,-count,-duphash,-uuid,-abrt_version,\
-+	-username,-hostname,-os_release,-os_info,\
-+	-time,-pid,-pwd,-last_occurrence,-ureports_counter,\
-+	%reporter,\
-+	%oneline
-+
-+%attach:: -comment,-reason,-reported_to,-event_log,%multiline,\
-+	-coredump,%binary
-diff --git a/src/plugins/mantisbt_formatdup.conf b/src/plugins/mantisbt_formatdup.conf
-new file mode 100644
-index 0000000..b1552ac
---- /dev/null
-+++ b/src/plugins/mantisbt_formatdup.conf
-@@ -0,0 +1,65 @@
-+# Lines starting with # are ignored.
-+# Lines can be continued on the next line using trailing backslash.
-+#
-+# Format:
-+# %summary:: summary format
-+# section:: element1[,element2]...
-+# The literal text line to be added to Bugzilla comment. Can be empty.
-+# (IOW: empty lines are NOT ignored!)
-+#
-+# Summary format is a line of text, where %element% is replaced by
-+# text element's content, and [[...%element%...]] block is used only if
-+# %element% exists. [[...]] blocks can nest.
-+#
-+# Sections can be:
-+# - %summary: bug summary format string.
-+# - %attach: a list of elements to attach.
-+# - text, double colon (::) and the list of comma-separated elements.
-+#   Text can be empty (":: elem1, elem2, elem3" works),
-+#   in this case "Text:" header line will be omitted.
-+#
-+# Elements can be:
-+# - problem directory element names, which get formatted as
-+#   <element_name>: <contents>
-+#   or
-+#   <element_name>:
-+#   :<contents>
-+#   :<contents>
-+#   :<contents>
-+# - problem directory element names prefixed by "%bare_",
-+#   which is formatted as-is, without "<element_name>:" and colons
-+# - %oneline, %multiline, %text wildcards, which select all corresponding
-+#   elements for output or attachment
-+# - %binary wildcard, valid only for %attach section, instructs to attach
-+#   binary elements
-+# - problem directory element names prefixed by "-",
-+#   which excludes given element from all wildcards
-+#
-+#   Nonexistent elements are silently ignored.
-+#   If none of elements exists, the section will not be created.
-+
-+# When we add a comment to an existing BZ, %summary is ignored
-+# (it specifies *new bug* summary field):
-+# %summary:: blah blah
-+
-+# When dup is detected, BZ reporter adds a comment to it.
-+# This comment may interrupt an ongoing conversation in the BZ.
-+# (Three people independently filed a bug against abrt about this).
-+# Need to clearly explain what this comment is, to prevent confusion.
-+# Hopefully, this line would suffice:
-+Another user experienced a similar problem:
-+
-+# If user filled out comment field, show it:
-+:: %bare_comment
-+
-+# var_log_messages has too much variance (time/date),
-+# we exclude it from message so that dup message elimination has more chances to work
-+:: \
-+	-pkg_arch,-pkg_epoch,-pkg_name,-pkg_release,-pkg_version,\
-+		-component,-architecture,\
-+	-analyzer,-count,-duphash,-uuid,-abrt_version,\
-+	-username,-hostname,-os_release,-os_info,\
-+	-time,-pid,-pwd,-last_occurrence,-ureports_counter,\
-+	-var_log_messages,\
-+	%reporter,\
-+	%oneline
-diff --git a/src/plugins/report_CentOSBugTracker.conf b/src/plugins/report_CentOSBugTracker.conf
-new file mode 100644
-index 0000000..04cab13
---- /dev/null
-+++ b/src/plugins/report_CentOSBugTracker.conf
-@@ -0,0 +1,4 @@
-+Mantisbt_MantisbtURL = https://bugs.centos.org
-+Mantisbt_Login =
-+Mantisbt_Password
-+Mantisbt_SSLVerify = yes
-diff --git a/src/plugins/report_CentOSBugTracker.xml.in b/src/plugins/report_CentOSBugTracker.xml.in
-new file mode 100644
-index 0000000..81f909b
---- /dev/null
-+++ b/src/plugins/report_CentOSBugTracker.xml.in
-@@ -0,0 +1,65 @@
-+<?xml version="1.0" encoding="UTF-8" ?>
-+<event>
-+    <_name>CentOS Bug Tracker</_name>
-+    <_description>Report to CentOS Bug Tracker</_description>
-+
-+    <requires-items>component,duphash,os_release</requires-items>
-+    <exclude-items-by-default>coredump,count,event_log,reported_to,vmcore</exclude-items-by-default>
-+    <exclude-items-always></exclude-items-always>
-+    <exclude-binary-items>no</exclude-binary-items>
-+    <include-items-by-default></include-items-by-default>
-+    <minimal-rating>3</minimal-rating>
-+    <gui-review-elements>yes</gui-review-elements>
-+
-+    <options>
-+        <option type="text" name="Mantisbt_Login">
-+            <_label>User name</_label>
-+            <allow-empty>no</allow-empty>
-+            <_description>CentOS Bug Tracker account user name</_description>
-+            <_note-html>You can create bugs.centos.org account &lt;a href="https://bugs.centos.org/signup_page.php"&gt;here&lt;/a&gt;</_note-html>
-+        </option>
-+        <option type="password" name="Mantisbt_Password">
-+            <_label>Password</_label>
-+            <allow-empty>no</allow-empty>
-+            <_description>CentOS Bug Tracker account password</_description>
-+        </option>
-+        <advanced-options>
-+            <option type="text" name="Mantisbt_MantisbtURL">
-+                <_label>CentOS Bug Tracker URL</_label>
-+                <allow-empty>no</allow-empty>
-+                <_note-html>Address of CentOS Bug Tracker server</_note-html>
-+                <default-value>https://bugs.centos.org</default-value>
-+            </option>
-+            <option type="bool" name="Mantisbt_SSLVerify">
-+                <_label>Verify SSL</_label>
-+                <_note-html>Check SSL key validity</_note-html>
-+                <default-value>yes</default-value>
-+            </option>
-+            <option type="text" name="Mantisbt_Project">
-+                <_label>CentOS Bug Tracker project</_label>
-+                <allow-empty>yes</allow-empty>
-+                <_note-html>Specify this only if you needed different project than specified in /etc/os-release</_note-html>
-+            </option>
-+            <option type="text" name="Mantisbt_ProjectVersion">
-+                <_label>CentOS Bug Tracker project version</_label>
-+                <allow-empty>yes</allow-empty>
-+                <_note-html>Specify this only if you needed different project version than specified in /etc/os-release</_note-html>
-+            </option>
-+            <option type="text" name="http_proxy">
-+                <_label>HTTP Proxy</_label>
-+                <allow-empty>yes</allow-empty>
-+                <_note-html>Sets the proxy server to use for HTTP</_note-html>
-+            </option>
-+            <option type="text" name="HTTPS_PROXY">
-+                <_label>HTTPS Proxy</_label>
-+                <allow-empty>yes</allow-empty>
-+                <_note-html>Sets the proxy server to use for HTTPS</_note-html>
-+            </option>
-+            <option type="bool" name="Mantisbt_CreatePrivate">
-+                <_label>Restrict access</_label>
-+                <_note-html>Restrict access to the created CentOS Bug Tracker issue allowing only users from specified groups to view it (see advanced settings for more details)</_note-html>
-+                <default-value>no</default-value>
-+            </option>
-+        </advanced-options>
-+    </options>
-+</event>
-diff --git a/src/plugins/reporter-mantisbt.c b/src/plugins/reporter-mantisbt.c
-new file mode 100644
-index 0000000..d281cdb
---- /dev/null
-+++ b/src/plugins/reporter-mantisbt.c
-@@ -0,0 +1,696 @@
-+/*
-+    Copyright (C) 2014  ABRT team
-+    Copyright (C) 2014  RedHat Inc
-+
-+    This program is free software; you can redistribute it and/or modify
-+    it under the terms of the GNU General Public License as published by
-+    the Free Software Foundation; either version 2 of the License, or
-+    (at your option) any later version.
-+
-+    This program is distributed in the hope that it will be useful,
-+    but WITHOUT ANY WARRANTY; without even the implied warranty of
-+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+    GNU General Public License for more details.
-+
-+    You should have received a copy of the GNU General Public License along
-+    with this program; if not, write to the Free Software Foundation, Inc., 51
-+    Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-+*/
-+
-+#include "internal_libreport.h"
-+#include "client.h"
-+#include "mantisbt.h"
-+#include "problem_report.h"
-+
-+static void
-+parse_osinfo_for_mantisbt(map_string_t *osinfo, char** project, char** version)
-+{
-+    const char *name = get_map_string_item_or_NULL(osinfo, "CENTOS_MANTISBT_PROJECT");
-+    if (!name)
-+        name = get_map_string_item_or_NULL(osinfo, OSINFO_NAME);
-+
-+    const char *version_id = get_map_string_item_or_NULL(osinfo, "CENTOS_MANTISBT_PROJECT_VERSION");
-+    if (!version_id)
-+        version_id = get_map_string_item_or_NULL(osinfo, OSINFO_VERSION_ID);
-+
-+    if (name && version_id)
-+    {
-+        *project = xstrdup(name);
-+        *version = xstrdup(version_id);
-+        return;
-+    }
-+
-+    /* something bad happend */
-+    *project = NULL;
-+    *version = NULL;
-+}
-+
-+static char *
-+ask_mantisbt_login(const char *message)
-+{
-+    char *login = ask(message);
-+    if (login == NULL || login[0] == '\0')
-+    {
-+        set_xfunc_error_retval(EXIT_CANCEL_BY_USER);
-+        error_msg_and_die(_("Can't continue without login"));
-+    }
-+
-+    return login;
-+}
-+
-+static char *
-+ask_mantisbt_password(const char *message)
-+{
-+    char *password = ask_password(message);
-+    /* TODO: this should be fixed in ask_password() as other tools have the same problem */
-+    putchar('\n');
-+    if (password == NULL || password[0] == '\0')
-+    {
-+        set_xfunc_error_retval(EXIT_CANCEL_BY_USER);
-+        error_msg_and_die(_("Can't continue without password"));
-+    }
-+
-+    return password;
-+}
-+
-+static void
-+ask_mantisbt_credentials(mantisbt_settings_t *settings, const char *pre_message)
-+{
-+    free(settings->m_login);
-+    free(settings->m_password);
-+
-+    char *question = xasprintf("%s %s", pre_message, _("Please enter your CentOS Bug Tracker login:"));
-+    settings->m_login = ask_mantisbt_login(question);
-+    free(question);
-+
-+    question = xasprintf("%s %s '%s':", pre_message, _("Please enter the password for"), settings->m_login);
-+    settings->m_password = ask_mantisbt_password(question);
-+    free(question);
-+
-+    return;
-+}
-+
-+static void
-+verify_credentials(mantisbt_settings_t *settings)
-+{
-+    if (settings->m_login[0] == '\0' || settings->m_password[0] == '\0')
-+        ask_mantisbt_credentials(settings, _("Credentials are not provided by configuration."));
-+
-+    while (true)
-+    {
-+        soap_request_t *req = soap_request_new_for_method("mc_login");
-+        soap_request_add_credentials_parameter(req, settings);
-+
-+        mantisbt_result_t *result = mantisbt_soap_call(settings, req);
-+        soap_request_free(req);
-+
-+        if (g_verbose > 2)
-+        {
-+            GList *ids = response_get_main_ids_list(result->mr_body);
-+            if (ids != NULL)
-+                log("%s", (char *)ids->data);
-+            response_values_free(ids);
-+        }
-+
-+        int result_val = result->mr_http_resp_code;
-+        mantisbt_result_free(result);
-+
-+        if (result_val == 200)
-+            return;
-+
-+        ask_mantisbt_credentials(settings, _("Invalid password or login."));
-+    }
-+}
-+
-+static void
-+set_settings(mantisbt_settings_t *m, map_string_t *settings, struct dump_dir *dd)
-+{
-+    const char *environ;
-+
-+    environ = getenv("Mantisbt_Login");
-+    m->m_login = xstrdup(environ ? environ : get_map_string_item_or_empty(settings, "Login"));
-+
-+    environ = getenv("Mantisbt_Password");
-+    m->m_password = xstrdup(environ ? environ : get_map_string_item_or_empty(settings, "Password"));
-+
-+    environ = getenv("Mantisbt_MantisbtURL");
-+    m->m_mantisbt_url = environ ? environ : get_map_string_item_or_empty(settings, "MantisbtURL");
-+    if (!m->m_mantisbt_url[0])
-+        m->m_mantisbt_url = "https://bugs.centos.org/";
-+    else
-+    {
-+        /* We don't want trailing '/': "https://host/dir/" -> "https://host/dir" */
-+        char *last_slash = strrchr(m->m_mantisbt_url, '/');
-+        if (last_slash && last_slash[1] == '\0')
-+            *last_slash = '\0';
-+    }
-+    m->m_mantisbt_soap_url = concat_path_file(m->m_mantisbt_url, "api/soap/mantisconnect.php");
-+
-+    environ = getenv("Mantisbt_Project");
-+    if (environ)
-+    {
-+        m->m_project = xstrdup(environ);
-+        environ = getenv("Mantisbt_ProjectVersion");
-+        if (environ)
-+            m->m_project_version = xstrdup(environ);
-+    }
-+    else
-+    {
-+        const char *option = get_map_string_item_or_NULL(settings, "Project");
-+        if (option)
-+            m->m_project = xstrdup(option);
-+        option = get_map_string_item_or_NULL(settings, "ProjectVersion");
-+        if (option)
-+            m->m_project_version = xstrdup(option);
-+    }
-+
-+    if (!m->m_project || !*m->m_project) /* if not overridden or empty... */
-+    {
-+        free(m->m_project);
-+        free(m->m_project_version);
-+
-+        if (dd != NULL)
-+        {
-+            map_string_t *osinfo = new_map_string();
-+
-+            char *os_info_data = dd_load_text(dd, FILENAME_OS_INFO);
-+            parse_osinfo(os_info_data, osinfo);
-+            free(os_info_data);
-+
-+            parse_osinfo_for_mantisbt(osinfo, &m->m_project, &m->m_project_version);
-+            free_map_string(osinfo);
-+        }
-+    }
-+
-+    environ = getenv("Mantisbt_SSLVerify");
-+    m->m_ssl_verify = string_to_bool(environ ? environ : get_map_string_item_or_empty(settings, "SSLVerify"));
-+
-+    environ = getenv("Mantisbt_DontMatchComponents");
-+    m->m_DontMatchComponents = environ ? environ : get_map_string_item_or_empty(settings, "DontMatchComponents");
-+
-+    environ = getenv(CREATE_PRIVATE_TICKET);
-+    if (environ)
-+        m->m_create_private = string_to_bool(environ);
-+
-+    if (!m->m_create_private)
-+    {
-+        environ = getenv("Mantisbt_CreatePrivate");
-+        m->m_create_private = string_to_bool(environ ? environ : get_map_string_item_or_empty(settings, "CreatePrivate"));
-+    }
-+    log_notice("create private CentOS Bug Tracker ticket: '%s'", m->m_create_private ? "YES": "NO");
-+}
-+
-+int main(int argc, char **argv)
-+{
-+    abrt_init(argv);
-+
-+    /* I18n */
-+    setlocale(LC_ALL, "");
-+#if ENABLE_NLS
-+    bindtextdomain(PACKAGE, LOCALEDIR);
-+    textdomain(PACKAGE);
-+#endif
-+
-+    const char *program_usage_string = _(
-+        "\n& [-vf] [-c CONFFILE]... [-F FMTFILE] [-A FMTFILE2] -d DIR"
-+        "\nor:"
-+        "\n& [-v] [-c CONFFILE]... [-d DIR] -t[ID] FILE..."
-+        "\nor:"
-+        "\n& [-v] [-c CONFFILE]... [-d DIR] -t[ID] -w"
-+        "\nor:"
-+        "\n& [-v] [-c CONFFILE]... -h DUPHASH"
-+        "\n"
-+        "\nReports problem to CentOS Bug Tracker."
-+        "\n"
-+        "\nThe tool reads DIR. Then it tries to find an issue"
-+        "\nwith the same abrt_hash in custom field 'abrt_hash'."
-+        "\n"
-+        "\nIf such issue is not found, then a new issue is created. Elements of DIR"
-+        "\nare stored in the issue as part of issue description or as attachments,"
-+        "\ndepending on their type and size."
-+        "\n"
-+        "\nOtherwise, if such issue is found and it is marked as CLOSED DUPLICATE,"
-+        "\nthe tool follows the chain of duplicates until it finds a non-DUPLICATE issue."
-+        "\nThe tool adds a new comment to found issue."
-+        "\n"
-+        "\nThe URL to new or modified issue is printed to stdout and recorded in"
-+        "\n'reported_to' element."
-+        "\n"
-+        "\nOption -t uploads FILEs to the already created issue on CentOS Bug Tracker site."
-+        "\nThe issue ID is retrieved from directory specified by -d DIR."
-+        "\nIf problem data in DIR was never reported to CentOS Bug Tracker, upload will fail."
-+        "\n"
-+        "\nOption -tID uploads FILEs to the issue with specified ID on CentOS Bug Tracker site."
-+        "\n-d DIR is ignored."
-+        "\n"
-+        "\nOption -r sets the last url from reporter_to element which is prefixed with"
-+        "\nTRACKER_NAME to URL field. This option is applied only when a new issue is to be"
-+        "\nfiled. The default value is 'ABRT Server'"
-+        "\n"
-+        "\nIf not specified, CONFFILE defaults to "CONF_DIR"/plugins/mantisb.conf"
-+        "\nIts lines should have 'PARAM = VALUE' format."
-+        "\nRecognized string parameters: MantisbtURL, Login, Password, Project, ProjectVersion."
-+        "\nRecognized boolean parameter (VALUE should be 1/0, yes/no): SSLVerify, CreatePrivate."
-+        "\nParameters can be overridden via $Mantisbt_PARAM environment variables."
-+        "\n"
-+        "\nFMTFILE and FMTFILE2 default to "CONF_DIR"/plugins/mantisbt_format.conf"
-+    );
-+
-+    enum {
-+        OPT_v = 1 << 0,
-+        OPT_d = 1 << 1,
-+        OPT_c = 1 << 2,
-+        OPT_F = 1 << 3,
-+        OPT_A = 1 << 4,
-+        OPT_t = 1 << 5,
-+        OPT_f = 1 << 6,
-+        OPT_h = 1 << 7,
-+        OPT_r = 1 << 8,
-+        OPT_D = 1 << 9,
-+    };
-+
-+    const char *dump_dir_name = ".";
-+    GList *conf_file = NULL;
-+    const char *fmt_file = CONF_DIR"/plugins/mantisbt_format.conf";
-+    const char *fmt_file2 = fmt_file;
-+    char *abrt_hash = NULL;
-+    char *ticket_no = NULL;
-+    const char *tracker_str = "ABRT Server";
-+    char *debug_str = NULL;
-+    mantisbt_settings_t mbt_settings = { 0 };
-+    /* Keep enum above and order of options below in sync! */
-+    struct options program_options[] = {
-+        OPT__VERBOSE(&g_verbose),
-+        OPT_STRING(   'd', NULL, &dump_dir_name , "DIR"    , _("Problem directory")),
-+        OPT_LIST(     'c', NULL, &conf_file     , "FILE"   , _("Configuration file (may be given many times)")),
-+        OPT_STRING(   'F', NULL, &fmt_file      , "FILE"   , _("Formatting file for initial comment")),
-+        OPT_STRING(   'A', NULL, &fmt_file2     , "FILE"   , _("Formatting file for duplicates")),
-+        OPT_OPTSTRING('t', "ticket", &ticket_no , "ID"     , _("Attach FILEs [to issue with this ID]")),
-+        OPT_BOOL(     'f', NULL, NULL,                       _("Force reporting even if this problem is already reported")),
-+        OPT_STRING(   'h', "duphash", &abrt_hash, "DUPHASH", _("Print BUG_ID which has given DUPHASH")),
-+        OPT_STRING(   'r', "tracker", &tracker_str, "TRACKER_NAME", _("A name of bug tracker for an additional URL from 'reported_to'")),
-+
-+        OPT_OPTSTRING('D', "debug", &debug_str  , "STR"    , _("Debug")),
-+        OPT_END()
-+    };
-+
-+    unsigned opts = parse_opts(argc, argv, program_options, program_usage_string);
-+    argv += optind;
-+
-+    export_abrt_envvars(0);
-+
-+    map_string_t *settings = new_map_string();
-+
-+    {
-+        if (!conf_file)
-+            conf_file = g_list_append(conf_file, (char*) CONF_DIR"/plugins/mantisbt.conf");
-+        while (conf_file)
-+        {
-+            char *fn = (char *)conf_file->data;
-+            log_notice("Loading settings from '%s'", fn);
-+            load_conf_file(fn, settings, /*skip key w/o values:*/ false);
-+            log_debug("Loaded '%s'", fn);
-+            conf_file = g_list_delete_link(conf_file, conf_file);
-+        }
-+
-+        struct dump_dir *dd = NULL;
-+        if (abrt_hash == NULL)
-+        {
-+            dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
-+            if (!dd)
-+                error_msg_and_die(_("Can't open problem dir '%s'."), dump_dir_name);
-+        }
-+
-+        set_settings(&mbt_settings, settings, dd);
-+        dd_close(dd);
-+        /* WRONG! set_settings() does not copy the strings, it merely sets up pointers
-+         * to settings[] dictionary:
-+         */
-+        /*free_map_string(settings);*/
-+    }
-+
-+    /* No connection is opened between client and server. Users authentication
-+     * is performed on every SOAP method call. In the first step we verify the
-+     * credentials by calling 'mc_login' method.  In the case the credentials are
-+     * correctly applies the reporter uses them in the next requests. It is not
-+     * necessary to call 'mc_login' method because the method provides only
-+     * verification of credentials.
-+     */
-+    verify_credentials(&mbt_settings);
-+
-+    if (abrt_hash)
-+    {
-+        log(_("Looking for similar problems in CentOS Bug Tracker"));
-+        GList *ids = mantisbt_search_by_abrt_hash(&mbt_settings, abrt_hash);
-+        mantisbt_settings_free(&mbt_settings);
-+
-+        if (ids == NULL)
-+            return EXIT_FAILURE;
-+
-+        puts(ids->data);
-+        response_values_free(ids);
-+        return EXIT_SUCCESS;
-+    }
-+
-+    mantisbt_get_project_id_from_name(&mbt_settings);
-+
-+    if (opts & OPT_t)
-+    {
-+        if (!argv[0])
-+            show_usage_and_die(program_usage_string, program_options);
-+
-+        if (!ticket_no)
-+        {
-+            struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
-+            if (!dd)
-+                xfunc_die();
-+            report_result_t *reported_to = find_in_reported_to(dd, "CentOS Bug Tracker");
-+            dd_close(dd);
-+
-+            if (!reported_to || !reported_to->url)
-+                error_msg_and_die(_("Can't get MantisBT ID because this problem has not yet been reported to MantisBT."));
-+
-+            char *url = reported_to->url;
-+            reported_to->url = NULL;
-+            free_report_result(reported_to);
-+
-+            if (prefixcmp(url, mbt_settings.m_mantisbt_url) != 0)
-+                error_msg_and_die(_("This problem has been reported to MantisBT '%s' which differs from the configured MantisBT '%s'."), url, mbt_settings.m_mantisbt_url);
-+
-+            ticket_no = strrchr(url, '=');
-+            if (!ticket_no)
-+                error_msg_and_die(_("Malformed url to MantisBT '%s'."), url);
-+
-+            /* won't ever call free on it - it simplifies the code a lot */
-+            ticket_no = xstrdup(ticket_no + 1);
-+            log(_("Using CentOS Bug Tracker ID '%s'"), ticket_no);
-+        }
-+
-+        /* Attach files to existing MantisBT issues */
-+        while (*argv)
-+        {
-+            const char *path = *argv++;
-+            char *filename = basename(path);
-+            log(_("Attaching file '%s' to issue %s"), filename, ticket_no);
-+            mantisbt_attach_file(&mbt_settings, ticket_no, filename, path);
-+        }
-+
-+        return 0;
-+    }
-+
-+    /* Create new issue in MantisBT */
-+
-+    if (!(opts & OPT_f))
-+    {
-+        struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
-+        if (!dd)
-+            xfunc_die();
-+        report_result_t *reported_to = find_in_reported_to(dd, "CentOS Bug Tracker");
-+        dd_close(dd);
-+
-+        if (reported_to && reported_to->url)
-+        {
-+            char *msg = xasprintf(_("This problem was already reported to CentOS Bug Tracker (see '%s')."
-+                            " Do you still want to create a new issue?"),
-+                            reported_to->url);
-+            int yes = ask_yes_no(msg);
-+            free(msg);
-+            if (!yes)
-+                return 0;
-+        }
-+        free_report_result(reported_to);
-+    }
-+
-+    problem_data_t *problem_data = create_problem_data_for_reporting(dump_dir_name);
-+    if (!problem_data)
-+        xfunc_die(); /* create_problem_data_for_reporting already emitted error msg */
-+
-+    const char *category = problem_data_get_content_or_die(problem_data, FILENAME_COMPONENT);
-+    const char *duphash   = problem_data_get_content_or_die(problem_data, FILENAME_DUPHASH);
-+
-+    if (opts & OPT_D)
-+    {
-+        problem_formatter_t *pf = problem_formatter_new();
-+        problem_formatter_add_section(pf, PR_SEC_ADDITIONAL_INFO, /* optional section */ 0);
-+
-+        if (problem_formatter_load_file(pf, fmt_file))
-+            error_msg_and_die("Invalid format file: %s", fmt_file);
-+
-+        problem_report_t *pr = NULL;
-+        if (problem_formatter_generate_report(pf, problem_data, &pr))
-+            error_msg_and_die("Failed to format issue report from problem data");
-+
-+        printf("summary: %s\n"
-+                "\n"
-+                "Description:\n%s\n"
-+                "Additional info:\n%s\n"
-+                , problem_report_get_summary(pr)
-+                , problem_report_get_description(pr)
-+                , problem_report_get_section(pr, PR_SEC_ADDITIONAL_INFO)
-+        );
-+
-+        puts("attachments:");
-+        for (GList *a = problem_report_get_attachments(pr); a != NULL; a = g_list_next(a))
-+            printf(" %s\n", (const char *)a->data);
-+
-+        problem_report_free(pr);
-+        problem_formatter_free(pf);
-+        exit(0);
-+    }
-+
-+     int bug_id = 0;
-+
-+    /* If REMOTE_RESULT contains "DUPLICATE 12345", we consider it a dup of 12345
-+     * and won't search on MantisBT server.
-+     */
-+    char *remote_result;
-+    remote_result = problem_data_get_content_or_NULL(problem_data, FILENAME_REMOTE_RESULT);
-+    if (remote_result)
-+    {
-+        char *cmd = strtok(remote_result, " \n");
-+        char *id = strtok(NULL, " \n");
-+
-+        if (!prefixcmp(cmd, "DUPLICATE"))
-+        {
-+            errno = 0;
-+            char *e;
-+            bug_id = strtoul(id, &e, 10);
-+            if (errno || id == e || *e != '\0' || bug_id > INT_MAX)
-+            {
-+                /* error / no digits / illegal trailing chars / too big a number */
-+                bug_id = 0;
-+            }
-+        }
-+    }
-+
-+    mantisbt_issue_info_t *ii;
-+    if (!bug_id)
-+    {
-+        log(_("Checking for duplicates"));
-+
-+        int existing_id = -1;
-+        int crossver_id = -1;
-+        {
-+            /* Figure out whether we want to match category
-+             * when doing dup search.
-+             */
-+            const char *category_substitute = is_in_comma_separated_list(category, mbt_settings.m_DontMatchComponents) ? NULL : category;
-+
-+            /* We don't do dup detection across versions (see below why),
-+             * but we do add a note if cross-version potential dup exists.
-+             * For that, we search for cross version dups first:
-+             */
-+            // SOAP API searching method is not in the final version, it's possible the project will be string
-+            GList *crossver_bugs_ids = mantisbt_search_duplicate_issues(&mbt_settings, category_substitute, /*version*/ NULL, duphash);
-+
-+            unsigned crossver_bugs_count = g_list_length(crossver_bugs_ids);
-+            log_debug("CentOS Bug Tracker has %i reports with duphash '%s' including cross-version ones",
-+                    crossver_bugs_count, duphash);
-+            if (crossver_bugs_count > 0)
-+                crossver_id = atoi(g_list_first(crossver_bugs_ids)->data);
-+
-+            if (crossver_bugs_count > 0)
-+            {
-+                // SOAP API searching method is not in the final version, it's possible the project will be string
-+                GList *dup_bugs_ids = mantisbt_search_duplicate_issues(&mbt_settings, category_substitute, mbt_settings.m_project_version, duphash);
-+
-+                unsigned dup_bugs_count =  g_list_length(dup_bugs_ids);
-+                log_debug("CentOS Bug Tracker has %i reports with duphash '%s'",
-+                        dup_bugs_count, duphash);
-+                if (dup_bugs_count > 0)
-+                    existing_id = atoi(g_list_first(dup_bugs_ids)->data);
-+            }
-+        }
-+
-+        if (existing_id < 0)
-+        {
-+            /* Create new issue */
-+            log(_("Creating a new issue"));
-+            problem_formatter_t *pf = problem_formatter_new();
-+            problem_formatter_add_section(pf, PR_SEC_ADDITIONAL_INFO, 0);
-+
-+            if (problem_formatter_load_file(pf, fmt_file))
-+                error_msg_and_die(_("Invalid format file: %s"), fmt_file);
-+
-+            problem_report_t *pr = NULL;
-+            if (problem_formatter_generate_report(pf, problem_data, &pr))
-+                error_msg_and_die(_("Failed to format problem data"));
-+
-+            if (crossver_id >= 0)
-+                problem_report_buffer_printf(
-+                        problem_report_get_buffer(pr, PR_SEC_DESCRIPTION),
-+                        "\nPotential duplicate: issue %u\n", crossver_id);
-+
-+            problem_formatter_free(pf);
-+
-+            /* get tracker URL if exists */
-+            struct dump_dir *dd = dd_opendir(dump_dir_name, 0);
-+            char *tracker_url = NULL;
-+            if (dd)
-+            {
-+                report_result_t *reported_to = find_in_reported_to(dd, tracker_str);
-+                dd_close(dd);
-+
-+                if (reported_to && reported_to->url)
-+                {
-+                    log(_("Adding External URL to issue"));
-+                    tracker_url = xstrdup(reported_to->url);
-+                    free_report_result(reported_to);
-+                }
-+            }
-+
-+            int new_id = mantisbt_create_new_issue(&mbt_settings, problem_data, pr, tracker_url);
-+
-+            free(tracker_url);
-+
-+            if (new_id == -1)
-+                return EXIT_FAILURE;
-+
-+            log(_("Adding attachments to issue %i"), new_id);
-+            char *new_id_str = xasprintf("%u", new_id);
-+
-+            for (GList *a = problem_report_get_attachments(pr); a != NULL; a = g_list_next(a))
-+            {
-+                const char *item_name = (const char *)a->data;
-+                struct problem_item *item = problem_data_get_item_or_NULL(problem_data, item_name);
-+                if (!item)
-+                    continue;
-+                else if (item->flags & CD_FLAG_TXT)
-+                    mantisbt_attach_data(&mbt_settings, new_id_str, item_name, item->content, strlen(item->content));
-+                else if (item->flags & CD_FLAG_BIN)
-+                    mantisbt_attach_file(&mbt_settings, new_id_str, item_name, item->content);
-+            }
-+
-+            free(new_id_str);
-+            problem_report_free(pr);
-+            ii = mantisbt_issue_info_new();
-+            ii->mii_id = new_id;
-+            ii->mii_status = xstrdup("new");
-+
-+            goto finish;
-+        }
-+
-+        bug_id = existing_id;
-+    }
-+
-+    ii = mantisbt_get_issue_info(&mbt_settings, bug_id);
-+
-+    log(_("Bug is already reported: %i"), ii->mii_id);
-+
-+    /* Follow duplicates */
-+    if ((strcmp(ii->mii_status, "closed") == 0)
-+     && (strcmp(ii->mii_resolution, "duplicate") == 0)
-+    ) {
-+        mantisbt_issue_info_t *origin = mantisbt_find_origin_bug_closed_duplicate(&mbt_settings, ii);
-+        if (origin)
-+        {
-+            mantisbt_issue_info_free(ii);
-+            ii = origin;
-+        }
-+    }
-+
-+    /* TODO CC list
-+     * Is no MantisBT SOAP API method which allows adding users to CC list
-+     * without updating issue.
-+     */
-+
-+    /* Add comment and bt */
-+    const char *comment = problem_data_get_content_or_NULL(problem_data, FILENAME_COMMENT);
-+    if (comment && comment[0])
-+    {
-+        problem_formatter_t *pf = problem_formatter_new();
-+
-+        if (problem_formatter_load_file(pf, fmt_file2))
-+            error_msg_and_die(_("Invalid duplicate format file: '%s"), fmt_file2);
-+
-+        problem_report_t *pr;
-+        if (problem_formatter_generate_report(pf, problem_data, &pr))
-+            error_msg_and_die(_("Failed to format duplicate comment from problem data"));
-+
-+        const char *mbtcomment = problem_report_get_description(pr);
-+
-+        int dup_comment = is_comment_dup(ii->mii_notes, mbtcomment);
-+        if (!dup_comment)
-+        {
-+            log(_("Adding new comment to issue %d"), ii->mii_id);
-+            mantisbt_add_issue_note(&mbt_settings, ii->mii_id, mbtcomment);
-+
-+            const char *bt = problem_data_get_content_or_NULL(problem_data, FILENAME_BACKTRACE);
-+            unsigned rating = 0;
-+            const char *rating_str = problem_data_get_content_or_NULL(problem_data, FILENAME_RATING);
-+            /* python doesn't have rating file */
-+            if (rating_str)
-+                rating = xatou(rating_str);
-+            if (bt && rating > ii->mii_best_bt_rating)
-+            {
-+                char *bug_id_str = xasprintf("%i", ii->mii_id);
-+
-+                log(_("Attaching better backtrace"));
-+
-+                // find unique filename of attachment
-+                char *name = NULL;
-+                for (int i = 0;; ++i)
-+                {
-+                    if (i == 0)
-+                        name = xasprintf("%s", FILENAME_BACKTRACE);
-+                    else
-+                        name = xasprintf("%s%d", FILENAME_BACKTRACE, i);
-+
-+                    if (g_list_find_custom(ii->mii_attachments, name, (GCompareFunc) strcmp) == NULL)
-+                        break;
-+
-+                    free(name);
-+                }
-+                mantisbt_attach_data(&mbt_settings, bug_id_str, name, bt, strlen(bt));
-+
-+                free(name);
-+                free(bug_id_str);
-+            }
-+        }
-+        else
-+            log(_("Found the same comment in the issue history, not adding a new one"));
-+
-+        problem_report_free(pr);
-+        problem_formatter_free(pf);
-+    }
-+
-+finish:
-+    log(_("Status: %s%s%s %s/view.php?id=%u"),
-+                ii->mii_status,
-+                ii->mii_resolution ? " " : "",
-+                ii->mii_resolution ? ii->mii_resolution : "",
-+                mbt_settings.m_mantisbt_url,
-+                ii->mii_id);
-+
-+    struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ 0);
-+    if (dd)
-+    {
-+        char *msg = xasprintf("CentOS Bug Tracker: URL=%s/view.php?id=%u", mbt_settings.m_mantisbt_url, ii->mii_id);
-+        add_reported_to(dd, msg);
-+        free(msg);
-+        dd_close(dd);
-+    }
-+
-+    mantisbt_settings_free(&mbt_settings);
-+    return 0;
-+}
-diff --git a/src/workflows/Makefile.am b/src/workflows/Makefile.am
-index 72502ca..7ecb34e 100644
---- a/src/workflows/Makefile.am
-+++ b/src/workflows/Makefile.am
-@@ -23,6 +23,18 @@ dist_workflows_DATA = \
-     workflow_Logger.xml \
-     workflow_LoggerCCpp.xml
- 
-+if BUILD_MANTISBT
-+dist_workflows_DATA += \
-+    workflow_CentOSCCpp.xml \
-+    workflow_CentOSKerneloops.xml \
-+    workflow_CentOSPython.xml \
-+    workflow_CentOSPython3.xml \
-+    workflow_CentOSVmcore.xml \
-+    workflow_CentOSXorg.xml \
-+    workflow_CentOSLibreport.xml \
-+    workflow_CentOSJava.xml
-+endif
-+
- if BUILD_BUGZILLA
- dist_workflows_DATA += \
-     workflow_AnacondaFedora.xml \
-@@ -46,7 +58,8 @@ dist_workflowsdef_DATA =\
-     report_uReport.conf \
-     report_mailx.conf \
-     report_logger.conf \
--    report_uploader.conf
-+    report_uploader.conf \
-+    report_centos.conf
- 
- if BUILD_BUGZILLA
- dist_workflowsdef_DATA += \
-diff --git a/src/workflows/report_centos.conf b/src/workflows/report_centos.conf
-new file mode 100644
-index 0000000..07b0d40
---- /dev/null
-+++ b/src/workflows/report_centos.conf
-@@ -0,0 +1,31 @@
-+EVENT=workflow_CentOSLibreport analyzer=libreport
-+# this is just a meta event which consists of other events
-+# the list is defined in the xml file
-+
-+EVENT=workflow_CentOSCCpp analyzer=CCpp
-+# this is just a meta event which consists of other events
-+# the list is defined in the xml file
-+
-+EVENT=workflow_CentOSPython analyzer=Python component!=anaconda
-+# this is just a meta event which consists of other events
-+# the list is defined in the xml file
-+
-+EVENT=workflow_CentOSPython3 analyzer=Python3 component!=anaconda
-+# this is just a meta event which consists of other events
-+# the list is defined in the xml file
-+
-+EVENT=workflow_CentOSKerneloops analyzer=Kerneloops
-+# this is just a meta event which consists of other events
-+# the list is defined in the xml file
-+
-+EVENT=workflow_CentOSVmcore analyzer=vmcore
-+# this is just a meta event which consists of other events
-+# the list is defined in the xml file
-+
-+EVENT=workflow_CentOSXorg analyzer=xorg
-+# this is just a meta event which consists of other events
-+# the list is defined in the xml file
-+
-+EVENT=workflow_CentOSJava analyzer=Java
-+# this is just a meta event which consists of other events
-+# the list is defined in the xml file
-diff --git a/src/workflows/workflow_CentOSCCpp.xml.in b/src/workflows/workflow_CentOSCCpp.xml.in
-new file mode 100644
-index 0000000..ea94d56
---- /dev/null
-+++ b/src/workflows/workflow_CentOSCCpp.xml.in
-@@ -0,0 +1,12 @@
-+<?xml version="1.0" encoding="UTF-8" ?>
-+<workflow>
-+    <_name>Report to CentOS Bug Tracker</_name>
-+    <_description>Process the C/C++ crash using the CentOS infrastructure</_description>
-+
-+    <events>
-+        <event>report_uReport</event>
-+        <event>collect_*</event>
-+        <event>analyze_CCpp</event>
-+        <event>report_CentOSBugTracker</event>
-+    </events>
-+</workflow>
-diff --git a/src/workflows/workflow_CentOSJava.xml.in b/src/workflows/workflow_CentOSJava.xml.in
-new file mode 100644
-index 0000000..89f9295
---- /dev/null
-+++ b/src/workflows/workflow_CentOSJava.xml.in
-@@ -0,0 +1,11 @@
-+<?xml version="1.0" encoding="UTF-8" ?>
-+<workflow>
-+    <_name>Report to CentOS Bug Tracker</_name>
-+    <_description>Process the Java exception using the CentOS infrastructure</_description>
-+
-+    <events>
-+        <event>report_uReport</event>
-+        <event>collect_*</event>
-+        <event>report_CentOSBugTracker</event>
-+    </events>
-+</workflow>
-diff --git a/src/workflows/workflow_CentOSKerneloops.xml.in b/src/workflows/workflow_CentOSKerneloops.xml.in
-new file mode 100644
-index 0000000..c43c681
---- /dev/null
-+++ b/src/workflows/workflow_CentOSKerneloops.xml.in
-@@ -0,0 +1,11 @@
-+<?xml version="1.0" encoding="UTF-8" ?>
-+<workflow>
-+    <_name>Report to CentOS Bug Tracker</_name>
-+    <_description>Process the kerneloops using the CentOS infrastructure</_description>
-+
-+    <events>
-+        <event>report_uReport</event>
-+        <event>collect_*</event>
-+        <event>report_CentOSBugTracker</event>
-+    </events>
-+</workflow>
-diff --git a/src/workflows/workflow_CentOSLibreport.xml.in b/src/workflows/workflow_CentOSLibreport.xml.in
-new file mode 100644
-index 0000000..2f6ed82
---- /dev/null
-+++ b/src/workflows/workflow_CentOSLibreport.xml.in
-@@ -0,0 +1,9 @@
-+<?xml version="1.0" encoding="UTF-8" ?>
-+<workflow>
-+    <_name>Report to CentOS Bug Tracker</_name>
-+    <_description>Process the problem using the CentOS infrastructure</_description>
-+
-+    <events>
-+        <event>report_CentOSBugTracker</event>
-+    </events>
-+</workflow>
-diff --git a/src/workflows/workflow_CentOSPython.xml.in b/src/workflows/workflow_CentOSPython.xml.in
-new file mode 100644
-index 0000000..7e26c6c
---- /dev/null
-+++ b/src/workflows/workflow_CentOSPython.xml.in
-@@ -0,0 +1,11 @@
-+<?xml version="1.0" encoding="UTF-8" ?>
-+<workflow>
-+    <_name>Report to CentOS Bug Tracker</_name>
-+    <_description>Process the python exception using the CentOS infrastructure</_description>
-+
-+    <events>
-+        <event>report_uReport</event>
-+        <event>collect_*</event>
-+        <event>report_CentOSBugTracker</event>
-+    </events>
-+</workflow>
-diff --git a/src/workflows/workflow_CentOSPython3.xml.in b/src/workflows/workflow_CentOSPython3.xml.in
-new file mode 100644
-index 0000000..f1dd8a9
---- /dev/null
-+++ b/src/workflows/workflow_CentOSPython3.xml.in
-@@ -0,0 +1,11 @@
-+<?xml version="1.0" encoding="UTF-8" ?>
-+<workflow>
-+    <_name>Report to CentOS Bug Tracker</_name>
-+    <_description>Process the python 3 exception using the CentOS infrastructure</_description>
-+
-+    <events>
-+        <event>report_uReport</event>
-+        <event>collect_*</event>
-+        <event>report_CentOSBugTracker</event>
-+    </events>
-+</workflow>
-diff --git a/src/workflows/workflow_CentOSVmcore.xml.in b/src/workflows/workflow_CentOSVmcore.xml.in
-new file mode 100644
-index 0000000..c876594
---- /dev/null
-+++ b/src/workflows/workflow_CentOSVmcore.xml.in
-@@ -0,0 +1,12 @@
-+<?xml version="1.0" encoding="UTF-8" ?>
-+<workflow>
-+    <_name>Report to CentOS Bug Tracker</_name>
-+    <_description>Process the kernel crash using the CentOS infrastructure</_description>
-+
-+    <events>
-+        <event>analyze_VMcore</event>
-+        <event>report_uReport</event>
-+        <event>collect_*</event>
-+        <event>report_CentOSBugTracker</event>
-+    </events>
-+</workflow>
-diff --git a/src/workflows/workflow_CentOSXorg.xml.in b/src/workflows/workflow_CentOSXorg.xml.in
-new file mode 100644
-index 0000000..bf52221
---- /dev/null
-+++ b/src/workflows/workflow_CentOSXorg.xml.in
-@@ -0,0 +1,9 @@
-+<?xml version="1.0" encoding="UTF-8" ?>
-+<workflow>
-+    <_name>Report to CentOS Bug Tracker</_name>
-+    <_description>Process the X Server problem using the CentOS infrastructure</_description>
-+
-+    <events>
-+        <event>report_CentOSBugTracker</event>
-+    </events>
-+</workflow>
--- 
-1.8.3.1
-
diff --git a/SOURCES/1007-reporter-mantisbt-change-default-formating-file-for-.patch b/SOURCES/1007-reporter-mantisbt-change-default-formating-file-for-.patch
deleted file mode 100644
index 6f1777a..0000000
--- a/SOURCES/1007-reporter-mantisbt-change-default-formating-file-for-.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 8d54f840cdb094ca8e32f02e967393d7498ee26d Mon Sep 17 00:00:00 2001
-From: Matej Habrnal <mhabrnal@redhat.com>
-Date: Fri, 20 Feb 2015 00:27:05 +0100
-Subject: [PATCH 1007/1015] reporter-mantisbt: change default formating file
- for duplicate issues
-
-reporter-mantisbt doesn't work well with mantisbt_format.conf as a default
-format conf file for creating duplicate issues because the note which is added
-doesn't contain an 'Additional information' section.
-
-Default formating file for duplicate is mantisbt_formatdup.conf
-
-Signed-off-by: Matej Habrnal <mhabrnal@redhat.com>
----
- src/plugins/reporter-mantisbt.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/src/plugins/reporter-mantisbt.c b/src/plugins/reporter-mantisbt.c
-index d281cdb..dc9968f 100644
---- a/src/plugins/reporter-mantisbt.c
-+++ b/src/plugins/reporter-mantisbt.c
-@@ -253,7 +253,8 @@ int main(int argc, char **argv)
-         "\nRecognized boolean parameter (VALUE should be 1/0, yes/no): SSLVerify, CreatePrivate."
-         "\nParameters can be overridden via $Mantisbt_PARAM environment variables."
-         "\n"
--        "\nFMTFILE and FMTFILE2 default to "CONF_DIR"/plugins/mantisbt_format.conf"
-+        "\nFMTFILE default to "CONF_DIR"/plugins/mantisbt_format.conf."
-+        "\nFMTFILE2 default to "CONF_DIR"/plugins/mantisbt_formatdup.conf."
-     );
- 
-     enum {
-@@ -272,7 +273,7 @@ int main(int argc, char **argv)
-     const char *dump_dir_name = ".";
-     GList *conf_file = NULL;
-     const char *fmt_file = CONF_DIR"/plugins/mantisbt_format.conf";
--    const char *fmt_file2 = fmt_file;
-+    const char *fmt_file2 = CONF_DIR"/plugins/mantisbt_formatdup.conf";
-     char *abrt_hash = NULL;
-     char *ticket_no = NULL;
-     const char *tracker_str = "ABRT Server";
--- 
-1.8.3.1
-
diff --git a/SOURCES/1009-reporter-mantisbt-adds-man-pages-for-reporter-mantis.patch b/SOURCES/1009-reporter-mantisbt-adds-man-pages-for-reporter-mantis.patch
deleted file mode 100644
index efb3a9f..0000000
--- a/SOURCES/1009-reporter-mantisbt-adds-man-pages-for-reporter-mantis.patch
+++ /dev/null
@@ -1,528 +0,0 @@
-From 9c819b8c77ea5c05e3a37117a2174162160b1c57 Mon Sep 17 00:00:00 2001
-From: Matej Habrnal <mhabrnal@redhat.com>
-Date: Fri, 20 Feb 2015 03:14:54 +0100
-Subject: [PATCH 1009/1015] reporter-mantisbt: adds man pages for
- reporter-mantisbt
-
-Signed-off-by: Matej Habrnal <mhabrnal@redhat.com>
-
-Conflicts:
-	doc/Makefile.am
----
- doc/Makefile.am                      |  13 ++-
- doc/centos_report_event.conf.5       |   1 +
- doc/mantisbt.conf.txt                |  18 +++
- doc/mantisbt_format.conf.txt         |  18 +++
- doc/mantisbt_formatdup.conf.txt      |  18 +++
- doc/report_CentOSBugTracker.conf.txt |  45 +++++++
- doc/report_centos.conf.txt           |  41 +++++++
- doc/reporter-mantisbt.txt            | 219 +++++++++++++++++++++++++++++++++++
- src/plugins/Makefile.am              |   4 +
- src/workflows/Makefile.am            |  12 ++
- 10 files changed, 387 insertions(+), 2 deletions(-)
- create mode 100644 doc/centos_report_event.conf.5
- create mode 100644 doc/mantisbt.conf.txt
- create mode 100644 doc/mantisbt_format.conf.txt
- create mode 100644 doc/mantisbt_formatdup.conf.txt
- create mode 100644 doc/report_CentOSBugTracker.conf.txt
- create mode 100644 doc/report_centos.conf.txt
- create mode 100644 doc/reporter-mantisbt.txt
-
-diff --git a/doc/Makefile.am b/doc/Makefile.am
-index 83a41d9..e437388 100644
---- a/doc/Makefile.am
-+++ b/doc/Makefile.am
-@@ -25,6 +25,7 @@ MAN1_TXT += reporter-print.txt
- MAN1_TXT += reporter-rhtsupport.txt
- MAN1_TXT += reporter-upload.txt
- MAN1_TXT += reporter-ureport.txt
-+MAN1_TXT += reporter-mantisbt.txt
- 
- MAN5_TXT =
- MAN5_TXT += anaconda_event.conf.txt
-@@ -37,6 +38,9 @@ MAN5_TXT += bugzilla_formatdup_anaconda.conf.txt
- MAN5_TXT += bugzilla_formatdup.conf.txt
- MAN5_TXT += bugzilla_format_kernel.conf.txt
- MAN5_TXT += bugzilla_format_libreport.conf.txt
-+MAN5_TXT += mantisbt.conf.txt
-+MAN5_TXT += mantisbt_format.conf.txt
-+MAN5_TXT += mantisbt_formatdup.conf.txt
- MAN5_TXT += emergencyanalysis_event.conf.txt
- MAN5_TXT += forbidden_words.conf.txt
- MAN5_TXT += mailx.conf.txt
-@@ -45,6 +49,7 @@ MAN5_TXT += print_event.conf.txt
- MAN5_TXT += report_Bugzilla.conf.txt
- MAN5_TXT += report_event.conf.txt
- MAN5_TXT += report_fedora.conf.txt
-+MAN5_TXT += report_centos.conf.txt
- MAN5_TXT += report_Logger.conf.txt
- MAN5_TXT += report_rhel.conf.txt
- MAN5_TXT += report_rhel_bugzilla.conf.txt
-@@ -53,15 +58,19 @@ MAN5_TXT += report_logger.conf.txt
- MAN5_TXT += report_mailx.conf.txt
- MAN5_TXT += report_uploader.conf.txt
- MAN5_TXT += report_Uploader.conf.txt
-+MAN5_TXT += report_CentOSBugTracker.conf.txt
- MAN5_TXT += rhtsupport.conf.txt
- MAN5_TXT += rhtsupport_event.conf.txt
- MAN5_TXT += uploader_event.conf.txt
- MAN5_TXT += ureport.conf.txt
- MAN5_TXT += upload.conf.txt
- 
-+MAN5_PREFORMATTED =
-+MAN5_PREFORMATTED += centos_report_event.conf.5
-+
- # Manual pages are generated from .txt via Docbook
- man1_MANS = ${MAN1_TXT:%.txt=%.1}
--man5_MANS = ${MAN5_TXT:%.txt=%.5}
-+man5_MANS = ${MAN5_TXT:%.txt=%.5} ${MAN5_PREFORMATTED}
- 
- SUFFIXES = .1 .5
- 
-@@ -76,5 +85,5 @@ SUFFIXES = .1 .5
-                                     --conf-file ../asciidoc.conf \
-                                     -alibreport_version=$(PACKAGE_VERSION) -o $@ $<
- 
--EXTRA_DIST = $(MAN1_TXT) $(MAN5_TXT)
-+EXTRA_DIST = $(MAN1_TXT) $(MAN5_TXT) $(MAN5_PREFORMATTED)
- CLEANFILES = $(man1_MANS)
-diff --git a/doc/centos_report_event.conf.5 b/doc/centos_report_event.conf.5
-new file mode 100644
-index 0000000..71c3fcb
---- /dev/null
-+++ b/doc/centos_report_event.conf.5
-@@ -0,0 +1 @@
-+.so man5/report_event.conf.5
-diff --git a/doc/mantisbt.conf.txt b/doc/mantisbt.conf.txt
-new file mode 100644
-index 0000000..d4ba605
---- /dev/null
-+++ b/doc/mantisbt.conf.txt
-@@ -0,0 +1,18 @@
-+mantisbt.conf(5)
-+===============
-+
-+NAME
-+----
-+mantisbt.conf - configuration file for libreport.
-+
-+DESCRIPTION
-+-----------
-+This configuration file provides default configuration for 'reporter-mantisbt'.
-+
-+SEE ALSO
-+--------
-+reporter-mantisbt(1)
-+
-+AUTHOR
-+------
-+* ABRT team
-diff --git a/doc/mantisbt_format.conf.txt b/doc/mantisbt_format.conf.txt
-new file mode 100644
-index 0000000..860d911
---- /dev/null
-+++ b/doc/mantisbt_format.conf.txt
-@@ -0,0 +1,18 @@
-+mantisbt_format.conf(5)
-+=======================
-+
-+NAME
-+----
-+mantisbt_format.conf - configuration file for libreport.
-+
-+DESCRIPTION
-+-----------
-+This configuration file provides definition of general formatting for new MantisBT issues.
-+
-+SEE ALSO
-+--------
-+reporter-mantisbt(1)
-+
-+AUTHOR
-+------
-+* ABRT Team
-diff --git a/doc/mantisbt_formatdup.conf.txt b/doc/mantisbt_formatdup.conf.txt
-new file mode 100644
-index 0000000..a617226
---- /dev/null
-+++ b/doc/mantisbt_formatdup.conf.txt
-@@ -0,0 +1,18 @@
-+mantisbt_formatdup.conf(5)
-+==========================
-+
-+NAME
-+----
-+mantisbt_formatdup.conf - configuration file for libreport.
-+
-+DESCRIPTION
-+-----------
-+This configuration file provides definition of general formatting for duplicate MantisBT issues.
-+
-+SEE ALSO
-+--------
-+reporter-mantisbt(1)
-+
-+AUTHOR
-+------
-+* ABRT Team
-diff --git a/doc/report_CentOSBugTracker.conf.txt b/doc/report_CentOSBugTracker.conf.txt
-new file mode 100644
-index 0000000..6ba35d3
---- /dev/null
-+++ b/doc/report_CentOSBugTracker.conf.txt
-@@ -0,0 +1,45 @@
-+report_CentOSBugTracker.conf(5)
-+===============================
-+
-+NAME
-+----
-+report_CentOSBugTracker.conf - libreport's configuration file for 'report_CentOSBugTracker' events.
-+
-+DESCRIPTION
-+-----------
-+This configuration file contains values for options defined in
-+/usr/share/libreport/events/report_CentOSBugTracker.xml
-+
-+Configuration file lines should have 'PARAM = VALUE' format. The parameters are:
-+
-+'Mantisbt_Login'::
-+	Login to MantisBT account.
-+
-+'Mantisbt_Password'::
-+	Password to MantisBT account.
-+
-+'Mantisbt_MantisbtURL'::
-+	MantisBT HTTP(S) address. (default: https://bugs.centos.org)
-+
-+'Mantisbt_SSLVerify'::
-+	Use yes/true/on/1 to verify server's SSL certificate. (default: yes)
-+
-+'Mantisbt_Project'::
-+	Project issue field value. Useful if you needed different project than specified in /etc/os-release
-+
-+'Mantisbt_ProjectVersion'::
-+	Version issue field value. Useful if you needed different project version than specified in /etc/os-release
-+
-+'http_proxy'::
-+	the proxy server to use for HTTP
-+
-+'HTTPS_PROXY'::
-+	the proxy server to use for HTTPS
-+
-+SEE ALSO
-+--------
-+report_event.conf(5), reporter-mantisbt(1)
-+
-+AUTHOR
-+------
-+* ABRT team
-diff --git a/doc/report_centos.conf.txt b/doc/report_centos.conf.txt
-new file mode 100644
-index 0000000..23a5fde
---- /dev/null
-+++ b/doc/report_centos.conf.txt
-@@ -0,0 +1,41 @@
-+report_centos.conf(5)
-+=====================
-+
-+NAME
-+----
-+report_centos.conf - configuration file for libreport.
-+
-+DESCRIPTION
-+-----------
-+This configuration file specifies which of the reporting work flow definitions
-+are applicable for all problems types on CentOS.
-+
-+All applicable work flows are presented to users in User Interface as
-+possibilities for processing of any problems. A particular work flow becomes
-+applicable if its conditions are satisfied.
-+
-+This configuration file consists from one condition per line.
-+
-+Each condition line must start with EVENT=workflow_NAME where "workflow_" is
-+constant prefix and "workflow_NAME" is base name of path to reporting work flow
-+configuration file.
-+
-+The rest of condition line has form VAR=VAL, VAR!=VAL or VAL~=REGEX, where VAR
-+is a name of problem directory element to be checked (for example,
-+"executable", "package", hostname" etc). The condition may consists
-+from as many element checks as it is necessary.
-+
-+EXAMPLES
-+--------
-+Condition line::
-+    EVENT=workflow_CentOSCCpp analyzer=CCpp
-+
-+The condition line above expects existence of /usr/share/libreport/workflows/workflow_CentOSCCpp.xml
-+
-+SEE ALSO
-+--------
-+report-gtk(1)
-+
-+AUTHOR
-+------
-+* ABRT team
-diff --git a/doc/reporter-mantisbt.txt b/doc/reporter-mantisbt.txt
-new file mode 100644
-index 0000000..92255b0
---- /dev/null
-+++ b/doc/reporter-mantisbt.txt
-@@ -0,0 +1,219 @@
-+reporter-mantisbt(1)
-+====================
-+
-+NAME
-+----
-+reporter-mantisbt - Reports problem to Mantis Bug Tracker.
-+
-+SYNOPSIS
-+--------
-+'reporter-mantisbt' [-vrf] [-c CONFFILE]... [-F FMTFILE] [-A FMTFILE2] -d DIR
-+
-+Or:
-+
-+'reporter-mantisbt' [-v] [-c CONFFILE]... [-d DIR] -t[ID] FILE...
-+
-+Or:
-+
-+'reporter-mantisbt' [-v] [-c CONFFILE]... -h DUPHASH
-+
-+DESCRIPTION
-+-----------
-+The tool reads problem directory DIR. Then it logs in to MantisBT
-+and tries to find an issue with the same duphash HEXSTRING in 'abrt_hash' field.
-+
-+If such issue is not found, then a new issue is created. Elements of DIR
-+are stored in the issue as part of issue description or as attachments,
-+depending on their type and size.
-+
-+Otherwise, if such issue is found and it is marked as CLOSED DUPLICATE,
-+the tool follows the chain of duplicates until it finds a non-DUPLICATE issue.
-+The tool adds a new note to found issue.
-+
-+The URL to new or modified issue is printed to stdout and recorded in
-+'reported_to' element in DIR.
-+
-+Option -t uploads FILEs to the already created issue on MantisBT site.
-+The issue ID is retrieved from directory specified by -d DIR.
-+If problem data in DIR was never reported to MantisBT, upload will fail.
-+
-+Option -tID uploads FILEs to the issue with specified ID on MantisBT site.
-+-d DIR is ignored.
-+
-+Option -r sets the last url from reporter_to element which is prefixed with
-+TRACKER_NAME to URL field. This option is applied only when a new issue is to be
-+filed. The default value is 'ABRT Server'"
-+
-+Configuration file
-+~~~~~~~~~~~~~~~~~~
-+If not specified, CONFFILE defaults to /etc/libreport/plugins/mantisbt.conf.
-+Configuration file lines should have 'PARAM = VALUE' format. The parameters are:
-+
-+'Login'::
-+	Login to MantisBT account.
-+
-+'Password'::
-+	Password to MantisBT account.
-+
-+'MantisbtURL'::
-+	MantisBT HTTP(S) address. (default: http://localhost/mantisbt)
-+
-+'SSLVerify'::
-+	Use yes/true/on/1 to verify server's SSL certificate. (default: no)
-+
-+'Project'::
-+	Project issue field value. Useful if you needed different project than specified in /etc/os-release
-+
-+'ProjectVersion'::
-+	Version issue field value. Useful if you needed different project version than specified in /etc/os-release
-+
-+'CreatePrivate'::
-+    Create private MantisBT issue. (default: no)
-+
-+Parameters can be overridden via $Mantisbt_PARAM environment variables.
-+
-+Formatting configuration files
-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+Lines starting with # are ignored.
-+
-+Lines can be continued on the next line using trailing backslash.
-+
-+Format:
-+
-+   "%summary:: summary format"
-+   "section:: element1[,element2]..."
-+   The literal text line to be added to MantisBT Description or Additional information. Can be empty.
-+   (Empty lines are NOT ignored!)
-+
-+   Summary format is a line of text, where %element% is replaced by
-+   text element's content, and [[...%element%...]] block is used only if
-+   %element% exists. [[...]] blocks can nest.
-+
-+   Sections can be:
-+   - %summary: issue Summary format string.
-+   - %attach: a list of elements to attach.
-+   - %Additional info: issue Additional Information content.
-+   - text, double colon (::) and the list of comma-separated elements.
-+
-+   Description and Additional information MantisBT's fields:
-+   All text, double colons (::) and lists of comma-separated elements which
-+   are placed above the section '%Additional info::' in the configuration file are
-+   stored in the 'Description' field in MantisBT. All text etc. which are placed
-+   under the '%Additional info::' are stored in the 'Additional information' field.
-+
-+   For example:
-+   |:: comment               |  (Description)
-+   |                         |  (Description)
-+   |Package:: package        |  (Description)
-+   |                         |  (Description)
-+   |%Additional_info::       |
-+   |%reporter%               |  (Additional info)
-+   |User:: user_name,uid     |  (Additional info)
-+   |                         |  (Additional info)
-+   |Directories:: root,cwd   |  (Additional info)
-+
-+   Elements can be:
-+   - problem directory element names, which get formatted as
-+     <element_name>: <contents>
-+     or
-+     <element_name>:
-+     :<contents>
-+     :<contents>
-+     :<contents>
-+   - problem directory element names prefixed by "%bare_",
-+     which is formatted as-is, without "<element_name>:" and colons
-+   - %oneline, %multiline, %text wildcards, which select all corresponding
-+     elements for output or attachment
-+   - %binary wildcard, valid only for %attach section, instructs to attach
-+     binary elements
-+   - problem directory element names prefixed by "-",
-+     which excludes given element from all wildcards
-+
-+     Nonexistent elements are silently ignored.
-+     If none of elements exists, the section will not be created.
-+
-+Integration with ABRT events
-+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+'reporter-mantisbt' can be used as an ABRT reporter. Example
-+fragment for /etc/libreport/report_event.conf:
-+
-+------------
-+# Report Python crashes
-+EVENT=report_CentOSBugTracker analyzer=Python
-+      reporter-mantisbt -d . -c /etc/libreport/plugins/mantisbt.conf
-+------------
-+
-+OPTIONS
-+-------
-+-d DIR::
-+   Path to problem directory.
-+
-+-c CONFFILE::
-+   Path to configuration file.
-+
-+-f::
-+   Force reporting even if this problem is already reported.
-+
-+-F CONF_FORMAT_FILE::
-+   Formatting file for new issues. Default: /etc/libreport/plugins/mantisbt_format.conf
-+
-+-A CONF_FORMAT_FILE::
-+   Formatting file for duplicates. Default: /etc/libreport/plugins/mantisbt_formatdup.conf
-+
-+-t[ID]::
-+   Upload FILEs to the already created issue on MantisBT site.
-+
-+-h::
-+--duphash DUPHASH::
-+   Search in MantisBT by abrt's DUPHASH and print ISSUE_ID.
-+
-+-r TRACKER_NAME::
-+   Set the last url from reporter_to element which is prefixed with TRACKER_NAME to URL field in MantisBT.
-+
-+ENVIRONMENT VARIABLES
-+---------------------
-+Environment variables take precedence over values provided in
-+the configuration file.
-+
-+'Mantisbt_Login'::
-+	Login to MantisBT account.
-+
-+'Mantisbt_Password'::
-+	Password to MantisBT account.
-+
-+'Mantisbt_MantisbtURL'::
-+	MantisBT HTTP(S) address. (default: http://localhost/mantisbt)
-+
-+'Mantisbt_SSLVerify'::
-+	Use yes/true/on/1 to verify server's SSL certificate. (default: no)
-+
-+'Mantisbt_Project'::
-+	Project issue field value. Useful if you needed different project than specified in /etc/os-release
-+
-+'Mantisbt_ProjectVersion'::
-+	Version issue field value. Useful if you needed different project version than specified in /etc/os-release
-+
-+'Mantisbt_CreatePrivate'::
-+    Create private MantisBT issue. (default: no)
-+
-+FILES
-+-----
-+/usr/share/libreport/conf.d/plugins/mantisbt.conf::
-+    Readonly default configuration files.
-+
-+/etc/libreport/plugins/mantisbt.conf::
-+    Configuration file.
-+
-+/etc/libreport/plugins/mantisbt_format.conf::
-+    Configure formating for reporting.
-+
-+/etc/libreport/plugins/mantisbt_formatdup.conf::
-+    Configure formating for reporting duplicates.
-+
-+SEE ALSO
-+--------
-+report_event.conf(5), mantisbt_format.conf(5), mantisbt_formatdup.conf(5)
-+
-+AUTHORS
-+-------
-+* ABRT team
-diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
-index fd3f477..27194a4 100644
---- a/src/plugins/Makefile.am
-+++ b/src/plugins/Makefile.am
-@@ -109,6 +109,10 @@ if BUILD_UREPORT
- reporters_extra_dist += report_uReport.xml.in
- endif
- 
-+if BUILD_MANTISBT
-+reporters_extra_dist += report_CentOSBugTracker.xml.in
-+endif
-+
- EXTRA_DIST = $(reporters_extra_dist) \
-     report_Logger.conf \
-     report_Logger.xml.in \
-diff --git a/src/workflows/Makefile.am b/src/workflows/Makefile.am
-index 7ecb34e..17127a0 100644
---- a/src/workflows/Makefile.am
-+++ b/src/workflows/Makefile.am
-@@ -107,3 +107,15 @@ EXTRA_DIST += \
-     workflow_RHELBugzillaLibreport.xml.in \
-     workflow_RHELBugzillaJava.xml.in
- endif
-+
-+if BUILD_MANTISBT
-+EXTRA_DIST += \
-+    workflow_CentOSCCpp.xml.in \
-+    workflow_CentOSKerneloops.xml.in \
-+    workflow_CentOSPython.xml.in \
-+    workflow_CentOSPython3.xml.in \
-+    workflow_CentOSVmcore.xml.in \
-+    workflow_CentOSXorg.xml.in \
-+    workflow_CentOSLibreport.xml.in \
-+    workflow_CentOSJava.xml.in
-+endif
--- 
-1.8.3.1
-
diff --git a/SOURCES/1010-move-problem_report-to-plugins.patch b/SOURCES/1010-move-problem_report-to-plugins.patch
deleted file mode 100644
index 9ba00e7..0000000
--- a/SOURCES/1010-move-problem_report-to-plugins.patch
+++ /dev/null
@@ -1,3284 +0,0 @@
-From a24be1f0915646dd0390884ceb4ee1bfae7fbe0c Mon Sep 17 00:00:00 2001
-From: Jakub Filak <jfilak@redhat.com>
-Date: Wed, 25 Mar 2015 16:43:19 +0100
-Subject: [PATCH 1010/1015] move problem_report to plugins
-
-Get rid of satyr from libreport.
-
-Signed-off-by: Jakub Filak <jfilak@redhat.com>
----
- po/POTFILES.in               |    2 +-
- src/include/Makefile.am      |    1 -
- src/include/problem_report.h |  334 ------------
- src/lib/Makefile.am          |    7 +-
- src/lib/problem_report.c     | 1210 ------------------------------------------
- src/plugins/Makefile.am      |   24 +-
- src/plugins/problem_report.c | 1210 ++++++++++++++++++++++++++++++++++++++++++
- src/plugins/problem_report.h |  334 ++++++++++++
- tests/testsuite.at           |    2 +-
- 9 files changed, 1568 insertions(+), 1556 deletions(-)
- delete mode 100644 src/include/problem_report.h
- delete mode 100644 src/lib/problem_report.c
- create mode 100644 src/plugins/problem_report.c
- create mode 100644 src/plugins/problem_report.h
-
-diff --git a/po/POTFILES.in b/po/POTFILES.in
-index 9cf8f72..8b62b59 100644
---- a/po/POTFILES.in
-+++ b/po/POTFILES.in
-@@ -25,11 +25,11 @@ src/lib/ureport.c
- src/lib/make_descr.c
- src/lib/parse_options.c
- src/lib/problem_data.c
--src/lib/problem_report.c
- src/lib/reported_to.c
- src/lib/reporters.c
- src/lib/run_event.c
- src/plugins/abrt_rh_support.c
-+src/plugins/problem_report.c
- src/plugins/report_Bugzilla.xml.in
- src/plugins/report.c
- src/plugins/reporter-bugzilla.c
-diff --git a/src/include/Makefile.am b/src/include/Makefile.am
-index 4d8c6a5..7a76cf4 100644
---- a/src/include/Makefile.am
-+++ b/src/include/Makefile.am
-@@ -5,7 +5,6 @@ libreport_include_HEADERS = \
-     dump_dir.h \
-     event_config.h \
-     problem_data.h \
--    problem_report.h \
-     report.h \
-     run_event.h \
-     libreport_curl.h \
-diff --git a/src/include/problem_report.h b/src/include/problem_report.h
-deleted file mode 100644
-index f2d41d8..0000000
---- a/src/include/problem_report.h
-+++ /dev/null
-@@ -1,334 +0,0 @@
--/*
--    Copyright (C) 2014  ABRT team
--    Copyright (C) 2014  RedHat Inc
--
--    This program is free software; you can redistribute it and/or modify
--    it under the terms of the GNU General Public License as published by
--    the Free Software Foundation; either version 2 of the License, or
--    (at your option) any later version.
--
--    This program is distributed in the hope that it will be useful,
--    but WITHOUT ANY WARRANTY; without even the implied warranty of
--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--    GNU General Public License for more details.
--
--    You should have received a copy of the GNU General Public License along
--    with this program; if not, write to the Free Software Foundation, Inc.,
--    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--
--    @brief API for formating of problem data
--
--    These functions can be used to convert a problem data to its string
--    representation.
--
--    The output format can be parsed from a string:
--
--        problem_formatter_t *formatter = problem_formatter_new();
--        problem_formatter_load_string(formatter, MY_FORMAT_STRING);
--
--    or loaded from a file:
--
--        problem_formatter_t *formatter = problem_formatter_new();
--        problem_formatter_load_file(formatter, MY_FORMAT_FILE);
--
--    Once you have configured your formatter you can convert problem_data to
--    problem_report by calling:
--
--        problem_report_t *report;
--        if (problem_formatter_generate_report(formatter, data, &report) != 0)
--            errx(EXIT_FAILURE, "Problem data cannot be converted to problem report.");
--
--    Now you can print the report:
--
--        printf("Problem: %s\n", problem_report_get_summary());
--        printf("%s\n",          problem_report_get_description());
--
--        puts("Problem attachments:");
--        for (GList *a = problem_report_get_attachments(pr); a != NULL; a = g_list_next(a))
--            printf(" %s\n", a->data);
--
--    Format description:
--
--         ----
--         %summary:: summary format
--         %attach:: elemnt1[,element2]...
--         section:: element1[,element2]...
--         The literal text line to be added to report.
--         ----
--
--         Summary format is a line of text, where %element% is replaced by
--         text element's content, and [[...%element%...]] block is used only if
--         %element% exists. [[...]] blocks can nest.
--
--         Sections can be:
--         - %summary: bug summary format string.
--
--         - %attach: a list of elements to attach.
--
--         - text, double colon (::) and the list of comma-separated elements.
--           Text can be empty (":: elem1, elem2, elem3" works),
--           in this case "Text:" header line will be omitted.
--
--         - %description: this section is implicit and contains all text
--           sections unless another section was specified (%summary and %attach
--           are ignored when determining text section's placement)
--
--         - every text element belongs to the last specified section (%summary
--           and %attach sections are ignored). If no section was specified,
--           the text element belogns to %description.
--
--         - If none of elements exists, the section will not be created.
--
--         - Empty lines are NOT ignored.
--
--         Elements can be:
--         - problem directory element names, which get formatted as
--           <element_name>: <contents>
--           or
--           <element_name>:
--           :<contents>
--           :<contents>
--           :<contents>
--
--         - problem directory element names prefixed by "%bare_",
--           which is formatted as-is, without "<element_name>:" and colons
--
--         - %oneline, %multiline, %text wildcards, which select all corresponding
--           elements for output or attachment
--
--         - %binary wildcard, valid only for %attach section, instructs to attach
--           binary elements
--
--         - problem directory element names prefixed by "-",
--           which excludes given element from all wildcards
--
--         - Nonexistent elements are silently ignored.
--
--    You can add your own section:
--
--        problem_formatter_t *formatter = problem_formatter_new();
--        problem_formatter_add_section(formatter, "additional_info", PFFF_REQUIRED);
--
--    and then you can use the section in the formatting string:
--
--        problem_formatter_load_string(formatter,
--                "::comment\n"
--                "%additional_info:: maps");
--        problem_formatter_generate_report(formatter, data, &report);
--
--        printf("Problem: %s\n",         problem_report_get_summary());
--        printf("%s\n",                  problem_report_get_description());
--        printf("Additional info: %s\n", problem_report_get_section(report, "additiona_info"));
--
--    The lines above are equivalent to the following lines:
--
--        printf("Problem: %s\n",         problem_data_get_content_or_NULL(data, "reason"));
--        printf("%s\n",                  problem_data_get_content_or_NULL(data, "comment"));
--        printf("Additional info: %s\n", problem_data_get_content_or_NULL(data, "maps"));
--*/
--#ifndef LIBREPORT_PROBLEM_REPORT_H
--#define LIBREPORT_PROBLEM_REPORT_H
--
--#include <glib.h>
--#include <stdio.h>
--#include "problem_data.h"
--
--#ifdef __cplusplus
--extern "C" {
--#endif
--
--#define PR_SEC_SUMMARY "summary"
--#define PR_SEC_DESCRIPTION "description"
--
--/*
-- * The problem report structure represents a problem data formatted according
-- * to a format string.
-- *
-- * A problem report is composed of well-known sections:
-- *   - summary
-- *   - descritpion
-- *   - attach
-- *
-- * and custom sections accessed by:
-- *   problem_report_get_section();
-- */
--struct problem_report;
--typedef struct problem_report problem_report_t;
--
--/*
-- * Helpers for easily switching between FILE and struct strbuf
-- */
--
--/*
-- * Type of buffer used by Problem report
-- */
--typedef FILE problem_report_buffer;
--
--/*
-- * Wrapper for the proble buffer's formated output function.
-- */
--#define problem_report_buffer_printf(buf, fmt, ...)\
--    fprintf((buf), (fmt), ##__VA_ARGS__)
--
--
--/*
-- * Get a section buffer
-- *
-- * Use this function if you need to amend something to a formatted section.
-- *
-- * @param self Problem report
-- * @param section_name Name of required section
-- * @return Always valid pointer to a section buffer
-- */
--problem_report_buffer *problem_report_get_buffer(const problem_report_t *self,
--        const char *section_name);
--
--/*
-- * Get Summary string
-- *
-- * The returned pointer is valid as long as you perform no further output to
-- * the summary buffer.
-- *
-- * @param self Problem report
-- * @return Non-NULL pointer to summary data
-- */
--const char *problem_report_get_summary(const problem_report_t *self);
--
--/*
-- * Get Description string
-- *
-- * The returned pointer is valid as long as you perform no further output to
-- * the description buffer.
-- *
-- * @param self Problem report
-- * @return Non-NULL pointer to description data
-- */
--const char *problem_report_get_description(const problem_report_t *self);
--
--/*
-- * Get Section's string
-- *
-- * The returned pointer is valid as long as you perform no further output to
-- * the section's buffer.
-- *
-- * @param self Problem report
-- * @param section_name Name of the required section
-- * @return Non-NULL pointer to description data
-- */
--const char *problem_report_get_section(const problem_report_t *self,
--        const char *section_name);
--
--/*
-- * Get GList of the problem data items that are to be attached
-- *
-- * @param self Problem report
-- * @return A pointer to GList (NULL means empty list)
-- */
--GList *problem_report_get_attachments(const problem_report_t *self);
--
--/*
-- * Releases all resources allocated by a problem report
-- *
-- * @param self Problem report
-- */
--void problem_report_free(problem_report_t *self);
--
--
--/*
-- * An enum of Extra section flags
-- */
--enum problem_formatter_section_flags {
--    PFFF_REQUIRED = 1 << 0, ///< section must be present in the format spec
--};
--
--/*
-- * The problem formatter structure formats a problem data according to a format
-- * string and stores result a problem report.
-- *
-- * The problem formatter uses '%reason%' as %summary section format string, if
-- * %summary is not provided by a format string.
-- */
--struct problem_formatter;
--typedef struct problem_formatter problem_formatter_t;
--
--/*
-- * Constructs a new problem formatter.
-- *
-- * @return Non-NULL pointer to the new problem formatter
-- */
--problem_formatter_t *problem_formatter_new(void);
--
--/*
-- * Releases all resources allocated by a problem formatter
-- *
-- * @param self Problem formatter
-- */
--void problem_formatter_free(problem_formatter_t *self);
--
--/*
-- * Adds a new recognized section
-- *
-- * The problem formatter ignores a section in the format spec if the section is
-- * not one of the default nor added by this function.
-- *
-- * How the problem formatter handles these extra sections:
-- *
-- * A custom section is something like %description section. %description is the
-- * default section where all text (sub)sections are stored. If the formatter
-- * finds the custom section in format string, then starts storing text
-- * (sub)sections in the custom section.
-- *
-- * (%description)    |:: comment
-- * (%description)    |
-- * (%description)    |Package:: package
-- * (%description)    |
-- * (%additiona_info) |%additional_info::
-- * (%additiona_info) |%reporter%
-- * (%additiona_info) |User:: user_name,uid
-- * (%additiona_info) |
-- * (%additiona_info) |Directories:: root,cwd
-- *
-- *
-- * @param self Problem formatter
-- * @param name Name of the added section
-- * @param flags Info about the added section
-- * @return Zero on success. -EEXIST if the name is already known by the formatter
-- */
--int problem_formatter_add_section(problem_formatter_t *self, const char *name, int flags);
--
--/*
-- * Loads a problem format from a string.
-- *
-- * @param self Problem formatter
-- * @param fmt Format
-- * @return Zero on success or number of warnings (e.g. missing section,
-- * unrecognized section).
-- */
--int problem_formatter_load_string(problem_formatter_t* self, const char *fmt);
--
--/*
-- * Loads a problem format from a file.
-- *
-- * @param self Problem formatter
-- * @param pat Path to the format file
-- * @return Zero on success or number of warnings (e.g. missing section,
-- * unrecognized section).
-- */
--int problem_formatter_load_file(problem_formatter_t* self, const char *path);
--
--/*
-- * Creates a new problem report, formats the data according to the loaded
-- * format string and stores output in the report.
-- *
-- * @param self Problem formatter
-- * @param data Problem data to format
-- * @param report Pointer where the created problem report is to be stored
-- * @return Zero on success, otherwise non-zero value.
-- */
--int problem_formatter_generate_report(const problem_formatter_t *self, problem_data_t *data, problem_report_t **report);
--
--#ifdef __cplusplus
--}
--#endif
--
--#endif // LIBREPORT_PROBLEM_REPORT_H
-diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
-index d41e543..80a7c4d 100644
---- a/src/lib/Makefile.am
-+++ b/src/lib/Makefile.am
-@@ -38,7 +38,6 @@ libreport_la_SOURCES = \
-     make_descr.c \
-     run_event.c \
-     problem_data.c \
--    problem_report.c \
-     create_dump_dir.c \
-     abrt_types.c \
-     parse_release.c \
-@@ -80,7 +79,6 @@ libreport_la_CPPFLAGS = \
-     $(GLIB_CFLAGS) \
-     $(GOBJECT_CFLAGS) \
-     $(AUGEAS_CFLAGS) \
--    $(SATYR_CFLAGS) \
-     -D_GNU_SOURCE
- libreport_la_LDFLAGS = \
-     -ltar \
-@@ -90,8 +88,7 @@ libreport_la_LIBADD = \
-     $(GLIB_LIBS) \
-     $(JOURNAL_LIBS) \
-     $(GOBJECT_LIBS) \
--    $(AUGEAS_LIBS) \
--    $(SATYR_LIBS)
-+    $(AUGEAS_LIBS)
- 
- libreportconfdir = $(CONF_DIR)
- dist_libreportconf_DATA = \
-@@ -152,8 +149,8 @@ libreport_web_la_LIBADD = \
-     $(PROXY_LIBS) \
-     $(LIBXML_LIBS) \
-     $(JSON_C_LIBS) \
--    $(SATYR_LIBS) \
-     $(XMLRPC_LIBS) $(XMLRPC_CLIENT_LIBS) \
-+    $(SATYR_LIBS) \
-     libreport.la
- 
- DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@
-diff --git a/src/lib/problem_report.c b/src/lib/problem_report.c
-deleted file mode 100644
-index 2bf5530..0000000
---- a/src/lib/problem_report.c
-+++ /dev/null
-@@ -1,1210 +0,0 @@
--/*
--    Copyright (C) 2014  ABRT team
--    Copyright (C) 2014  RedHat Inc
--
--    This program is free software; you can redistribute it and/or modify
--    it under the terms of the GNU General Public License as published by
--    the Free Software Foundation; either version 2 of the License, or
--    (at your option) any later version.
--
--    This program is distributed in the hope that it will be useful,
--    but WITHOUT ANY WARRANTY; without even the implied warranty of
--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--    GNU General Public License for more details.
--
--    You should have received a copy of the GNU General Public License along
--    with this program; if not, write to the Free Software Foundation, Inc.,
--    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
--*/
--
--#include "problem_report.h"
--#include "internal_libreport.h"
--
--#include <satyr/stacktrace.h>
--#include <satyr/abrt.h>
--
--#include <assert.h>
--
--#define DESTROYED_POINTER (void *)0xdeadbeef
--
--/* FORMAT:
-- * |%summary:: Hello, world
-- * |Problem description:: %bare_comment
-- * |
-- * |Package:: package
-- * |
-- * |%attach: %binary, backtrace
-- * |
-- * |%additional_info::
-- * |%reporter%
-- * |User:: user_name,uid
-- * |
-- * |Directories:: root,cwd
-- *
-- * PARSED DATA (list of struct section_t):
-- * {
-- *   section_t {
-- *      .name     = '%summary';
-- *      .items    = { 'Hello, world' };
-- *      .children = NULL;
-- *   },
-- *   section_t {
-- *      .name     = '%attach'
-- *      .items    = { '%binary', 'backtrace' };
-- *      .children = NULL;
-- *   },
-- *   section_t {
-- *      .name     = '%description'
-- *      .items    = NULL;
-- *      .children = {
-- *        section_t {
-- *          .name     = 'Problem description:';
-- *          .items    = { '%bare_comment' };
-- *          .children = NULL;
-- *        },
-- *        section_t {
-- *          .name     = '';
-- *          .items    = NULL;
-- *          .children = NULL;
-- *        },
-- *        section_t {
-- *          .name     = 'Package:';
-- *          .items    = { 'package' };
-- *          .children = NULL;
-- *        },
-- *      }
-- *   },
-- *   section_t {
-- *      .name     = '%additional_info'
-- *      .items    = { '%reporter%' };
-- *      .children = {
-- *        section_t {
-- *          .name     = 'User:';
-- *          .items    = { 'user_name', 'uid' };
-- *          .children = NULL;
-- *        },
-- *        section_t {
-- *          .name     = '';
-- *          .items    = NULL;
-- *          .children = NULL;
-- *        },
-- *        section_t {
-- *          .name     = 'Directories:';
-- *          .items    = { 'root', 'cwd' };
-- *          .children = NULL;
-- *        },
-- *      }
-- *   }
-- * }
-- */
--struct section_t {
--    char *name;      ///< name or output text (%summar, 'Package version:');
--    GList *items;    ///< list of file names and special items (%reporter, %binar, ...)
--    GList *children; ///< list of sub sections (struct section_t)
--};
--
--typedef struct section_t section_t;
--
--static section_t *
--section_new(const char *name)
--{
--    section_t *self = xmalloc(sizeof(*self));
--    self->name = xstrdup(name);
--    self->items = NULL;
--    self->children = NULL;
--
--    return self;
--}
--
--static void
--section_free(section_t *self)
--{
--    if (self == NULL)
--        return;
--
--    free(self->name);
--    g_list_free_full(self->items, free);
--    g_list_free_full(self->children, (GDestroyNotify)section_free);
--
--    free(self);
--}
--
--static int
--section_name_cmp(section_t *lhs, const char *rhs)
--{
--    return strcmp((lhs->name + 1), rhs);
--}
--
--/* Utility functions */
--
--static GList*
--split_string_on_char(const char *str, char ch)
--{
--    GList *list = NULL;
--    for (;;)
--    {
--        const char *delim = strchrnul(str, ch);
--        list = g_list_prepend(list, xstrndup(str, delim - str));
--        if (*delim == '\0')
--            break;
--        str = delim + 1;
--    }
--    return g_list_reverse(list);
--}
--
--static int
--compare_item_name(const char *lookup, const char *name)
--{
--    if (lookup[0] == '-')
--        lookup++;
--    else if (strncmp(lookup, "%bare_", 6) == 0)
--        lookup += 6;
--    return strcmp(lookup, name);
--}
--
--static int
--is_item_name_in_section(const section_t *lookup, const char *name)
--{
--    if (g_list_find_custom(lookup->items, name, (GCompareFunc)compare_item_name))
--        return 0; /* "found it!" */
--    return 1;
--}
--
--static bool is_explicit_or_forbidden(const char *name, GList *comment_fmt_spec);
--
--static int
--is_explicit_or_forbidden_child(const section_t *master_section, const char *name)
--{
--    if (is_explicit_or_forbidden(name, master_section->children))
--        return 0; /* "found it!" */
--    return 1;
--}
--
--/* For example: 'package' belongs to '%oneline', but 'package' is used in
-- * 'Version of component', so it is not very helpful to include that file once
-- * more in another section
-- */
--static bool
--is_explicit_or_forbidden(const char *name, GList *comment_fmt_spec)
--{
--    return    g_list_find_custom(comment_fmt_spec, name, (GCompareFunc)is_item_name_in_section)
--           || g_list_find_custom(comment_fmt_spec, name, (GCompareFunc)is_explicit_or_forbidden_child);
--}
--
--static GList*
--load_stream(FILE *fp)
--{
--    assert(fp);
--
--    GList *sections = NULL;
--    section_t *master = section_new("%description");
--    section_t *sec = NULL;
--
--    sections = g_list_append(sections, master);
--
--    char *line;
--    while ((line = xmalloc_fgetline(fp)) != NULL)
--    {
--        /* Skip comments */
--        char first = *skip_whitespace(line);
--        if (first == '#')
--            goto free_line;
--
--        /* Handle trailing backslash continuation */
-- check_continuation: ;
--        unsigned len = strlen(line);
--        if (len && line[len-1] == '\\')
--        {
--            line[len-1] = '\0';
--            char *next_line = xmalloc_fgetline(fp);
--            if (next_line)
--            {
--                line = append_to_malloced_string(line, next_line);
--                free(next_line);
--                goto check_continuation;
--            }
--        }
--
--        /* We are reusing line buffer to form temporary
--         * "key\0values\0..." in its beginning
--         */
--        bool summary_line = false;
--        char *value = NULL;
--        char *src;
--        char *dst;
--        for (src = dst = line; *src; src++)
--        {
--            char c = *src;
--            /* did we reach the value list? */
--            if (!value && c == ':' && src[1] == ':')
--            {
--                *dst++ = '\0'; /* terminate key */
--                src += 1;
--                value = dst; /* remember where value starts */
--                summary_line = (strcmp(line, "%summary") == 0);
--                if (summary_line)
--                {
--                    value = (src + 1);
--                    break;
--                }
--                continue;
--            }
--            /* skip whitespace in value list */
--            if (value && isspace(c))
--                continue;
--            *dst++ = c; /* store next key or value char */
--        }
--
--        GList *item_list = NULL;
--        if (summary_line)
--        {
--            /* %summary is special */
--            item_list = g_list_append(NULL, xstrdup(skip_whitespace(value)));
--        }
--        else
--        {
--            *dst = '\0'; /* terminate value (or key) */
--            if (value)
--                item_list = split_string_on_char(value, ',');
--        }
--
--        sec = section_new(line);
--        sec->items = item_list;
--
--        if (sec->name[0] == '%')
--        {
--            if (!summary_line && strcmp(sec->name, "%attach") != 0)
--            {
--                master->children = g_list_reverse(master->children);
--                master = sec;
--            }
--
--            sections = g_list_prepend(sections, sec);
--        }
--        else
--            master->children = g_list_prepend(master->children, sec);
--
-- free_line:
--        free(line);
--    }
--
--    /* If master equals sec, then master's children list was not yet reversed.
--     *
--     * %description is the default section (i.e is not explicitly mentioned)
--     * and %summary nor %attach cause its children list to reverse.
--     */
--    if (master == sec || strcmp(master->name, "%description") == 0)
--        master->children = g_list_reverse(master->children);
--
--    return sections;
--}
--
--
--/* Summary generation */
--
--#define MAX_OPT_DEPTH 10
--static int
--format_percented_string(const char *str, problem_data_t *pd, FILE *result)
--{
--    long old_pos[MAX_OPT_DEPTH] = { 0 };
--    int okay[MAX_OPT_DEPTH] = { 1 };
--    long len = 0;
--    int opt_depth = 1;
--
--    while (*str) {
--        switch (*str) {
--        default:
--            putc(*str, result);
--            len++;
--            str++;
--            break;
--        case '\\':
--            if (str[1])
--                str++;
--            putc(*str, result);
--            len++;
--            str++;
--            break;
--        case '[':
--            if (str[1] == '[' && opt_depth < MAX_OPT_DEPTH)
--            {
--                old_pos[opt_depth] = len;
--                okay[opt_depth] = 1;
--                opt_depth++;
--                str += 2;
--            } else {
--                putc(*str, result);
--                len++;
--                str++;
--            }
--            break;
--        case ']':
--            if (str[1] == ']' && opt_depth > 1)
--            {
--                opt_depth--;
--                if (!okay[opt_depth])
--                {
--                    if (fseek(result, old_pos[opt_depth], SEEK_SET) < 0)
--                        perror_msg_and_die("fseek");
--                    len = old_pos[opt_depth];
--                }
--                str += 2;
--            } else {
--                putc(*str, result);
--                len++;
--                str++;
--            }
--            break;
--        case '%': ;
--            char *nextpercent = strchr(++str, '%');
--            if (!nextpercent)
--            {
--                error_msg_and_die("Unterminated %%element%%: '%s'", str - 1);
--            }
--
--            *nextpercent = '\0';
--            const problem_item *item = problem_data_get_item_or_NULL(pd, str);
--            *nextpercent = '%';
--
--            if (item && (item->flags & CD_FLAG_TXT))
--            {
--                fputs(item->content, result);
--                len += strlen(item->content);
--            }
--            else
--                okay[opt_depth - 1] = 0;
--            str = nextpercent + 1;
--            break;
--        }
--    }
--
--    if (opt_depth > 1)
--    {
--        error_msg_and_die("Unbalanced [[ ]] bracket");
--    }
--
--    if (!okay[0])
--    {
--        error_msg("Undefined variable outside of [[ ]] bracket");
--    }
--
--    return 0;
--}
--
--/* BZ comment generation */
--
--static int
--append_text(struct strbuf *result, const char *item_name, const char *content, bool print_item_name)
--{
--    char *eol = strchrnul(content, '\n');
--    if (eol[0] == '\0' || eol[1] == '\0')
--    {
--        /* one-liner */
--        int pad = 16 - (strlen(item_name) + 2);
--        if (pad < 0)
--            pad = 0;
--        if (print_item_name)
--            strbuf_append_strf(result,
--                    eol[0] == '\0' ? "%s: %*s%s\n" : "%s: %*s%s",
--                    item_name, pad, "", content
--            );
--        else
--            strbuf_append_strf(result,
--                    eol[0] == '\0' ? "%s\n" : "%s",
--                    content
--            );
--    }
--    else
--    {
--        /* multi-line item */
--        if (print_item_name)
--            strbuf_append_strf(result, "%s:\n", item_name);
--        for (;;)
--        {
--            eol = strchrnul(content, '\n');
--            strbuf_append_strf(result,
--                    /* For %bare_multiline_item, we don't want to print colons */
--                    (print_item_name ? ":%.*s\n" : "%.*s\n"),
--                    (int)(eol - content), content
--            );
--            if (eol[0] == '\0' || eol[1] == '\0')
--                break;
--            content = eol + 1;
--        }
--    }
--    return 1;
--}
--
--static int
--append_short_backtrace(struct strbuf *result, problem_data_t *problem_data, size_t max_text_size, bool print_item_name)
--{
--    const problem_item *item = problem_data_get_item_or_NULL(problem_data,
--                                                             FILENAME_BACKTRACE);
--    if (!item)
--        return 0; /* "I did not print anything" */
--    if (!(item->flags & CD_FLAG_TXT))
--        return 0; /* "I did not print anything" */
--
--    char *truncated = NULL;
--
--    if (strlen(item->content) >= max_text_size)
--    {
--        log_debug("'backtrace' exceeds the text file size, going to append its short version");
--
--        char *error_msg = NULL;
--        const char *type = problem_data_get_content_or_NULL(problem_data, FILENAME_TYPE);
--        if (!type)
--        {
--            log_debug("Problem data does not contain '"FILENAME_TYPE"' file");
--            return 0;
--        }
--
--        /* For CCpp crashes, use the GDB-produced backtrace which should be
--         * available by now. sr_abrt_type_from_analyzer returns SR_REPORT_CORE
--         * by default for CCpp crashes.
--         */
--        enum sr_report_type report_type = sr_abrt_type_from_analyzer(type);
--        if (strcmp(type, "CCpp") == 0)
--        {
--            log_debug("Successfully identified 'CCpp' abrt type");
--            report_type = SR_REPORT_GDB;
--        }
--
--        struct sr_stacktrace *backtrace = sr_stacktrace_parse(report_type,
--                item->content, &error_msg);
--
--        if (!backtrace)
--        {
--            log(_("Can't parse backtrace: %s"), error_msg);
--            free(error_msg);
--            return 0;
--        }
--
--        /* Get optimized thread stack trace for 10 top most frames */
--        truncated = sr_stacktrace_to_short_text(backtrace, 10);
--        sr_stacktrace_free(backtrace);
--
--        if (!truncated)
--        {
--            log(_("Can't generate stacktrace description (no crash thread?)"));
--            return 0;
--        }
--    }
--    else
--    {
--        log_debug("'backtrace' is small enough to be included as is");
--    }
--
--    append_text(result,
--                /*item_name:*/ truncated ? "truncated_backtrace" : FILENAME_BACKTRACE,
--                /*content:*/   truncated ? truncated             : item->content,
--                print_item_name
--    );
--    free(truncated);
--    return 1;
--}
--
--static int
--append_item(struct strbuf *result, const char *item_name, problem_data_t *pd, GList *comment_fmt_spec)
--{
--    bool print_item_name = (strncmp(item_name, "%bare_", strlen("%bare_")) != 0);
--    if (!print_item_name)
--        item_name += strlen("%bare_");
--
--    if (item_name[0] != '%')
--    {
--        struct problem_item *item = problem_data_get_item_or_NULL(pd, item_name);
--        if (!item)
--            return 0; /* "I did not print anything" */
--        if (!(item->flags & CD_FLAG_TXT))
--            return 0; /* "I did not print anything" */
--
--        char *formatted = problem_item_format(item);
--        char *content = formatted ? formatted : item->content;
--        append_text(result, item_name, content, print_item_name);
--        free(formatted);
--        return 1; /* "I printed something" */
--    }
--
--    /* Special item name */
--
--    /* Compat with previously-existed ad-hockery: %short_backtrace */
--    if (strcmp(item_name, "%short_backtrace") == 0)
--        return append_short_backtrace(result, pd, CD_TEXT_ATT_SIZE_BZ, print_item_name);
--
--    /* Compat with previously-existed ad-hockery: %reporter */
--    if (strcmp(item_name, "%reporter") == 0)
--        return append_text(result, "reporter", PACKAGE"-"VERSION, print_item_name);
--
--    /* %oneline,%multiline,%text */
--    bool oneline   = (strcmp(item_name+1, "oneline"  ) == 0);
--    bool multiline = (strcmp(item_name+1, "multiline") == 0);
--    bool text      = (strcmp(item_name+1, "text"     ) == 0);
--    if (!oneline && !multiline && !text)
--    {
--        log("Unknown or unsupported element specifier '%s'", item_name);
--        return 0; /* "I did not print anything" */
--    }
--
--    int printed = 0;
--
--    /* Iterate over _sorted_ items */
--    GList *sorted_names = g_hash_table_get_keys(pd);
--    sorted_names = g_list_sort(sorted_names, (GCompareFunc)strcmp);
--
--    /* %text => do as if %oneline, then repeat as if %multiline */
--    if (text)
--        oneline = 1;
--
-- again: ;
--    GList *l = sorted_names;
--    while (l)
--    {
--        const char *name = l->data;
--        l = l->next;
--        struct problem_item *item = g_hash_table_lookup(pd, name);
--        if (!item)
--            continue; /* paranoia, won't happen */
--
--        if (!(item->flags & CD_FLAG_TXT))
--            continue;
--
--        if (is_explicit_or_forbidden(name, comment_fmt_spec))
--            continue;
--
--        char *formatted = problem_item_format(item);
--        char *content = formatted ? formatted : item->content;
--        char *eol = strchrnul(content, '\n');
--        bool is_oneline = (eol[0] == '\0' || eol[1] == '\0');
--        if (oneline == is_oneline)
--            printed |= append_text(result, name, content, print_item_name);
--        free(formatted);
--    }
--    if (text && oneline)
--    {
--        /* %text, and we just did %oneline. Repeat as if %multiline */
--        oneline = 0;
--        /*multiline = 1; - not checked in fact, so why bother setting? */
--        goto again;
--    }
--
--    g_list_free(sorted_names); /* names themselves are not freed */
--
--    return printed;
--}
--
--#define add_to_section_output(format, ...) \
--    do { \
--    for (; empty_lines > 0; --empty_lines) fputc('\n', result); \
--    empty_lines = 0; \
--    fprintf(result, format, __VA_ARGS__); \
--    } while (0)
--
--static void
--format_section(section_t *section, problem_data_t *pd, GList *comment_fmt_spec, FILE *result)
--{
--    int empty_lines = -1;
--
--    for (GList *iter = section->children; iter; iter = g_list_next(iter))
--    {
--        section_t *child = (section_t *)iter->data;
--        if (child->items)
--        {
--            /* "Text: item[,item]..." */
--            struct strbuf *output = strbuf_new();
--            GList *item = child->items;
--            while (item)
--            {
--                const char *str = item->data;
--                item = item->next;
--                if (str[0] == '-') /* "-name", ignore it */
--                    continue;
--                append_item(output, str, pd, comment_fmt_spec);
--            }
--
--            if (output->len != 0)
--                add_to_section_output((child->name[0] ? "%s:\n%s" : "%s%s"),
--                                      child->name, output->buf);
--
--            strbuf_free(output);
--        }
--        else
--        {
--            /* Just "Text" (can be "") */
--
--            /* Filter out trailint empty lines */
--            if (child->name[0] != '\0')
--                add_to_section_output("%s\n", child->name);
--            /* Do not count empty lines, if output wasn't yet produced */
--            else if (empty_lines >= 0)
--                ++empty_lines;
--        }
--    }
--}
--
--static GList *
--get_special_items(const char *item_name, problem_data_t *pd, GList *comment_fmt_spec)
--{
--    /* %oneline,%multiline,%text,%binary */
--    bool oneline   = (strcmp(item_name+1, "oneline"  ) == 0);
--    bool multiline = (strcmp(item_name+1, "multiline") == 0);
--    bool text      = (strcmp(item_name+1, "text"     ) == 0);
--    bool binary    = (strcmp(item_name+1, "binary"   ) == 0);
--    if (!oneline && !multiline && !text && !binary)
--    {
--        log("Unknown or unsupported element specifier '%s'", item_name);
--        return NULL;
--    }
--
--    log_debug("Special item_name '%s', iterating for attach...", item_name);
--    GList *result = 0;
--
--    /* Iterate over _sorted_ items */
--    GList *sorted_names = g_hash_table_get_keys(pd);
--    sorted_names = g_list_sort(sorted_names, (GCompareFunc)strcmp);
--
--    GList *l = sorted_names;
--    while (l)
--    {
--        const char *name = l->data;
--        l = l->next;
--        struct problem_item *item = g_hash_table_lookup(pd, name);
--        if (!item)
--            continue; /* paranoia, won't happen */
--
--        if (is_explicit_or_forbidden(name, comment_fmt_spec))
--            continue;
--
--        if ((item->flags & CD_FLAG_TXT) && !binary)
--        {
--            char *content = item->content;
--            char *eol = strchrnul(content, '\n');
--            bool is_oneline = (eol[0] == '\0' || eol[1] == '\0');
--            if (text || oneline == is_oneline)
--                result = g_list_append(result, xstrdup(name));
--        }
--        else if ((item->flags & CD_FLAG_BIN) && binary)
--            result = g_list_append(result, xstrdup(name));
--    }
--
--    g_list_free(sorted_names); /* names themselves are not freed */
--
--
--    log_debug("...Done iterating over '%s' for attach", item_name);
--
--    return result;
--}
--
--static GList *
--get_attached_files(problem_data_t *pd, GList *items, GList *comment_fmt_spec)
--{
--    GList *result = NULL;
--    GList *item = items;
--    while (item != NULL)
--    {
--        const char *item_name = item->data;
--        item = item->next;
--        if (item_name[0] == '-') /* "-name", ignore it */
--            continue;
--
--        if (item_name[0] != '%')
--        {
--            result = g_list_append(result, xstrdup(item_name));
--            continue;
--        }
--
--        GList *special = get_special_items(item_name, pd, comment_fmt_spec);
--        if (special == NULL)
--        {
--            log_notice("No attachment found for '%s'", item_name);
--            continue;
--        }
--
--        result = g_list_concat(result, special);
--    }
--
--    return result;
--}
--
--/*
-- * Problem Report - memor stream
-- *
-- * A wrapper for POSIX memory stream.
-- *
-- * A memory stream is presented as FILE *.
-- *
-- * A memory stream is associated with a pointer to written data and a pointer
-- * to size of the written data.
-- *
-- * This structure holds all of the used pointers.
-- */
--struct memstream_buffer
--{
--    char *msb_buffer;
--    size_t msb_size;
--    FILE *msb_stream;
--};
--
--static struct memstream_buffer *
--memstream_buffer_new()
--{
--    struct memstream_buffer *self = xmalloc(sizeof(*self));
--
--    self->msb_buffer = NULL;
--    self->msb_stream = open_memstream(&(self->msb_buffer), &(self->msb_size));
--
--    return self;
--}
--
--static void
--memstream_buffer_free(struct memstream_buffer *self)
--{
--    if (self == NULL)
--        return;
--
--    fclose(self->msb_stream);
--    self->msb_stream = DESTROYED_POINTER;
--
--    free(self->msb_buffer);
--    self->msb_buffer = DESTROYED_POINTER;
--
--    free(self);
--}
--
--static FILE *
--memstream_get_stream(struct memstream_buffer *self)
--{
--    assert(self != NULL);
--
--    return self->msb_stream;
--}
--
--static const char *
--memstream_get_string(struct memstream_buffer *self)
--{
--    assert(self != NULL);
--    assert(self->msb_stream != NULL);
--
--    fflush(self->msb_stream);
--
--    return self->msb_buffer;
--}
--
--
--/*
-- * Problem Report
-- *
-- * The formated strings are internaly stored in "buffer"s. If a programer wants
-- * to get a formated section data, a getter function extracts those data from
-- * the apropriate buffer and returns them in form of null-terminated string.
-- *
-- * Each section has own buffer.
-- *
-- * There are three common sections that are always present:
-- * 1. summary
-- * 2. description
-- * 3. attach
-- * Buffers of these sections has own structure member for the sake of
-- * efficiency.
-- *
-- * The custom sections hash their buffers stored in a map where key is a
-- * section's name and value is a section's buffer.
-- *
-- * Problem report provides the programers with the possibility to ammend
-- * formated output to any section buffer.
-- */
--struct problem_report
--{
--    struct memstream_buffer *pr_sec_summ; ///< %summary buffer
--    struct memstream_buffer *pr_sec_desc; ///< %description buffer
--    GList            *pr_attachments;     ///< %attach - list of file names
--    GHashTable       *pr_sec_custom;      ///< map : %(custom section) -> buffer
--};
--
--static problem_report_t *
--problem_report_new()
--{
--    problem_report_t *self = xmalloc(sizeof(*self));
--
--    self->pr_sec_summ = memstream_buffer_new();
--    self->pr_sec_desc = memstream_buffer_new();
--    self->pr_attachments = NULL;
--    self->pr_sec_custom = NULL;
--
--    return self;
--}
--
--static void
--problem_report_initialize_custom_sections(problem_report_t *self)
--{
--    assert(self != NULL);
--    assert(self->pr_sec_custom == NULL);
--
--    self->pr_sec_custom = g_hash_table_new_full(g_str_hash, g_str_equal, free,
--                                                (GDestroyNotify)memstream_buffer_free);
--}
--
--static void
--problem_report_destroy_custom_sections(problem_report_t *self)
--{
--    assert(self != NULL);
--    assert(self->pr_sec_custom != NULL);
--
--    g_hash_table_destroy(self->pr_sec_custom);
--}
--
--static int
--problem_report_add_custom_section(problem_report_t *self, const char *name)
--{
--    assert(self != NULL);
--
--    if (self->pr_sec_custom == NULL)
--    {
--        problem_report_initialize_custom_sections(self);
--    }
--
--    if (problem_report_get_buffer(self, name))
--    {
--        log_warning("Custom section already exists : '%s'", name);
--        return -EEXIST;
--    }
--
--    log_debug("Problem report enriched with section : '%s'", name);
--    g_hash_table_insert(self->pr_sec_custom, xstrdup(name), memstream_buffer_new());
--    return 0;
--}
--
--static struct memstream_buffer *
--problem_report_get_section_buffer(const problem_report_t *self, const char *section_name)
--{
--    if (self->pr_sec_custom == NULL)
--    {
--        log_debug("Couldn't find section '%s': no custom section added", section_name);
--        return NULL;
--    }
--
--    return (struct memstream_buffer *)g_hash_table_lookup(self->pr_sec_custom, section_name);
--}
--
--problem_report_buffer *
--problem_report_get_buffer(const problem_report_t *self, const char *section_name)
--{
--    assert(self != NULL);
--    assert(section_name != NULL);
--
--    if (strcmp(PR_SEC_SUMMARY, section_name) == 0)
--        return memstream_get_stream(self->pr_sec_summ);
--
--    if (strcmp(PR_SEC_DESCRIPTION, section_name) == 0)
--        return memstream_get_stream(self->pr_sec_desc);
--
--    struct memstream_buffer *buf = problem_report_get_section_buffer(self, section_name);
--    return buf == NULL ? NULL : memstream_get_stream(buf);
--}
--
--const char *
--problem_report_get_summary(const problem_report_t *self)
--{
--    assert(self != NULL);
--
--    return memstream_get_string(self->pr_sec_summ);
--}
--
--const char *
--problem_report_get_description(const problem_report_t *self)
--{
--    assert(self != NULL);
--
--    return memstream_get_string(self->pr_sec_desc);
--}
--
--const char *
--problem_report_get_section(const problem_report_t *self, const char *section_name)
--{
--    assert(self != NULL);
--    assert(section_name);
--
--    struct memstream_buffer *buf = problem_report_get_section_buffer(self, section_name);
--
--    if (buf == NULL)
--        return NULL;
--
--    return memstream_get_string(buf);
--}
--
--static void
--problem_report_set_attachments(problem_report_t *self, GList *attachments)
--{
--    assert(self != NULL);
--    assert(self->pr_attachments == NULL);
--
--    self->pr_attachments = attachments;
--}
--
--GList *
--problem_report_get_attachments(const problem_report_t *self)
--{
--    assert(self != NULL);
--
--    return self->pr_attachments;
--}
--
--void
--problem_report_free(problem_report_t *self)
--{
--    if (self == NULL)
--        return;
--
--    memstream_buffer_free(self->pr_sec_summ);
--    self->pr_sec_summ = DESTROYED_POINTER;
--
--    memstream_buffer_free(self->pr_sec_desc);
--    self->pr_sec_desc = DESTROYED_POINTER;
--
--    g_list_free_full(self->pr_attachments, free);
--    self->pr_attachments = DESTROYED_POINTER;
--
--    if (self->pr_sec_custom)
--    {
--        problem_report_destroy_custom_sections(self);
--        self->pr_sec_custom = DESTROYED_POINTER;
--    }
--
--    free(self);
--}
--
--/*
-- * Problem Formatter - extra section
-- */
--struct extra_section
--{
--    char *pfes_name;    ///< name with % prefix
--    int   pfes_flags;   ///< whether is required or not
--};
--
--static struct extra_section *
--extra_section_new(const char *name, int flags)
--{
--    struct extra_section *self = xmalloc(sizeof(*self));
--
--    self->pfes_name = xstrdup(name);
--    self->pfes_flags = flags;
--
--    return self;
--}
--
--static void
--extra_section_free(struct extra_section *self)
--{
--    if (self == NULL)
--        return;
--
--    free(self->pfes_name);
--    self->pfes_name = DESTROYED_POINTER;
--
--    free(self);
--}
--
--static int
--extra_section_name_cmp(struct extra_section *lhs, const char *rhs)
--{
--    return strcmp(lhs->pfes_name, rhs);
--}
--
--/*
-- * Problem Formatter
-- *
-- * Holds parsed sections lists.
-- */
--struct problem_formatter
--{
--    GList *pf_sections;         ///< parsed sections (struct section_t)
--    GList *pf_extra_sections;   ///< user configured sections (struct extra_section)
--    char  *pf_default_summary;  ///< default summary format
--};
--
--problem_formatter_t *
--problem_formatter_new(void)
--{
--    problem_formatter_t *self = xzalloc(sizeof(*self));
--
--    self->pf_default_summary = xstrdup("%reason%");
--
--    return self;
--}
--
--void
--problem_formatter_free(problem_formatter_t *self)
--{
--    if (self == NULL)
--        return;
--
--    g_list_free_full(self->pf_sections, (GDestroyNotify)section_free);
--    self->pf_sections = DESTROYED_POINTER;
--
--    g_list_free_full(self->pf_extra_sections, (GDestroyNotify)extra_section_free);
--    self->pf_extra_sections = DESTROYED_POINTER;
--
--    free(self->pf_default_summary);
--    self->pf_default_summary = DESTROYED_POINTER;
--
--    free(self);
--}
--
--static int
--problem_formatter_is_section_known(problem_formatter_t *self, const char *name)
--{
--  return    strcmp(name, "summary")     == 0
--         || strcmp(name, "attach")      == 0
--         || strcmp(name, "description") == 0
--         || NULL != g_list_find_custom(self->pf_extra_sections, name, (GCompareFunc)extra_section_name_cmp);
--}
--
--// i.e additional_info -> no flags
--int
--problem_formatter_add_section(problem_formatter_t *self, const char *name, int flags)
--{
--    /* Do not add already added sections */
--    if (problem_formatter_is_section_known(self, name))
--    {
--        log_debug("Extra section already exists : '%s' ", name);
--        return -EEXIST;
--    }
--
--    self->pf_extra_sections = g_list_prepend(self->pf_extra_sections,
--                                             extra_section_new(name, flags));
--
--    return 0;
--}
--
--// check format validity and produce warnings
--static int
--problem_formatter_validate(problem_formatter_t *self)
--{
--    int retval = 0;
--
--    /* Go through all (struct extra_section)s and check whete those having flag
--     * PFFF_REQUIRED are present in the parsed (struct section_t)s.
--     */
--    for (GList *iter = self->pf_extra_sections; iter; iter = g_list_next(iter))
--    {
--        struct extra_section *section = (struct extra_section *)iter->data;
--
--        log_debug("Validating extra section : '%s'", section->pfes_name);
--
--        if (   (PFFF_REQUIRED & section->pfes_flags)
--            && NULL == g_list_find_custom(self->pf_sections, section->pfes_name, (GCompareFunc)section_name_cmp))
--        {
--            log_warning("Problem format misses required section : '%s'", section->pfes_name);
--            ++retval;
--        }
--    }
--
--    /* Go through all the parsed (struct section_t)s check whether are all
--     * known, i.e. each section is either one of the common sections (summary,
--     * description, attach) or is present in the (struct extra_section)s.
--     */
--    for (GList *iter = self->pf_sections; iter; iter = g_list_next(iter))
--    {
--        section_t *section = (section_t *)iter->data;
--
--        if (!problem_formatter_is_section_known(self, (section->name + 1)))
--        {
--            log_warning("Problem format contains unrecognized section : '%s'", section->name);
--            ++retval;
--        }
--    }
--
--    return retval;
--}
--
--int
--problem_formatter_load_string(problem_formatter_t *self, const char *fmt)
--{
--    const size_t len = strlen(fmt);
--    if (len != 0)
--    {
--        FILE *fp = fmemopen((void *)fmt, len, "r");
--        if (fp == NULL)
--        {
--            error_msg("Not enough memory to open a stream for reading format string.");
--            return -ENOMEM;
--        }
--
--        self->pf_sections = load_stream(fp);
--        fclose(fp);
--    }
--
--    return problem_formatter_validate(self);
--}
--
--int
--problem_formatter_load_file(problem_formatter_t *self, const char *path)
--{
--    FILE *fp = stdin;
--    if (strcmp(path, "-") != 0)
--    {
--        fp = fopen(path, "r");
--        if (!fp)
--            return -ENOENT;
--    }
--
--    self->pf_sections = load_stream(fp);
--
--    if (fp != stdin)
--        fclose(fp);
--
--    return problem_formatter_validate(self);
--}
--
--// generates report
--int
--problem_formatter_generate_report(const problem_formatter_t *self, problem_data_t *data, problem_report_t **report)
--{
--    problem_report_t *pr = problem_report_new();
--
--    for (GList *iter = self->pf_extra_sections; iter; iter = g_list_next(iter))
--        problem_report_add_custom_section(pr, ((struct extra_section *)iter->data)->pfes_name);
--
--    bool has_summary = false;
--    for (GList *iter = self->pf_sections; iter; iter = g_list_next(iter))
--    {
--        section_t *section = (section_t *)iter->data;
--
--        /* %summary is something special */
--        if (strcmp(section->name, "%summary") == 0)
--        {
--            has_summary = true;
--            format_percented_string((const char *)section->items->data, data,
--                                    problem_report_get_buffer(pr, PR_SEC_SUMMARY));
--        }
--        /* %attach as well */
--        else if (strcmp(section->name, "%attach") == 0)
--        {
--            problem_report_set_attachments(pr, get_attached_files(data, section->items, self->pf_sections));
--        }
--        else /* %description or a custom section (e.g. %additional_info) */
--        {
--            FILE *buffer = problem_report_get_buffer(pr, section->name + 1);
--
--            if (buffer != NULL)
--            {
--                log_debug("Formatting section : '%s'", section->name);
--                format_section(section, data, self->pf_sections, buffer);
--            }
--            else
--                log_warning("Unsupported section '%s'", section->name);
--        }
--    }
--
--    if (!has_summary) {
--        log_debug("Problem format misses section '%%summary'. Using the default one : '%s'.",
--                    self->pf_default_summary);
--
--        format_percented_string(self->pf_default_summary,
--                   data, problem_report_get_buffer(pr, PR_SEC_SUMMARY));
--    }
--
--    *report = pr;
--    return 0;
--}
-diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
-index 27194a4..f4f94ff 100644
---- a/src/plugins/Makefile.am
-+++ b/src/plugins/Makefile.am
-@@ -125,6 +125,17 @@ EXTRA_DIST = $(reporters_extra_dist) \
- $(DESTDIR)/$(DEBUG_INFO_DIR):
- 	$(mkdir_p) '$@'
- 
-+noinst_LIBRARIES = libreport-problem-report.a
-+libreport_problem_report_a_SOURCES = \
-+    problem_report.c \
-+    problem_report.h
-+libreport_problem_report_a_CFLAGS = \
-+    -I$(srcdir)/../include \
-+    $(LIBREPORT_CFLAGS) \
-+    $(GLIB_CFLAGS) \
-+    $(SATYR_CFLAGS) \
-+    -D_GNU_SOURCE
-+
- if BUILD_BUGZILLA
- reporter_bugzilla_SOURCES = \
-     reporter-bugzilla.c rhbz.c rhbz.h
-@@ -146,7 +157,8 @@ reporter_bugzilla_LDADD = \
-     $(GLIB_LIBS) \
-     $(XMLRPC_LIBS) $(XMLRPC_CLIENT_LIBS) \
-     ../lib/libreport-web.la \
--    ../lib/libreport.la
-+    ../lib/libreport.la \
-+    libreport-problem-report.a
- endif
- 
- if BUILD_MANTISBT
-@@ -169,7 +181,8 @@ reporter_mantisbt_CPPFLAGS = \
- reporter_mantisbt_LDADD = \
-     $(GLIB_LIBS) \
-     ../lib/libreport-web.la \
--    ../lib/libreport.la
-+    ../lib/libreport.la \
-+    libreport-problem-report.a
- endif
- 
- reporter_rhtsupport_SOURCES = \
-@@ -196,7 +209,8 @@ reporter_rhtsupport_LDADD = \
-     $(GLIB_LIBS) \
-     $(LIBXML_LIBS) \
-     ../lib/libreport-web.la \
--    ../lib/libreport.la
-+    ../lib/libreport.la \
-+    libreport-problem-report.a
- 
- reporter_upload_SOURCES = \
-     reporter-upload.c
-@@ -255,7 +269,9 @@ reporter_mailx_CPPFLAGS = \
-     $(LIBREPORT_CFLAGS) \
-     -D_GNU_SOURCE
- reporter_mailx_LDADD = \
--    ../lib/libreport.la
-+    ../lib/libreport.la \
-+    $(SATYR_LIBS) \
-+    libreport-problem-report.a
- 
- reporter_print_SOURCES = \
-     reporter-print.c
-diff --git a/src/plugins/problem_report.c b/src/plugins/problem_report.c
-new file mode 100644
-index 0000000..2bf5530
---- /dev/null
-+++ b/src/plugins/problem_report.c
-@@ -0,0 +1,1210 @@
-+/*
-+    Copyright (C) 2014  ABRT team
-+    Copyright (C) 2014  RedHat Inc
-+
-+    This program is free software; you can redistribute it and/or modify
-+    it under the terms of the GNU General Public License as published by
-+    the Free Software Foundation; either version 2 of the License, or
-+    (at your option) any later version.
-+
-+    This program is distributed in the hope that it will be useful,
-+    but WITHOUT ANY WARRANTY; without even the implied warranty of
-+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+    GNU General Public License for more details.
-+
-+    You should have received a copy of the GNU General Public License along
-+    with this program; if not, write to the Free Software Foundation, Inc.,
-+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-+*/
-+
-+#include "problem_report.h"
-+#include "internal_libreport.h"
-+
-+#include <satyr/stacktrace.h>
-+#include <satyr/abrt.h>
-+
-+#include <assert.h>
-+
-+#define DESTROYED_POINTER (void *)0xdeadbeef
-+
-+/* FORMAT:
-+ * |%summary:: Hello, world
-+ * |Problem description:: %bare_comment
-+ * |
-+ * |Package:: package
-+ * |
-+ * |%attach: %binary, backtrace
-+ * |
-+ * |%additional_info::
-+ * |%reporter%
-+ * |User:: user_name,uid
-+ * |
-+ * |Directories:: root,cwd
-+ *
-+ * PARSED DATA (list of struct section_t):
-+ * {
-+ *   section_t {
-+ *      .name     = '%summary';
-+ *      .items    = { 'Hello, world' };
-+ *      .children = NULL;
-+ *   },
-+ *   section_t {
-+ *      .name     = '%attach'
-+ *      .items    = { '%binary', 'backtrace' };
-+ *      .children = NULL;
-+ *   },
-+ *   section_t {
-+ *      .name     = '%description'
-+ *      .items    = NULL;
-+ *      .children = {
-+ *        section_t {
-+ *          .name     = 'Problem description:';
-+ *          .items    = { '%bare_comment' };
-+ *          .children = NULL;
-+ *        },
-+ *        section_t {
-+ *          .name     = '';
-+ *          .items    = NULL;
-+ *          .children = NULL;
-+ *        },
-+ *        section_t {
-+ *          .name     = 'Package:';
-+ *          .items    = { 'package' };
-+ *          .children = NULL;
-+ *        },
-+ *      }
-+ *   },
-+ *   section_t {
-+ *      .name     = '%additional_info'
-+ *      .items    = { '%reporter%' };
-+ *      .children = {
-+ *        section_t {
-+ *          .name     = 'User:';
-+ *          .items    = { 'user_name', 'uid' };
-+ *          .children = NULL;
-+ *        },
-+ *        section_t {
-+ *          .name     = '';
-+ *          .items    = NULL;
-+ *          .children = NULL;
-+ *        },
-+ *        section_t {
-+ *          .name     = 'Directories:';
-+ *          .items    = { 'root', 'cwd' };
-+ *          .children = NULL;
-+ *        },
-+ *      }
-+ *   }
-+ * }
-+ */
-+struct section_t {
-+    char *name;      ///< name or output text (%summar, 'Package version:');
-+    GList *items;    ///< list of file names and special items (%reporter, %binar, ...)
-+    GList *children; ///< list of sub sections (struct section_t)
-+};
-+
-+typedef struct section_t section_t;
-+
-+static section_t *
-+section_new(const char *name)
-+{
-+    section_t *self = xmalloc(sizeof(*self));
-+    self->name = xstrdup(name);
-+    self->items = NULL;
-+    self->children = NULL;
-+
-+    return self;
-+}
-+
-+static void
-+section_free(section_t *self)
-+{
-+    if (self == NULL)
-+        return;
-+
-+    free(self->name);
-+    g_list_free_full(self->items, free);
-+    g_list_free_full(self->children, (GDestroyNotify)section_free);
-+
-+    free(self);
-+}
-+
-+static int
-+section_name_cmp(section_t *lhs, const char *rhs)
-+{
-+    return strcmp((lhs->name + 1), rhs);
-+}
-+
-+/* Utility functions */
-+
-+static GList*
-+split_string_on_char(const char *str, char ch)
-+{
-+    GList *list = NULL;
-+    for (;;)
-+    {
-+        const char *delim = strchrnul(str, ch);
-+        list = g_list_prepend(list, xstrndup(str, delim - str));
-+        if (*delim == '\0')
-+            break;
-+        str = delim + 1;
-+    }
-+    return g_list_reverse(list);
-+}
-+
-+static int
-+compare_item_name(const char *lookup, const char *name)
-+{
-+    if (lookup[0] == '-')
-+        lookup++;
-+    else if (strncmp(lookup, "%bare_", 6) == 0)
-+        lookup += 6;
-+    return strcmp(lookup, name);
-+}
-+
-+static int
-+is_item_name_in_section(const section_t *lookup, const char *name)
-+{
-+    if (g_list_find_custom(lookup->items, name, (GCompareFunc)compare_item_name))
-+        return 0; /* "found it!" */
-+    return 1;
-+}
-+
-+static bool is_explicit_or_forbidden(const char *name, GList *comment_fmt_spec);
-+
-+static int
-+is_explicit_or_forbidden_child(const section_t *master_section, const char *name)
-+{
-+    if (is_explicit_or_forbidden(name, master_section->children))
-+        return 0; /* "found it!" */
-+    return 1;
-+}
-+
-+/* For example: 'package' belongs to '%oneline', but 'package' is used in
-+ * 'Version of component', so it is not very helpful to include that file once
-+ * more in another section
-+ */
-+static bool
-+is_explicit_or_forbidden(const char *name, GList *comment_fmt_spec)
-+{
-+    return    g_list_find_custom(comment_fmt_spec, name, (GCompareFunc)is_item_name_in_section)
-+           || g_list_find_custom(comment_fmt_spec, name, (GCompareFunc)is_explicit_or_forbidden_child);
-+}
-+
-+static GList*
-+load_stream(FILE *fp)
-+{
-+    assert(fp);
-+
-+    GList *sections = NULL;
-+    section_t *master = section_new("%description");
-+    section_t *sec = NULL;
-+
-+    sections = g_list_append(sections, master);
-+
-+    char *line;
-+    while ((line = xmalloc_fgetline(fp)) != NULL)
-+    {
-+        /* Skip comments */
-+        char first = *skip_whitespace(line);
-+        if (first == '#')
-+            goto free_line;
-+
-+        /* Handle trailing backslash continuation */
-+ check_continuation: ;
-+        unsigned len = strlen(line);
-+        if (len && line[len-1] == '\\')
-+        {
-+            line[len-1] = '\0';
-+            char *next_line = xmalloc_fgetline(fp);
-+            if (next_line)
-+            {
-+                line = append_to_malloced_string(line, next_line);
-+                free(next_line);
-+                goto check_continuation;
-+            }
-+        }
-+
-+        /* We are reusing line buffer to form temporary
-+         * "key\0values\0..." in its beginning
-+         */
-+        bool summary_line = false;
-+        char *value = NULL;
-+        char *src;
-+        char *dst;
-+        for (src = dst = line; *src; src++)
-+        {
-+            char c = *src;
-+            /* did we reach the value list? */
-+            if (!value && c == ':' && src[1] == ':')
-+            {
-+                *dst++ = '\0'; /* terminate key */
-+                src += 1;
-+                value = dst; /* remember where value starts */
-+                summary_line = (strcmp(line, "%summary") == 0);
-+                if (summary_line)
-+                {
-+                    value = (src + 1);
-+                    break;
-+                }
-+                continue;
-+            }
-+            /* skip whitespace in value list */
-+            if (value && isspace(c))
-+                continue;
-+            *dst++ = c; /* store next key or value char */
-+        }
-+
-+        GList *item_list = NULL;
-+        if (summary_line)
-+        {
-+            /* %summary is special */
-+            item_list = g_list_append(NULL, xstrdup(skip_whitespace(value)));
-+        }
-+        else
-+        {
-+            *dst = '\0'; /* terminate value (or key) */
-+            if (value)
-+                item_list = split_string_on_char(value, ',');
-+        }
-+
-+        sec = section_new(line);
-+        sec->items = item_list;
-+
-+        if (sec->name[0] == '%')
-+        {
-+            if (!summary_line && strcmp(sec->name, "%attach") != 0)
-+            {
-+                master->children = g_list_reverse(master->children);
-+                master = sec;
-+            }
-+
-+            sections = g_list_prepend(sections, sec);
-+        }
-+        else
-+            master->children = g_list_prepend(master->children, sec);
-+
-+ free_line:
-+        free(line);
-+    }
-+
-+    /* If master equals sec, then master's children list was not yet reversed.
-+     *
-+     * %description is the default section (i.e is not explicitly mentioned)
-+     * and %summary nor %attach cause its children list to reverse.
-+     */
-+    if (master == sec || strcmp(master->name, "%description") == 0)
-+        master->children = g_list_reverse(master->children);
-+
-+    return sections;
-+}
-+
-+
-+/* Summary generation */
-+
-+#define MAX_OPT_DEPTH 10
-+static int
-+format_percented_string(const char *str, problem_data_t *pd, FILE *result)
-+{
-+    long old_pos[MAX_OPT_DEPTH] = { 0 };
-+    int okay[MAX_OPT_DEPTH] = { 1 };
-+    long len = 0;
-+    int opt_depth = 1;
-+
-+    while (*str) {
-+        switch (*str) {
-+        default:
-+            putc(*str, result);
-+            len++;
-+            str++;
-+            break;
-+        case '\\':
-+            if (str[1])
-+                str++;
-+            putc(*str, result);
-+            len++;
-+            str++;
-+            break;
-+        case '[':
-+            if (str[1] == '[' && opt_depth < MAX_OPT_DEPTH)
-+            {
-+                old_pos[opt_depth] = len;
-+                okay[opt_depth] = 1;
-+                opt_depth++;
-+                str += 2;
-+            } else {
-+                putc(*str, result);
-+                len++;
-+                str++;
-+            }
-+            break;
-+        case ']':
-+            if (str[1] == ']' && opt_depth > 1)
-+            {
-+                opt_depth--;
-+                if (!okay[opt_depth])
-+                {
-+                    if (fseek(result, old_pos[opt_depth], SEEK_SET) < 0)
-+                        perror_msg_and_die("fseek");
-+                    len = old_pos[opt_depth];
-+                }
-+                str += 2;
-+            } else {
-+                putc(*str, result);
-+                len++;
-+                str++;
-+            }
-+            break;
-+        case '%': ;
-+            char *nextpercent = strchr(++str, '%');
-+            if (!nextpercent)
-+            {
-+                error_msg_and_die("Unterminated %%element%%: '%s'", str - 1);
-+            }
-+
-+            *nextpercent = '\0';
-+            const problem_item *item = problem_data_get_item_or_NULL(pd, str);
-+            *nextpercent = '%';
-+
-+            if (item && (item->flags & CD_FLAG_TXT))
-+            {
-+                fputs(item->content, result);
-+                len += strlen(item->content);
-+            }
-+            else
-+                okay[opt_depth - 1] = 0;
-+            str = nextpercent + 1;
-+            break;
-+        }
-+    }
-+
-+    if (opt_depth > 1)
-+    {
-+        error_msg_and_die("Unbalanced [[ ]] bracket");
-+    }
-+
-+    if (!okay[0])
-+    {
-+        error_msg("Undefined variable outside of [[ ]] bracket");
-+    }
-+
-+    return 0;
-+}
-+
-+/* BZ comment generation */
-+
-+static int
-+append_text(struct strbuf *result, const char *item_name, const char *content, bool print_item_name)
-+{
-+    char *eol = strchrnul(content, '\n');
-+    if (eol[0] == '\0' || eol[1] == '\0')
-+    {
-+        /* one-liner */
-+        int pad = 16 - (strlen(item_name) + 2);
-+        if (pad < 0)
-+            pad = 0;
-+        if (print_item_name)
-+            strbuf_append_strf(result,
-+                    eol[0] == '\0' ? "%s: %*s%s\n" : "%s: %*s%s",
-+                    item_name, pad, "", content
-+            );
-+        else
-+            strbuf_append_strf(result,
-+                    eol[0] == '\0' ? "%s\n" : "%s",
-+                    content
-+            );
-+    }
-+    else
-+    {
-+        /* multi-line item */
-+        if (print_item_name)
-+            strbuf_append_strf(result, "%s:\n", item_name);
-+        for (;;)
-+        {
-+            eol = strchrnul(content, '\n');
-+            strbuf_append_strf(result,
-+                    /* For %bare_multiline_item, we don't want to print colons */
-+                    (print_item_name ? ":%.*s\n" : "%.*s\n"),
-+                    (int)(eol - content), content
-+            );
-+            if (eol[0] == '\0' || eol[1] == '\0')
-+                break;
-+            content = eol + 1;
-+        }
-+    }
-+    return 1;
-+}
-+
-+static int
-+append_short_backtrace(struct strbuf *result, problem_data_t *problem_data, size_t max_text_size, bool print_item_name)
-+{
-+    const problem_item *item = problem_data_get_item_or_NULL(problem_data,
-+                                                             FILENAME_BACKTRACE);
-+    if (!item)
-+        return 0; /* "I did not print anything" */
-+    if (!(item->flags & CD_FLAG_TXT))
-+        return 0; /* "I did not print anything" */
-+
-+    char *truncated = NULL;
-+
-+    if (strlen(item->content) >= max_text_size)
-+    {
-+        log_debug("'backtrace' exceeds the text file size, going to append its short version");
-+
-+        char *error_msg = NULL;
-+        const char *type = problem_data_get_content_or_NULL(problem_data, FILENAME_TYPE);
-+        if (!type)
-+        {
-+            log_debug("Problem data does not contain '"FILENAME_TYPE"' file");
-+            return 0;
-+        }
-+
-+        /* For CCpp crashes, use the GDB-produced backtrace which should be
-+         * available by now. sr_abrt_type_from_analyzer returns SR_REPORT_CORE
-+         * by default for CCpp crashes.
-+         */
-+        enum sr_report_type report_type = sr_abrt_type_from_analyzer(type);
-+        if (strcmp(type, "CCpp") == 0)
-+        {
-+            log_debug("Successfully identified 'CCpp' abrt type");
-+            report_type = SR_REPORT_GDB;
-+        }
-+
-+        struct sr_stacktrace *backtrace = sr_stacktrace_parse(report_type,
-+                item->content, &error_msg);
-+
-+        if (!backtrace)
-+        {
-+            log(_("Can't parse backtrace: %s"), error_msg);
-+            free(error_msg);
-+            return 0;
-+        }
-+
-+        /* Get optimized thread stack trace for 10 top most frames */
-+        truncated = sr_stacktrace_to_short_text(backtrace, 10);
-+        sr_stacktrace_free(backtrace);
-+
-+        if (!truncated)
-+        {
-+            log(_("Can't generate stacktrace description (no crash thread?)"));
-+            return 0;
-+        }
-+    }
-+    else
-+    {
-+        log_debug("'backtrace' is small enough to be included as is");
-+    }
-+
-+    append_text(result,
-+                /*item_name:*/ truncated ? "truncated_backtrace" : FILENAME_BACKTRACE,
-+                /*content:*/   truncated ? truncated             : item->content,
-+                print_item_name
-+    );
-+    free(truncated);
-+    return 1;
-+}
-+
-+static int
-+append_item(struct strbuf *result, const char *item_name, problem_data_t *pd, GList *comment_fmt_spec)
-+{
-+    bool print_item_name = (strncmp(item_name, "%bare_", strlen("%bare_")) != 0);
-+    if (!print_item_name)
-+        item_name += strlen("%bare_");
-+
-+    if (item_name[0] != '%')
-+    {
-+        struct problem_item *item = problem_data_get_item_or_NULL(pd, item_name);
-+        if (!item)
-+            return 0; /* "I did not print anything" */
-+        if (!(item->flags & CD_FLAG_TXT))
-+            return 0; /* "I did not print anything" */
-+
-+        char *formatted = problem_item_format(item);
-+        char *content = formatted ? formatted : item->content;
-+        append_text(result, item_name, content, print_item_name);
-+        free(formatted);
-+        return 1; /* "I printed something" */
-+    }
-+
-+    /* Special item name */
-+
-+    /* Compat with previously-existed ad-hockery: %short_backtrace */
-+    if (strcmp(item_name, "%short_backtrace") == 0)
-+        return append_short_backtrace(result, pd, CD_TEXT_ATT_SIZE_BZ, print_item_name);
-+
-+    /* Compat with previously-existed ad-hockery: %reporter */
-+    if (strcmp(item_name, "%reporter") == 0)
-+        return append_text(result, "reporter", PACKAGE"-"VERSION, print_item_name);
-+
-+    /* %oneline,%multiline,%text */
-+    bool oneline   = (strcmp(item_name+1, "oneline"  ) == 0);
-+    bool multiline = (strcmp(item_name+1, "multiline") == 0);
-+    bool text      = (strcmp(item_name+1, "text"     ) == 0);
-+    if (!oneline && !multiline && !text)
-+    {
-+        log("Unknown or unsupported element specifier '%s'", item_name);
-+        return 0; /* "I did not print anything" */
-+    }
-+
-+    int printed = 0;
-+
-+    /* Iterate over _sorted_ items */
-+    GList *sorted_names = g_hash_table_get_keys(pd);
-+    sorted_names = g_list_sort(sorted_names, (GCompareFunc)strcmp);
-+
-+    /* %text => do as if %oneline, then repeat as if %multiline */
-+    if (text)
-+        oneline = 1;
-+
-+ again: ;
-+    GList *l = sorted_names;
-+    while (l)
-+    {
-+        const char *name = l->data;
-+        l = l->next;
-+        struct problem_item *item = g_hash_table_lookup(pd, name);
-+        if (!item)
-+            continue; /* paranoia, won't happen */
-+
-+        if (!(item->flags & CD_FLAG_TXT))
-+            continue;
-+
-+        if (is_explicit_or_forbidden(name, comment_fmt_spec))
-+            continue;
-+
-+        char *formatted = problem_item_format(item);
-+        char *content = formatted ? formatted : item->content;
-+        char *eol = strchrnul(content, '\n');
-+        bool is_oneline = (eol[0] == '\0' || eol[1] == '\0');
-+        if (oneline == is_oneline)
-+            printed |= append_text(result, name, content, print_item_name);
-+        free(formatted);
-+    }
-+    if (text && oneline)
-+    {
-+        /* %text, and we just did %oneline. Repeat as if %multiline */
-+        oneline = 0;
-+        /*multiline = 1; - not checked in fact, so why bother setting? */
-+        goto again;
-+    }
-+
-+    g_list_free(sorted_names); /* names themselves are not freed */
-+
-+    return printed;
-+}
-+
-+#define add_to_section_output(format, ...) \
-+    do { \
-+    for (; empty_lines > 0; --empty_lines) fputc('\n', result); \
-+    empty_lines = 0; \
-+    fprintf(result, format, __VA_ARGS__); \
-+    } while (0)
-+
-+static void
-+format_section(section_t *section, problem_data_t *pd, GList *comment_fmt_spec, FILE *result)
-+{
-+    int empty_lines = -1;
-+
-+    for (GList *iter = section->children; iter; iter = g_list_next(iter))
-+    {
-+        section_t *child = (section_t *)iter->data;
-+        if (child->items)
-+        {
-+            /* "Text: item[,item]..." */
-+            struct strbuf *output = strbuf_new();
-+            GList *item = child->items;
-+            while (item)
-+            {
-+                const char *str = item->data;
-+                item = item->next;
-+                if (str[0] == '-') /* "-name", ignore it */
-+                    continue;
-+                append_item(output, str, pd, comment_fmt_spec);
-+            }
-+
-+            if (output->len != 0)
-+                add_to_section_output((child->name[0] ? "%s:\n%s" : "%s%s"),
-+                                      child->name, output->buf);
-+
-+            strbuf_free(output);
-+        }
-+        else
-+        {
-+            /* Just "Text" (can be "") */
-+
-+            /* Filter out trailint empty lines */
-+            if (child->name[0] != '\0')
-+                add_to_section_output("%s\n", child->name);
-+            /* Do not count empty lines, if output wasn't yet produced */
-+            else if (empty_lines >= 0)
-+                ++empty_lines;
-+        }
-+    }
-+}
-+
-+static GList *
-+get_special_items(const char *item_name, problem_data_t *pd, GList *comment_fmt_spec)
-+{
-+    /* %oneline,%multiline,%text,%binary */
-+    bool oneline   = (strcmp(item_name+1, "oneline"  ) == 0);
-+    bool multiline = (strcmp(item_name+1, "multiline") == 0);
-+    bool text      = (strcmp(item_name+1, "text"     ) == 0);
-+    bool binary    = (strcmp(item_name+1, "binary"   ) == 0);
-+    if (!oneline && !multiline && !text && !binary)
-+    {
-+        log("Unknown or unsupported element specifier '%s'", item_name);
-+        return NULL;
-+    }
-+
-+    log_debug("Special item_name '%s', iterating for attach...", item_name);
-+    GList *result = 0;
-+
-+    /* Iterate over _sorted_ items */
-+    GList *sorted_names = g_hash_table_get_keys(pd);
-+    sorted_names = g_list_sort(sorted_names, (GCompareFunc)strcmp);
-+
-+    GList *l = sorted_names;
-+    while (l)
-+    {
-+        const char *name = l->data;
-+        l = l->next;
-+        struct problem_item *item = g_hash_table_lookup(pd, name);
-+        if (!item)
-+            continue; /* paranoia, won't happen */
-+
-+        if (is_explicit_or_forbidden(name, comment_fmt_spec))
-+            continue;
-+
-+        if ((item->flags & CD_FLAG_TXT) && !binary)
-+        {
-+            char *content = item->content;
-+            char *eol = strchrnul(content, '\n');
-+            bool is_oneline = (eol[0] == '\0' || eol[1] == '\0');
-+            if (text || oneline == is_oneline)
-+                result = g_list_append(result, xstrdup(name));
-+        }
-+        else if ((item->flags & CD_FLAG_BIN) && binary)
-+            result = g_list_append(result, xstrdup(name));
-+    }
-+
-+    g_list_free(sorted_names); /* names themselves are not freed */
-+
-+
-+    log_debug("...Done iterating over '%s' for attach", item_name);
-+
-+    return result;
-+}
-+
-+static GList *
-+get_attached_files(problem_data_t *pd, GList *items, GList *comment_fmt_spec)
-+{
-+    GList *result = NULL;
-+    GList *item = items;
-+    while (item != NULL)
-+    {
-+        const char *item_name = item->data;
-+        item = item->next;
-+        if (item_name[0] == '-') /* "-name", ignore it */
-+            continue;
-+
-+        if (item_name[0] != '%')
-+        {
-+            result = g_list_append(result, xstrdup(item_name));
-+            continue;
-+        }
-+
-+        GList *special = get_special_items(item_name, pd, comment_fmt_spec);
-+        if (special == NULL)
-+        {
-+            log_notice("No attachment found for '%s'", item_name);
-+            continue;
-+        }
-+
-+        result = g_list_concat(result, special);
-+    }
-+
-+    return result;
-+}
-+
-+/*
-+ * Problem Report - memor stream
-+ *
-+ * A wrapper for POSIX memory stream.
-+ *
-+ * A memory stream is presented as FILE *.
-+ *
-+ * A memory stream is associated with a pointer to written data and a pointer
-+ * to size of the written data.
-+ *
-+ * This structure holds all of the used pointers.
-+ */
-+struct memstream_buffer
-+{
-+    char *msb_buffer;
-+    size_t msb_size;
-+    FILE *msb_stream;
-+};
-+
-+static struct memstream_buffer *
-+memstream_buffer_new()
-+{
-+    struct memstream_buffer *self = xmalloc(sizeof(*self));
-+
-+    self->msb_buffer = NULL;
-+    self->msb_stream = open_memstream(&(self->msb_buffer), &(self->msb_size));
-+
-+    return self;
-+}
-+
-+static void
-+memstream_buffer_free(struct memstream_buffer *self)
-+{
-+    if (self == NULL)
-+        return;
-+
-+    fclose(self->msb_stream);
-+    self->msb_stream = DESTROYED_POINTER;
-+
-+    free(self->msb_buffer);
-+    self->msb_buffer = DESTROYED_POINTER;
-+
-+    free(self);
-+}
-+
-+static FILE *
-+memstream_get_stream(struct memstream_buffer *self)
-+{
-+    assert(self != NULL);
-+
-+    return self->msb_stream;
-+}
-+
-+static const char *
-+memstream_get_string(struct memstream_buffer *self)
-+{
-+    assert(self != NULL);
-+    assert(self->msb_stream != NULL);
-+
-+    fflush(self->msb_stream);
-+
-+    return self->msb_buffer;
-+}
-+
-+
-+/*
-+ * Problem Report
-+ *
-+ * The formated strings are internaly stored in "buffer"s. If a programer wants
-+ * to get a formated section data, a getter function extracts those data from
-+ * the apropriate buffer and returns them in form of null-terminated string.
-+ *
-+ * Each section has own buffer.
-+ *
-+ * There are three common sections that are always present:
-+ * 1. summary
-+ * 2. description
-+ * 3. attach
-+ * Buffers of these sections has own structure member for the sake of
-+ * efficiency.
-+ *
-+ * The custom sections hash their buffers stored in a map where key is a
-+ * section's name and value is a section's buffer.
-+ *
-+ * Problem report provides the programers with the possibility to ammend
-+ * formated output to any section buffer.
-+ */
-+struct problem_report
-+{
-+    struct memstream_buffer *pr_sec_summ; ///< %summary buffer
-+    struct memstream_buffer *pr_sec_desc; ///< %description buffer
-+    GList            *pr_attachments;     ///< %attach - list of file names
-+    GHashTable       *pr_sec_custom;      ///< map : %(custom section) -> buffer
-+};
-+
-+static problem_report_t *
-+problem_report_new()
-+{
-+    problem_report_t *self = xmalloc(sizeof(*self));
-+
-+    self->pr_sec_summ = memstream_buffer_new();
-+    self->pr_sec_desc = memstream_buffer_new();
-+    self->pr_attachments = NULL;
-+    self->pr_sec_custom = NULL;
-+
-+    return self;
-+}
-+
-+static void
-+problem_report_initialize_custom_sections(problem_report_t *self)
-+{
-+    assert(self != NULL);
-+    assert(self->pr_sec_custom == NULL);
-+
-+    self->pr_sec_custom = g_hash_table_new_full(g_str_hash, g_str_equal, free,
-+                                                (GDestroyNotify)memstream_buffer_free);
-+}
-+
-+static void
-+problem_report_destroy_custom_sections(problem_report_t *self)
-+{
-+    assert(self != NULL);
-+    assert(self->pr_sec_custom != NULL);
-+
-+    g_hash_table_destroy(self->pr_sec_custom);
-+}
-+
-+static int
-+problem_report_add_custom_section(problem_report_t *self, const char *name)
-+{
-+    assert(self != NULL);
-+
-+    if (self->pr_sec_custom == NULL)
-+    {
-+        problem_report_initialize_custom_sections(self);
-+    }
-+
-+    if (problem_report_get_buffer(self, name))
-+    {
-+        log_warning("Custom section already exists : '%s'", name);
-+        return -EEXIST;
-+    }
-+
-+    log_debug("Problem report enriched with section : '%s'", name);
-+    g_hash_table_insert(self->pr_sec_custom, xstrdup(name), memstream_buffer_new());
-+    return 0;
-+}
-+
-+static struct memstream_buffer *
-+problem_report_get_section_buffer(const problem_report_t *self, const char *section_name)
-+{
-+    if (self->pr_sec_custom == NULL)
-+    {
-+        log_debug("Couldn't find section '%s': no custom section added", section_name);
-+        return NULL;
-+    }
-+
-+    return (struct memstream_buffer *)g_hash_table_lookup(self->pr_sec_custom, section_name);
-+}
-+
-+problem_report_buffer *
-+problem_report_get_buffer(const problem_report_t *self, const char *section_name)
-+{
-+    assert(self != NULL);
-+    assert(section_name != NULL);
-+
-+    if (strcmp(PR_SEC_SUMMARY, section_name) == 0)
-+        return memstream_get_stream(self->pr_sec_summ);
-+
-+    if (strcmp(PR_SEC_DESCRIPTION, section_name) == 0)
-+        return memstream_get_stream(self->pr_sec_desc);
-+
-+    struct memstream_buffer *buf = problem_report_get_section_buffer(self, section_name);
-+    return buf == NULL ? NULL : memstream_get_stream(buf);
-+}
-+
-+const char *
-+problem_report_get_summary(const problem_report_t *self)
-+{
-+    assert(self != NULL);
-+
-+    return memstream_get_string(self->pr_sec_summ);
-+}
-+
-+const char *
-+problem_report_get_description(const problem_report_t *self)
-+{
-+    assert(self != NULL);
-+
-+    return memstream_get_string(self->pr_sec_desc);
-+}
-+
-+const char *
-+problem_report_get_section(const problem_report_t *self, const char *section_name)
-+{
-+    assert(self != NULL);
-+    assert(section_name);
-+
-+    struct memstream_buffer *buf = problem_report_get_section_buffer(self, section_name);
-+
-+    if (buf == NULL)
-+        return NULL;
-+
-+    return memstream_get_string(buf);
-+}
-+
-+static void
-+problem_report_set_attachments(problem_report_t *self, GList *attachments)
-+{
-+    assert(self != NULL);
-+    assert(self->pr_attachments == NULL);
-+
-+    self->pr_attachments = attachments;
-+}
-+
-+GList *
-+problem_report_get_attachments(const problem_report_t *self)
-+{
-+    assert(self != NULL);
-+
-+    return self->pr_attachments;
-+}
-+
-+void
-+problem_report_free(problem_report_t *self)
-+{
-+    if (self == NULL)
-+        return;
-+
-+    memstream_buffer_free(self->pr_sec_summ);
-+    self->pr_sec_summ = DESTROYED_POINTER;
-+
-+    memstream_buffer_free(self->pr_sec_desc);
-+    self->pr_sec_desc = DESTROYED_POINTER;
-+
-+    g_list_free_full(self->pr_attachments, free);
-+    self->pr_attachments = DESTROYED_POINTER;
-+
-+    if (self->pr_sec_custom)
-+    {
-+        problem_report_destroy_custom_sections(self);
-+        self->pr_sec_custom = DESTROYED_POINTER;
-+    }
-+
-+    free(self);
-+}
-+
-+/*
-+ * Problem Formatter - extra section
-+ */
-+struct extra_section
-+{
-+    char *pfes_name;    ///< name with % prefix
-+    int   pfes_flags;   ///< whether is required or not
-+};
-+
-+static struct extra_section *
-+extra_section_new(const char *name, int flags)
-+{
-+    struct extra_section *self = xmalloc(sizeof(*self));
-+
-+    self->pfes_name = xstrdup(name);
-+    self->pfes_flags = flags;
-+
-+    return self;
-+}
-+
-+static void
-+extra_section_free(struct extra_section *self)
-+{
-+    if (self == NULL)
-+        return;
-+
-+    free(self->pfes_name);
-+    self->pfes_name = DESTROYED_POINTER;
-+
-+    free(self);
-+}
-+
-+static int
-+extra_section_name_cmp(struct extra_section *lhs, const char *rhs)
-+{
-+    return strcmp(lhs->pfes_name, rhs);
-+}
-+
-+/*
-+ * Problem Formatter
-+ *
-+ * Holds parsed sections lists.
-+ */
-+struct problem_formatter
-+{
-+    GList *pf_sections;         ///< parsed sections (struct section_t)
-+    GList *pf_extra_sections;   ///< user configured sections (struct extra_section)
-+    char  *pf_default_summary;  ///< default summary format
-+};
-+
-+problem_formatter_t *
-+problem_formatter_new(void)
-+{
-+    problem_formatter_t *self = xzalloc(sizeof(*self));
-+
-+    self->pf_default_summary = xstrdup("%reason%");
-+
-+    return self;
-+}
-+
-+void
-+problem_formatter_free(problem_formatter_t *self)
-+{
-+    if (self == NULL)
-+        return;
-+
-+    g_list_free_full(self->pf_sections, (GDestroyNotify)section_free);
-+    self->pf_sections = DESTROYED_POINTER;
-+
-+    g_list_free_full(self->pf_extra_sections, (GDestroyNotify)extra_section_free);
-+    self->pf_extra_sections = DESTROYED_POINTER;
-+
-+    free(self->pf_default_summary);
-+    self->pf_default_summary = DESTROYED_POINTER;
-+
-+    free(self);
-+}
-+
-+static int
-+problem_formatter_is_section_known(problem_formatter_t *self, const char *name)
-+{
-+  return    strcmp(name, "summary")     == 0
-+         || strcmp(name, "attach")      == 0
-+         || strcmp(name, "description") == 0
-+         || NULL != g_list_find_custom(self->pf_extra_sections, name, (GCompareFunc)extra_section_name_cmp);
-+}
-+
-+// i.e additional_info -> no flags
-+int
-+problem_formatter_add_section(problem_formatter_t *self, const char *name, int flags)
-+{
-+    /* Do not add already added sections */
-+    if (problem_formatter_is_section_known(self, name))
-+    {
-+        log_debug("Extra section already exists : '%s' ", name);
-+        return -EEXIST;
-+    }
-+
-+    self->pf_extra_sections = g_list_prepend(self->pf_extra_sections,
-+                                             extra_section_new(name, flags));
-+
-+    return 0;
-+}
-+
-+// check format validity and produce warnings
-+static int
-+problem_formatter_validate(problem_formatter_t *self)
-+{
-+    int retval = 0;
-+
-+    /* Go through all (struct extra_section)s and check whete those having flag
-+     * PFFF_REQUIRED are present in the parsed (struct section_t)s.
-+     */
-+    for (GList *iter = self->pf_extra_sections; iter; iter = g_list_next(iter))
-+    {
-+        struct extra_section *section = (struct extra_section *)iter->data;
-+
-+        log_debug("Validating extra section : '%s'", section->pfes_name);
-+
-+        if (   (PFFF_REQUIRED & section->pfes_flags)
-+            && NULL == g_list_find_custom(self->pf_sections, section->pfes_name, (GCompareFunc)section_name_cmp))
-+        {
-+            log_warning("Problem format misses required section : '%s'", section->pfes_name);
-+            ++retval;
-+        }
-+    }
-+
-+    /* Go through all the parsed (struct section_t)s check whether are all
-+     * known, i.e. each section is either one of the common sections (summary,
-+     * description, attach) or is present in the (struct extra_section)s.
-+     */
-+    for (GList *iter = self->pf_sections; iter; iter = g_list_next(iter))
-+    {
-+        section_t *section = (section_t *)iter->data;
-+
-+        if (!problem_formatter_is_section_known(self, (section->name + 1)))
-+        {
-+            log_warning("Problem format contains unrecognized section : '%s'", section->name);
-+            ++retval;
-+        }
-+    }
-+
-+    return retval;
-+}
-+
-+int
-+problem_formatter_load_string(problem_formatter_t *self, const char *fmt)
-+{
-+    const size_t len = strlen(fmt);
-+    if (len != 0)
-+    {
-+        FILE *fp = fmemopen((void *)fmt, len, "r");
-+        if (fp == NULL)
-+        {
-+            error_msg("Not enough memory to open a stream for reading format string.");
-+            return -ENOMEM;
-+        }
-+
-+        self->pf_sections = load_stream(fp);
-+        fclose(fp);
-+    }
-+
-+    return problem_formatter_validate(self);
-+}
-+
-+int
-+problem_formatter_load_file(problem_formatter_t *self, const char *path)
-+{
-+    FILE *fp = stdin;
-+    if (strcmp(path, "-") != 0)
-+    {
-+        fp = fopen(path, "r");
-+        if (!fp)
-+            return -ENOENT;
-+    }
-+
-+    self->pf_sections = load_stream(fp);
-+
-+    if (fp != stdin)
-+        fclose(fp);
-+
-+    return problem_formatter_validate(self);
-+}
-+
-+// generates report
-+int
-+problem_formatter_generate_report(const problem_formatter_t *self, problem_data_t *data, problem_report_t **report)
-+{
-+    problem_report_t *pr = problem_report_new();
-+
-+    for (GList *iter = self->pf_extra_sections; iter; iter = g_list_next(iter))
-+        problem_report_add_custom_section(pr, ((struct extra_section *)iter->data)->pfes_name);
-+
-+    bool has_summary = false;
-+    for (GList *iter = self->pf_sections; iter; iter = g_list_next(iter))
-+    {
-+        section_t *section = (section_t *)iter->data;
-+
-+        /* %summary is something special */
-+        if (strcmp(section->name, "%summary") == 0)
-+        {
-+            has_summary = true;
-+            format_percented_string((const char *)section->items->data, data,
-+                                    problem_report_get_buffer(pr, PR_SEC_SUMMARY));
-+        }
-+        /* %attach as well */
-+        else if (strcmp(section->name, "%attach") == 0)
-+        {
-+            problem_report_set_attachments(pr, get_attached_files(data, section->items, self->pf_sections));
-+        }
-+        else /* %description or a custom section (e.g. %additional_info) */
-+        {
-+            FILE *buffer = problem_report_get_buffer(pr, section->name + 1);
-+
-+            if (buffer != NULL)
-+            {
-+                log_debug("Formatting section : '%s'", section->name);
-+                format_section(section, data, self->pf_sections, buffer);
-+            }
-+            else
-+                log_warning("Unsupported section '%s'", section->name);
-+        }
-+    }
-+
-+    if (!has_summary) {
-+        log_debug("Problem format misses section '%%summary'. Using the default one : '%s'.",
-+                    self->pf_default_summary);
-+
-+        format_percented_string(self->pf_default_summary,
-+                   data, problem_report_get_buffer(pr, PR_SEC_SUMMARY));
-+    }
-+
-+    *report = pr;
-+    return 0;
-+}
-diff --git a/src/plugins/problem_report.h b/src/plugins/problem_report.h
-new file mode 100644
-index 0000000..f2d41d8
---- /dev/null
-+++ b/src/plugins/problem_report.h
-@@ -0,0 +1,334 @@
-+/*
-+    Copyright (C) 2014  ABRT team
-+    Copyright (C) 2014  RedHat Inc
-+
-+    This program is free software; you can redistribute it and/or modify
-+    it under the terms of the GNU General Public License as published by
-+    the Free Software Foundation; either version 2 of the License, or
-+    (at your option) any later version.
-+
-+    This program is distributed in the hope that it will be useful,
-+    but WITHOUT ANY WARRANTY; without even the implied warranty of
-+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+    GNU General Public License for more details.
-+
-+    You should have received a copy of the GNU General Public License along
-+    with this program; if not, write to the Free Software Foundation, Inc.,
-+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-+
-+    @brief API for formating of problem data
-+
-+    These functions can be used to convert a problem data to its string
-+    representation.
-+
-+    The output format can be parsed from a string:
-+
-+        problem_formatter_t *formatter = problem_formatter_new();
-+        problem_formatter_load_string(formatter, MY_FORMAT_STRING);
-+
-+    or loaded from a file:
-+
-+        problem_formatter_t *formatter = problem_formatter_new();
-+        problem_formatter_load_file(formatter, MY_FORMAT_FILE);
-+
-+    Once you have configured your formatter you can convert problem_data to
-+    problem_report by calling:
-+
-+        problem_report_t *report;
-+        if (problem_formatter_generate_report(formatter, data, &report) != 0)
-+            errx(EXIT_FAILURE, "Problem data cannot be converted to problem report.");
-+
-+    Now you can print the report:
-+
-+        printf("Problem: %s\n", problem_report_get_summary());
-+        printf("%s\n",          problem_report_get_description());
-+
-+        puts("Problem attachments:");
-+        for (GList *a = problem_report_get_attachments(pr); a != NULL; a = g_list_next(a))
-+            printf(" %s\n", a->data);
-+
-+    Format description:
-+
-+         ----
-+         %summary:: summary format
-+         %attach:: elemnt1[,element2]...
-+         section:: element1[,element2]...
-+         The literal text line to be added to report.
-+         ----
-+
-+         Summary format is a line of text, where %element% is replaced by
-+         text element's content, and [[...%element%...]] block is used only if
-+         %element% exists. [[...]] blocks can nest.
-+
-+         Sections can be:
-+         - %summary: bug summary format string.
-+
-+         - %attach: a list of elements to attach.
-+
-+         - text, double colon (::) and the list of comma-separated elements.
-+           Text can be empty (":: elem1, elem2, elem3" works),
-+           in this case "Text:" header line will be omitted.
-+
-+         - %description: this section is implicit and contains all text
-+           sections unless another section was specified (%summary and %attach
-+           are ignored when determining text section's placement)
-+
-+         - every text element belongs to the last specified section (%summary
-+           and %attach sections are ignored). If no section was specified,
-+           the text element belogns to %description.
-+
-+         - If none of elements exists, the section will not be created.
-+
-+         - Empty lines are NOT ignored.
-+
-+         Elements can be:
-+         - problem directory element names, which get formatted as
-+           <element_name>: <contents>
-+           or
-+           <element_name>:
-+           :<contents>
-+           :<contents>
-+           :<contents>
-+
-+         - problem directory element names prefixed by "%bare_",
-+           which is formatted as-is, without "<element_name>:" and colons
-+
-+         - %oneline, %multiline, %text wildcards, which select all corresponding
-+           elements for output or attachment
-+
-+         - %binary wildcard, valid only for %attach section, instructs to attach
-+           binary elements
-+
-+         - problem directory element names prefixed by "-",
-+           which excludes given element from all wildcards
-+
-+         - Nonexistent elements are silently ignored.
-+
-+    You can add your own section:
-+
-+        problem_formatter_t *formatter = problem_formatter_new();
-+        problem_formatter_add_section(formatter, "additional_info", PFFF_REQUIRED);
-+
-+    and then you can use the section in the formatting string:
-+
-+        problem_formatter_load_string(formatter,
-+                "::comment\n"
-+                "%additional_info:: maps");
-+        problem_formatter_generate_report(formatter, data, &report);
-+
-+        printf("Problem: %s\n",         problem_report_get_summary());
-+        printf("%s\n",                  problem_report_get_description());
-+        printf("Additional info: %s\n", problem_report_get_section(report, "additiona_info"));
-+
-+    The lines above are equivalent to the following lines:
-+
-+        printf("Problem: %s\n",         problem_data_get_content_or_NULL(data, "reason"));
-+        printf("%s\n",                  problem_data_get_content_or_NULL(data, "comment"));
-+        printf("Additional info: %s\n", problem_data_get_content_or_NULL(data, "maps"));
-+*/
-+#ifndef LIBREPORT_PROBLEM_REPORT_H
-+#define LIBREPORT_PROBLEM_REPORT_H
-+
-+#include <glib.h>
-+#include <stdio.h>
-+#include "problem_data.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#define PR_SEC_SUMMARY "summary"
-+#define PR_SEC_DESCRIPTION "description"
-+
-+/*
-+ * The problem report structure represents a problem data formatted according
-+ * to a format string.
-+ *
-+ * A problem report is composed of well-known sections:
-+ *   - summary
-+ *   - descritpion
-+ *   - attach
-+ *
-+ * and custom sections accessed by:
-+ *   problem_report_get_section();
-+ */
-+struct problem_report;
-+typedef struct problem_report problem_report_t;
-+
-+/*
-+ * Helpers for easily switching between FILE and struct strbuf
-+ */
-+
-+/*
-+ * Type of buffer used by Problem report
-+ */
-+typedef FILE problem_report_buffer;
-+
-+/*
-+ * Wrapper for the proble buffer's formated output function.
-+ */
-+#define problem_report_buffer_printf(buf, fmt, ...)\
-+    fprintf((buf), (fmt), ##__VA_ARGS__)
-+
-+
-+/*
-+ * Get a section buffer
-+ *
-+ * Use this function if you need to amend something to a formatted section.
-+ *
-+ * @param self Problem report
-+ * @param section_name Name of required section
-+ * @return Always valid pointer to a section buffer
-+ */
-+problem_report_buffer *problem_report_get_buffer(const problem_report_t *self,
-+        const char *section_name);
-+
-+/*
-+ * Get Summary string
-+ *
-+ * The returned pointer is valid as long as you perform no further output to
-+ * the summary buffer.
-+ *
-+ * @param self Problem report
-+ * @return Non-NULL pointer to summary data
-+ */
-+const char *problem_report_get_summary(const problem_report_t *self);
-+
-+/*
-+ * Get Description string
-+ *
-+ * The returned pointer is valid as long as you perform no further output to
-+ * the description buffer.
-+ *
-+ * @param self Problem report
-+ * @return Non-NULL pointer to description data
-+ */
-+const char *problem_report_get_description(const problem_report_t *self);
-+
-+/*
-+ * Get Section's string
-+ *
-+ * The returned pointer is valid as long as you perform no further output to
-+ * the section's buffer.
-+ *
-+ * @param self Problem report
-+ * @param section_name Name of the required section
-+ * @return Non-NULL pointer to description data
-+ */
-+const char *problem_report_get_section(const problem_report_t *self,
-+        const char *section_name);
-+
-+/*
-+ * Get GList of the problem data items that are to be attached
-+ *
-+ * @param self Problem report
-+ * @return A pointer to GList (NULL means empty list)
-+ */
-+GList *problem_report_get_attachments(const problem_report_t *self);
-+
-+/*
-+ * Releases all resources allocated by a problem report
-+ *
-+ * @param self Problem report
-+ */
-+void problem_report_free(problem_report_t *self);
-+
-+
-+/*
-+ * An enum of Extra section flags
-+ */
-+enum problem_formatter_section_flags {
-+    PFFF_REQUIRED = 1 << 0, ///< section must be present in the format spec
-+};
-+
-+/*
-+ * The problem formatter structure formats a problem data according to a format
-+ * string and stores result a problem report.
-+ *
-+ * The problem formatter uses '%reason%' as %summary section format string, if
-+ * %summary is not provided by a format string.
-+ */
-+struct problem_formatter;
-+typedef struct problem_formatter problem_formatter_t;
-+
-+/*
-+ * Constructs a new problem formatter.
-+ *
-+ * @return Non-NULL pointer to the new problem formatter
-+ */
-+problem_formatter_t *problem_formatter_new(void);
-+
-+/*
-+ * Releases all resources allocated by a problem formatter
-+ *
-+ * @param self Problem formatter
-+ */
-+void problem_formatter_free(problem_formatter_t *self);
-+
-+/*
-+ * Adds a new recognized section
-+ *
-+ * The problem formatter ignores a section in the format spec if the section is
-+ * not one of the default nor added by this function.
-+ *
-+ * How the problem formatter handles these extra sections:
-+ *
-+ * A custom section is something like %description section. %description is the
-+ * default section where all text (sub)sections are stored. If the formatter
-+ * finds the custom section in format string, then starts storing text
-+ * (sub)sections in the custom section.
-+ *
-+ * (%description)    |:: comment
-+ * (%description)    |
-+ * (%description)    |Package:: package
-+ * (%description)    |
-+ * (%additiona_info) |%additional_info::
-+ * (%additiona_info) |%reporter%
-+ * (%additiona_info) |User:: user_name,uid
-+ * (%additiona_info) |
-+ * (%additiona_info) |Directories:: root,cwd
-+ *
-+ *
-+ * @param self Problem formatter
-+ * @param name Name of the added section
-+ * @param flags Info about the added section
-+ * @return Zero on success. -EEXIST if the name is already known by the formatter
-+ */
-+int problem_formatter_add_section(problem_formatter_t *self, const char *name, int flags);
-+
-+/*
-+ * Loads a problem format from a string.
-+ *
-+ * @param self Problem formatter
-+ * @param fmt Format
-+ * @return Zero on success or number of warnings (e.g. missing section,
-+ * unrecognized section).
-+ */
-+int problem_formatter_load_string(problem_formatter_t* self, const char *fmt);
-+
-+/*
-+ * Loads a problem format from a file.
-+ *
-+ * @param self Problem formatter
-+ * @param pat Path to the format file
-+ * @return Zero on success or number of warnings (e.g. missing section,
-+ * unrecognized section).
-+ */
-+int problem_formatter_load_file(problem_formatter_t* self, const char *path);
-+
-+/*
-+ * Creates a new problem report, formats the data according to the loaded
-+ * format string and stores output in the report.
-+ *
-+ * @param self Problem formatter
-+ * @param data Problem data to format
-+ * @param report Pointer where the created problem report is to be stored
-+ * @return Zero on success, otherwise non-zero value.
-+ */
-+int problem_formatter_generate_report(const problem_formatter_t *self, problem_data_t *data, problem_report_t **report);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif // LIBREPORT_PROBLEM_REPORT_H
-diff --git a/tests/testsuite.at b/tests/testsuite.at
-index ccb37d1..d4648d4 100644
---- a/tests/testsuite.at
-+++ b/tests/testsuite.at
-@@ -17,7 +17,7 @@ m4_include([xml_definition.at])
- m4_include([report_python.at])
- m4_include([string_list.at])
- m4_include([ureport.at])
--m4_include([problem_report.at])
-+# m4_include([problem_report.at])
- m4_include([dump_dir.at])
- m4_include([global_config.at])
- m4_include([iso_date.at])
--- 
-1.8.3.1
-
diff --git a/SOURCES/1012-reporter-mantisbt-add-event-for-reporting-AVCs.patch b/SOURCES/1012-reporter-mantisbt-add-event-for-reporting-AVCs.patch
deleted file mode 100644
index 84924bd..0000000
--- a/SOURCES/1012-reporter-mantisbt-add-event-for-reporting-AVCs.patch
+++ /dev/null
@@ -1,245 +0,0 @@
-From 9a7a376a236e24c448eb650328d0d4841026568b Mon Sep 17 00:00:00 2001
-From: Matej Habrnal <mhabrnal@redhat.com>
-Date: Wed, 13 May 2015 16:37:19 +0200
-Subject: [PATCH 1012/1015] reporter-mantisbt: add event for reporting AVCs
-
-Without this commit is not possible to report AVCs because there are not event
-for 'report_CentOSBugTracker' with analyzer=libreport which is used for
-reporting AVCs.
-
-Related to bugs.centos#8422 and libreport#348
-
-Signed-off-by: Matej Habrnal <mhabrnal@redhat.com>
----
- doc/Makefile.am                                    |  2 +
- doc/mantisbt_format_analyzer_libreport.conf.txt    | 18 +++++++
- doc/mantisbt_formatdup_analyzer_libreport.conf.txt | 18 +++++++
- src/plugins/Makefile.am                            |  4 +-
- src/plugins/centos_report_event.conf               |  5 ++
- .../mantisbt_format_analyzer_libreport.conf        | 59 ++++++++++++++++++++++
- .../mantisbt_formatdup_analyzer_libreport.conf     | 56 ++++++++++++++++++++
- 7 files changed, 161 insertions(+), 1 deletion(-)
- create mode 100644 doc/mantisbt_format_analyzer_libreport.conf.txt
- create mode 100644 doc/mantisbt_formatdup_analyzer_libreport.conf.txt
- create mode 100644 src/plugins/mantisbt_format_analyzer_libreport.conf
- create mode 100644 src/plugins/mantisbt_formatdup_analyzer_libreport.conf
-
-diff --git a/doc/Makefile.am b/doc/Makefile.am
-index e437388..c10deb4 100644
---- a/doc/Makefile.am
-+++ b/doc/Makefile.am
-@@ -41,6 +41,8 @@ MAN5_TXT += bugzilla_format_libreport.conf.txt
- MAN5_TXT += mantisbt.conf.txt
- MAN5_TXT += mantisbt_format.conf.txt
- MAN5_TXT += mantisbt_formatdup.conf.txt
-+MAN5_TXT += mantisbt_format_analyzer_libreport.conf.txt
-+MAN5_TXT += mantisbt_formatdup_analyzer_libreport.conf.txt
- MAN5_TXT += emergencyanalysis_event.conf.txt
- MAN5_TXT += forbidden_words.conf.txt
- MAN5_TXT += mailx.conf.txt
-diff --git a/doc/mantisbt_format_analyzer_libreport.conf.txt b/doc/mantisbt_format_analyzer_libreport.conf.txt
-new file mode 100644
-index 0000000..8cbd327
---- /dev/null
-+++ b/doc/mantisbt_format_analyzer_libreport.conf.txt
-@@ -0,0 +1,18 @@
-+mantisbt_format_analyzer_libreport.conf(5)
-+==========================================
-+
-+NAME
-+----
-+mantisbt_format_analyzer_libreport.conf - configuration file for libreport.
-+
-+DESCRIPTION
-+-----------
-+This configuration file provides definition of general formatting for duplicate MantisBT issues.
-+
-+SEE ALSO
-+--------
-+reporter-mantisbt(1)
-+
-+AUTHOR
-+------
-+* ABRT Team
-diff --git a/doc/mantisbt_formatdup_analyzer_libreport.conf.txt b/doc/mantisbt_formatdup_analyzer_libreport.conf.txt
-new file mode 100644
-index 0000000..cd082de
---- /dev/null
-+++ b/doc/mantisbt_formatdup_analyzer_libreport.conf.txt
-@@ -0,0 +1,18 @@
-+mantisbt_formatdup_analyzer_libreport.conf(5)
-+=============================================
-+
-+NAME
-+----
-+mantisbt_formatdup_analyzer_libreport.conf - configuration file for libreport.
-+
-+DESCRIPTION
-+-----------
-+This configuration file provides definition of general formatting for duplicate MantisBT issues.
-+
-+SEE ALSO
-+--------
-+reporter-mantisbt(1)
-+
-+AUTHOR
-+------
-+* ABRT Team
-diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
-index f4f94ff..3c1dfff 100644
---- a/src/plugins/Makefile.am
-+++ b/src/plugins/Makefile.am
-@@ -42,7 +42,9 @@ endif
- if BUILD_MANTISBT
- reporters_plugin_conf += mantisbt.conf
- reporters_plugin_format_conf += mantisbt_format.conf \
--    mantisbt_formatdup.conf
-+    mantisbt_formatdup.conf \
-+    mantisbt_format_analyzer_libreport.conf \
-+    mantisbt_formatdup_analyzer_libreport.conf
- endif
- 
- defaultreportpluginsconfdir = $(DEFAULT_REPORT_PLUGINS_CONF_DIR)
-diff --git a/src/plugins/centos_report_event.conf b/src/plugins/centos_report_event.conf
-index 53f12d8..adbca93 100644
---- a/src/plugins/centos_report_event.conf
-+++ b/src/plugins/centos_report_event.conf
-@@ -35,3 +35,8 @@ EVENT=report_CentOSBugTracker analyzer=CCpp duphash!=
-                 -F "/etc/libreport/plugins/$format" \
-                 -A "/etc/libreport/plugins/$formatdup"
- 
-+EVENT=report_CentOSBugTracker analyzer=libreport
-+    reporter-mantisbt \
-+        -c /etc/libreport/plugins/mantisbt.conf \
-+        -F /etc/libreport/plugins/mantisbt_format_analyzer_libreport.conf \
-+        -A /etc/libreport/plugins/mantisbt_formatdup_analyzer_libreport.conf
-diff --git a/src/plugins/mantisbt_format_analyzer_libreport.conf b/src/plugins/mantisbt_format_analyzer_libreport.conf
-new file mode 100644
-index 0000000..a514e38
---- /dev/null
-+++ b/src/plugins/mantisbt_format_analyzer_libreport.conf
-@@ -0,0 +1,59 @@
-+# Lines starting with # are ignored.
-+# Lines can be continued on the next line using trailing backslash.
-+#
-+# Format:
-+# %summary:: summary format
-+# section:: element1[,element2]...
-+# The literal text line to be added to Bugzilla comment. Can be empty.
-+# (IOW: empty lines are NOT ignored!)
-+#
-+# Summary format is a line of text, where %element% is replaced by
-+# text element's content, and [[...%element%...]] block is used only if
-+# %element% exists. [[...]] blocks can nest.
-+#
-+# Sections can be:
-+# - %summary: bug summary format string.
-+# - %attach: a list of elements to attach.
-+# - text, double colon (::) and the list of comma-separated elements.
-+#   Text can be empty (":: elem1, elem2, elem3" works),
-+#   in this case "Text:" header line will be omitted.
-+#
-+# Elements can be:
-+# - problem directory element names, which get formatted as
-+#   <element_name>: <contents>
-+#   or
-+#   <element_name>:
-+#   :<contents>
-+#   :<contents>
-+#   :<contents>
-+# - problem directory element names prefixed by "%bare_",
-+#   which is formatted as-is, without "<element_name>:" and colons
-+# - %oneline, %multiline, %text wildcards, which select all corresponding
-+#   elements for output or attachment
-+# - %binary wildcard, valid only for %attach section, instructs to attach
-+#   binary elements
-+# - problem directory element names prefixed by "-",
-+#   which excludes given element from all wildcards
-+#
-+#   Nonexistent elements are silently ignored.
-+#   If none of elements exists, the section will not be created.
-+
-+%summary:: %reason%
-+
-+Description of problem:: %bare_comment, %bare_description
-+
-+Version-Release number of selected component:: %bare_package
-+
-+Truncated backtrace:: %bare_%short_backtrace
-+
-+%Additional info::
-+:: -pkg_arch,-pkg_epoch,-pkg_name,-pkg_release,-pkg_version,\
-+    -component,-architecture,\
-+    -analyzer,-count,-duphash,-uuid,-abrt_version,\
-+    -username,-hostname,-os_release,-os_info,\
-+    -time,-pid,-pwd,-last_occurrence,-ureports_counter,\
-+    %reporter,\
-+    %oneline
-+
-+%attach:: -reported_to,-comment,-reason,-event_log,%multiline,\
-+    -coredump,%binary
-diff --git a/src/plugins/mantisbt_formatdup_analyzer_libreport.conf b/src/plugins/mantisbt_formatdup_analyzer_libreport.conf
-new file mode 100644
-index 0000000..d9ab0e3
---- /dev/null
-+++ b/src/plugins/mantisbt_formatdup_analyzer_libreport.conf
-@@ -0,0 +1,56 @@
-+# Lines starting with # are ignored.
-+# Lines can be continued on the next line using trailing backslash.
-+#
-+# Format:
-+# %summary:: summary format
-+# section:: element1[,element2]...
-+# The literal text line to be added to Bugzilla comment. Can be empty.
-+# (IOW: empty lines are NOT ignored!)
-+#
-+# Summary format is a line of text, where %element% is replaced by
-+# text element's content, and [[...%element%...]] block is used only if
-+# %element% exists. [[...]] blocks can nest.
-+#
-+# Sections can be:
-+# - %summary: bug summary format string.
-+# - %attach: a list of elements to attach.
-+# - text, double colon (::) and the list of comma-separated elements.
-+#   Text can be empty (":: elem1, elem2, elem3" works),
-+#   in this case "Text:" header line will be omitted.
-+#
-+# Elements can be:
-+# - problem directory element names, which get formatted as
-+#   <element_name>: <contents>
-+#   or
-+#   <element_name>:
-+#   :<contents>
-+#   :<contents>
-+#   :<contents>
-+# - problem directory element names prefixed by "%bare_",
-+#   which is formatted as-is, without "<element_name>:" and colons
-+# - %oneline, %multiline, %text wildcards, which select all corresponding
-+#   elements for output or attachment
-+# - %binary wildcard, valid only for %attach section, instructs to attach
-+#   binary elements
-+# - problem directory element names prefixed by "-",
-+#   which excludes given element from all wildcards
-+#
-+#   Nonexistent elements are silently ignored.
-+#   If none of elements exists, the section will not be created.
-+
-+Another user experienced a similar problem:
-+
-+# If user filled out comment field, show it:
-+:: %bare_comment
-+
-+# var_log_messages has too much variance (time/date),
-+# we exclude it from message so that dup message elimination has more chances to work
-+:: \
-+    -pkg_arch,-pkg_epoch,-pkg_name,-pkg_release,-pkg_version,\
-+        -component,-architecture,\
-+    -analyzer,-count,-duphash,-uuid,-abrt_version,\
-+    -username,-hostname,-os_release,-os_info,\
-+    -time,-pid,-pwd,-last_occurrence,-ureports_counter,\
-+    -var_log_messages,\
-+    %reporter,\
-+    %oneline
--- 
-1.8.3.1
-
diff --git a/SOURCES/1014-event-disable-report_RHTSupport-event-and-change-URL.patch b/SOURCES/1014-event-disable-report_RHTSupport-event-and-change-URL.patch
deleted file mode 100644
index 3765c62..0000000
--- a/SOURCES/1014-event-disable-report_RHTSupport-event-and-change-URL.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From 93cfff1cd5ca8f418709e4fa0e1b1c9d5b15ddcf Mon Sep 17 00:00:00 2001
-From: Matej Habrnal <mhabrnal@redhat.com>
-Date: Fri, 12 Jun 2015 07:51:50 +0200
-Subject: [PATCH 1014/1015] event: disable report_RHTSupport event and change
- URL for bugzilla
-
-Set the URL for bugzilla to non-exist one because we do not want the centos
-users report to bugzilla.
-
-Signed-off-by: Matej Habrnal <mhabrnal@redhat.com>
----
- src/plugins/bugzilla.conf         | 2 +-
- src/plugins/rhtsupport_event.conf | 4 ++--
- 2 files changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/src/plugins/bugzilla.conf b/src/plugins/bugzilla.conf
-index 51648de..159b188 100644
---- a/src/plugins/bugzilla.conf
-+++ b/src/plugins/bugzilla.conf
-@@ -1,5 +1,5 @@
- # Bugzilla URL
--BugzillaURL = https://bugzilla.redhat.com/
-+BugzillaURL = https://bugzilla.example.com/
- # yes means that ssl certificates will be checked
- SSLVerify = yes
- # your login has to exist, if you don have any, please create one
-diff --git a/src/plugins/rhtsupport_event.conf b/src/plugins/rhtsupport_event.conf
-index f6a9d47..4ccf9f5 100644
---- a/src/plugins/rhtsupport_event.conf
-+++ b/src/plugins/rhtsupport_event.conf
-@@ -1,3 +1,3 @@
--EVENT=report_RHTSupport
-+#EVENT=report_RHTSupport
-     # Submit an uReport and create a case in Red Hat Customer Portal
--    reporter-rhtsupport -u
-+    # reporter-rhtsupport -u
--- 
-1.8.3.1
-
diff --git a/SPECS/libreport.spec b/SPECS/libreport.spec
index d1b71a2..36ade42 100644
--- a/SPECS/libreport.spec
+++ b/SPECS/libreport.spec
@@ -7,7 +7,7 @@
 Summary: Generic library for reporting various problems
 Name: libreport
 Version: 2.1.11
-Release: 35%{?dist}
+Release: 38%{?dist}
 License: GPLv2+
 Group: System Environment/Libraries
 URL: https://fedorahosted.org/abrt/
@@ -237,23 +237,12 @@ Patch209: 0209-lib-problem-report-API-check-fseek-return-code.patch
 Patch210: 0210-RHTSupport-include-count-in-Support-cases.patch
 Patch211: 0211-configure-set-version-to-2.1.11.1.patch
 Patch212: 0212-Translation-updates.patch
+Patch213: 0213-reportclient-honor-ABRT_VERBOSE.patch
+Patch214: 0214-tree-wide-introduce-stop_on_not_reportable-option.patch
+Patch215: 0215-rhtsupport-fix-a-double-free-of-config-at-exit.patch
+Patch216: 0216-reportclient-fix-verbosity-test.patch
+Patch217: 0217-report-newt-free-allocated-variables-don-t-close-dd-.patch
 
-Patch1000: 1000-bugzilla-port-to-Problem-Format-API.patch
-Patch1001: 1001-lib-created-a-new-lib-file-for-reporters.patch
-#Patch1002: 1002-spec-changed-spec-file-to-work-with-last-commit.patch
-Patch1003: 1003-ureport-set-url-to-public-faf-server.patch
-Patch1004: 1004-conf-changed-URL-for-sending-uReport.patch
-Patch1005: 1005-reporter-mantisbt-first-version-of-the-reporter-mant.patch
-#Patch1006: 1006-spec-changed-spec-file-to-work-with-reporter-mantisb.patch
-Patch1007: 1007-reporter-mantisbt-change-default-formating-file-for-.patch
-#Patch1008: 1008-spec-change-spec-file-to-work-with-last-commit.patch
-Patch1009: 1009-reporter-mantisbt-adds-man-pages-for-reporter-mantis.patch
-Patch1010: 1010-move-problem_report-to-plugins.patch
-#Patch1011: 1011-spec-change-related-to-moving-problem_report-to-plug.patch
-Patch1012: 1012-reporter-mantisbt-add-event-for-reporting-AVCs.patch
-#Patch1013: 1013-spec-add-files-related-to-reporting-AVCs-by-reporter.patch
-Patch1014: 1014-event-disable-report_RHTSupport-event-and-change-URL.patch
-#Patch1015: 1015-spec-remove-dependecy-on-redhat-access-insights.patch
 
 # git is need for '%%autosetup -S git' which automatically applies all the
 # patches above. Please, be aware that the patches must be generated
@@ -443,32 +432,12 @@ Uploads micro-report to abrt server
 %description plugin-bugzilla
 Plugin to report bugs into the bugzilla.
 
-%package plugin-mantisbt
-Summary: %{name}'s mantisbt plugin
-Group: System Environment/Libraries
-Requires: %{name} = %{version}-%{release}
-Requires: libreport-web = %{version}-%{release}
-
-%description plugin-mantisbt
-Plugin to report bugs into the mantisbt.
-
-%package centos
-Summary: %{name}'s CentOS Bug Tracker workflow
-Group: System Environment/Libraries
-Requires: %{name} = %{version}-%{release}
-Requires: libreport-web = %{version}-%{release}
-Requires: libreport-plugin-mantisbt = %{version}-%{release}
-
-%description centos
-Workflows to report issues into the CentOS Bug Tracker.
-
 %package plugin-rhtsupport
 Summary: %{name}'s RHTSupport plugin
 Group: System Environment/Libraries
 Requires: %{name} = %{version}-%{release}
 Requires: libreport-web = %{version}-%{release}
-# This feature is only for RHEL so we do not need another dependency
-# Requires: redhat-access-insights
+Requires: redhat-access-insights
 
 %description plugin-rhtsupport
 Plugin to report bugs into RH support system.
@@ -701,6 +670,7 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
 %{_includedir}/libreport/dump_dir.h
 %{_includedir}/libreport/event_config.h
 %{_includedir}/libreport/problem_data.h
+%{_includedir}/libreport/problem_report.h
 %{_includedir}/libreport/report.h
 %{_includedir}/libreport/run_event.h
 %{_includedir}/libreport/file_obj.h
@@ -708,7 +678,6 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
 %{_includedir}/libreport/workflow.h
 %{_includedir}/libreport/ureport.h
 %{_includedir}/libreport/global_configuration.h
-%{_includedir}/libreport/reporters.h
 # Private api headers:
 %{_includedir}/libreport/internal_abrt_dbus.h
 %{_includedir}/libreport/internal_libreport.h
@@ -828,40 +797,6 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
 %{_mandir}/man5/bugzilla_format_kernel.conf.5.*
 %{_bindir}/reporter-bugzilla
 
-%files plugin-mantisbt
-%defattr(-,root,root,-)
-%config(noreplace) %{_sysconfdir}/libreport/plugins/mantisbt.conf
-%{_datadir}/%{name}/conf.d/plugins/mantisbt.conf
-%config(noreplace) %{_sysconfdir}/libreport/plugins/mantisbt_format.conf
-%config(noreplace) %{_sysconfdir}/libreport/plugins/mantisbt_formatdup.conf
-%config(noreplace) %{_sysconfdir}/libreport/plugins/mantisbt_format_analyzer_libreport.conf
-%config(noreplace) %{_sysconfdir}/libreport/plugins/mantisbt_formatdup_analyzer_libreport.conf
-%{_bindir}/reporter-mantisbt
-%{_mandir}/man1/reporter-mantisbt.1.gz
-%{_mandir}/man5/mantisbt.conf.5.*
-%{_mandir}/man5/mantisbt_format.conf.5.*
-%{_mandir}/man5/mantisbt_formatdup.conf.5.*
-%{_mandir}/man5/mantisbt_format_analyzer_libreport.conf.5.*
-%{_mandir}/man5/mantisbt_formatdup_analyzer_libreport.conf.5.*
-
-%files centos
-%{_datadir}/%{name}/workflows/workflow_CentOSCCpp.xml
-%{_datadir}/%{name}/workflows/workflow_CentOSKerneloops.xml
-%{_datadir}/%{name}/workflows/workflow_CentOSPython.xml
-%{_datadir}/%{name}/workflows/workflow_CentOSPython3.xml
-%{_datadir}/%{name}/workflows/workflow_CentOSVmcore.xml
-%{_datadir}/%{name}/workflows/workflow_CentOSXorg.xml
-%{_datadir}/%{name}/workflows/workflow_CentOSLibreport.xml
-%{_datadir}/%{name}/workflows/workflow_CentOSJava.xml
-%config(noreplace) %{_sysconfdir}/libreport/workflows.d/report_centos.conf
-%{_mandir}/man5/report_centos.conf.5.*
-%{_datadir}/%{name}/events/report_CentOSBugTracker.xml
-%config(noreplace) %{_sysconfdir}/libreport/events/report_CentOSBugTracker.conf
-%{_mandir}/man5/report_CentOSBugTracker.conf.5.*
-# report_CentOSBugTracker events are shipped by libreport package
-%config(noreplace) %{_sysconfdir}/libreport/events.d/centos_report_event.conf
-%{_mandir}/man5/centos_report_event.conf.5.gz
-
 %files plugin-rhtsupport
 %defattr(-,root,root,-)
 %config(noreplace) %{_sysconfdir}/libreport/plugins/rhtsupport.conf
@@ -963,7 +898,19 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
 
 
 %changelog
-* Thu Sep  1 2016 Matej Habrnal <mhabrnal@redhat.com> - 2.1.11-35.el7.centos
+* Tue Feb 21 2017 Matej Habrnal <mhabrnal@redhat.com> - 2.1.11-38
+- free allocated variables, don't close dd twice
+- Related: #1257159
+
+* Thu Feb  9 2017 Matej Habrnal <mhabrnal@redhat.com> - 2.1.11-37
+- rebuild
+
+* Wed Feb  8 2017 Matej Habrnal <mhabrnal@redhat.com> - 2.1.11-36
+- introduce 'stop_on_not_reportable' option
+- fix a double free of config at exit in reporter-rhtsupport
+- Related: #1373094, #1257159
+
+* Thu Sep  1 2016 Matej Habrnal <mhabrnal@redhat.com> - 2.1.11-35
 - Translation updates
 - Related: #1304240