>From 01da737d76a5f12aeca333d3fbbd517670ea68cd Mon Sep 17 00:00:00 2001
From: Karel Klic <kklic@redhat.com>
Date: Thu, 23 Sep 2010 15:27:46 +0200
Subject: [PATCH 1/2] Remove the embedded backtrace parser.

---
 .gitignore                   |    5 -
 abrt.spec                    |    2 -
 configure.ac                 |   10 -
 lib/utils/Makefile.am        |    4 -
 lib/utils/backtrace.c        |  846 ------------------------------------------
 lib/utils/backtrace.h        |  152 --------
 lib/utils/backtrace_parser.y |  684 ----------------------------------
 scripts/abrt-bz-downloader   |   82 ----
 scripts/abrt-bz-dupchecker   |  281 --------------
 scripts/abrt-bz-hashchecker  |   59 ---
 scripts/abrt-bz-ratingfixer  |  210 -----------
 scripts/abrt-bz-stats        |  313 ----------------
 scripts/check-bt-parsability |   20 -
 src/Makefile.am              |    2 +-
 src/utils/Makefile.am        |   11 -
 src/utils/abrt-backtrace.1   |   59 ---
 src/utils/abrt-backtrace.c   |  339 -----------------
 17 files changed, 1 insertions(+), 3078 deletions(-)
 delete mode 100644 lib/utils/backtrace.c
 delete mode 100644 lib/utils/backtrace.h
 delete mode 100644 lib/utils/backtrace_parser.y
 delete mode 100755 scripts/abrt-bz-downloader
 delete mode 100755 scripts/abrt-bz-dupchecker
 delete mode 100755 scripts/abrt-bz-hashchecker
 delete mode 100755 scripts/abrt-bz-ratingfixer
 delete mode 100755 scripts/abrt-bz-stats
 delete mode 100755 scripts/check-bt-parsability
 delete mode 100644 src/utils/Makefile.am
 delete mode 100644 src/utils/abrt-backtrace.1
 delete mode 100644 src/utils/abrt-backtrace.c

diff --git a/.gitignore b/.gitignore
index b621b33..5146909 100644
--- a/.gitignore
+++ b/.gitignore
@@ -46,19 +46,14 @@ po/remove-potcdate.sin
 po/stamp-po
 po/stamp-it
 py-compile
-scripts/*.bt
 src/applet/abrt-applet
 src/applet/abrt-applet.desktop
 src/cli/abrt-cli
-src/utils/abrt-backtrace
-lib/utils/backtrace_parser.c
-lib/utils/backtrace_parser.output
 src/daemon/abrtd
 src/gui/abrt.desktop
 src/hooks/abrt_exception_handler.py
 src/hooks/dumpoops
 src/hooks/abrt-hook-ccpp
-scripts/abrt-rate-backtrace
 stamp-h1
 x86_64/
 *.pyc
diff --git a/abrt.spec b/abrt.spec
index 28e02eb..980f76e 100644
--- a/abrt.spec
+++ b/abrt.spec
@@ -353,7 +353,6 @@ fi
 %{_sbindir}/abrt-action-save-package-data
 %{_bindir}/%{name}-debuginfo-install
 %{_bindir}/%{name}-handle-upload
-%{_bindir}/%{name}-backtrace
 %config(noreplace) %{_sysconfdir}/%{name}/%{name}.conf
 %config(noreplace) %{_sysconfdir}/%{name}/gpg_keys
 %config(noreplace) %{_sysconfdir}/dbus-1/system.d/dbus-%{name}.conf
@@ -366,7 +365,6 @@ fi
 %dir %{_sysconfdir}/%{name}
 %dir %{_sysconfdir}/%{name}/plugins
 %dir %{_libdir}/%{name}
-%{_mandir}/man1/%{name}-backtrace.1.gz
 %{_mandir}/man8/abrtd.8.gz
 %{_mandir}/man5/%{name}.conf.5.gz
 #%{_mandir}/man5/pyhook.conf.5.gz
diff --git a/configure.ac b/configure.ac
index 3736399..db86865 100644
--- a/configure.ac
+++ b/configure.ac
@@ -18,15 +18,6 @@ CXXFLAGS="$CXXFLAGS -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE \
 CFLAGS="$CFLAGS -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE \
           -D_FILE_OFFSET_BITS=64 -fno-strict-aliasing -std=gnu99 -Wall"
 
-AC_CHECK_PROGS(YACC, 'bison -y', [no])
-[if test "$YACC" = "no"]
-[then]
-    [echo "bison not found in the search path. Please ensure that it is"]
-    [echo "installed and its directory is included in the search path."]
-    [echo "Then run configure again before attempting to build ABRT."]
-    [exit 1]
-[fi]
-
 dnl ****** INTERNATIONALIZATION **********************
 GETTEXT_PACKAGE=abrt
 AC_SUBST(GETTEXT_PACKAGE)
@@ -127,7 +118,6 @@ AC_CONFIG_FILES([
 	src/applet/Makefile
 	src/gui/Makefile
 	src/cli/Makefile
-	src/utils/Makefile
 	inc/Makefile
 	po/Makefile.in
 	icons/Makefile
diff --git a/lib/utils/Makefile.am b/lib/utils/Makefile.am
index 1e10482..0e9460d 100644
--- a/lib/utils/Makefile.am
+++ b/lib/utils/Makefile.am
@@ -3,7 +3,6 @@
 lib_LTLIBRARIES = libABRTUtils.la libABRTdUtils.la
 HEADER_DIR = $(srcdir)/../../inc
 AM_CPPFLAGS = -I$(HEADER_DIR)
-AM_YFLAGS = --verbose
 
 # Not used just yet:
 # time.cpp
@@ -27,8 +26,6 @@ libABRTUtils_la_SOURCES = \
     abrt_dbus.c abrt_dbus.h \
     CrashTypes.cpp \
     ABRTException.cpp \
-    backtrace.c backtrace.h \
-    backtrace_parser.y \
     strbuf.c strbuf.h \
     abrt_packages.c abrt_packages.h \
     hooklib.c hooklib.h \
@@ -52,7 +49,6 @@ libABRTUtils_la_LIBADD = \
     $(DBUS_LIBS) \
     -ldl
 
-
 libABRTdUtils_la_SOURCES = \
     parse_release.cpp \
     make_descr.cpp \
diff --git a/lib/utils/backtrace.c b/lib/utils/backtrace.c
deleted file mode 100644
index f507cba..0000000
--- a/lib/utils/backtrace.c
+++ /dev/null
@@ -1,846 +0,0 @@
-/*
-    Copyright (C) 2009  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 <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include "backtrace.h"
-#include "strbuf.h"
-#include "xfuncs.h"
-
-struct frame *frame_new()
-{
-  struct frame *f = malloc(sizeof(struct frame));
-  if (!f)
-  {
-    puts("Error while allocating memory for backtrace frame.");
-    exit(5);
-  }
-
-  f->function = NULL;
-  f->number = 0;
-  f->sourcefile = NULL;
-  f->signal_handler_called = false;
-  f->next = NULL;
-  return f;
-}
-
-void frame_free(struct frame *f)
-{
-  if (f->function)
-    free(f->function);
-  if (f->sourcefile)
-    free(f->sourcefile);
-  free(f);
-}
-
-struct frame *frame_add_sibling(struct frame *a, struct frame *b)
-{
-  struct frame *aa = a;
-  while (aa->next)
-    aa = aa->next;
-
-  aa->next = b;
-  return a;
-}
-
-/* Appends a string representation of 'frame' to the 'str'. */
-static void frame_append_str(struct frame *frame, struct strbuf *str, bool verbose)
-{
-    if (verbose)
-        strbuf_append_strf(str, " #%d", frame->number);
-    else
-        strbuf_append_str(str, " ");
-
-    if (frame->function)
-        strbuf_append_strf(str, " %s", frame->function);
-    if (verbose && frame->sourcefile)
-    {
-        if (frame->function)
-            strbuf_append_str(str, " at");
-        strbuf_append_strf(str, " %s", frame->sourcefile);
-    }
-
-    if (frame->signal_handler_called)
-        strbuf_append_str(str, " <signal handler called>");
-
-    strbuf_append_str(str, "\n");
-}
-
-static bool frame_is_exit_handler(struct frame *frame)
-{
-  return (frame->function
-	  && frame->sourcefile
-	  && 0 == strcmp(frame->function, "__run_exit_handlers")
-	  && NULL != strstr(frame->sourcefile, "exit.c"));
-}
-
-/* Checks if a frame contains abort function used
- * by operating system to exit application.
- * E.g. in C it's called "abort" or "raise".
- */
-static bool frame_is_abort_frame(struct frame *frame)
-{
-  if (!frame->function || !frame->sourcefile)
-    return false;
-
-  if (0 == strcmp(frame->function, "raise")
-      && (NULL != strstr(frame->sourcefile, "pt-raise.c")
-          || NULL != strstr(frame->sourcefile, "/libc.so.6")))
-    return true;
-  else if (0 == strcmp(frame->function, "exit")
-           && NULL != strstr(frame->sourcefile, "exit.c"))
-    return true;
-  else if (0 == strcmp(frame->function, "abort")
-           && (NULL != strstr(frame->sourcefile, "abort.c")
-               || NULL != strstr(frame->sourcefile, "/libc.so.6")))
-    return true;
-  else if (frame_is_exit_handler(frame))
-    return true;
-
-  return false;
-}
-
-static bool frame_is_noncrash_frame(struct frame *frame)
-{
-  /* Abort frames. */
-  if (frame_is_abort_frame(frame))
-    return true;
-
-  if (!frame->function)
-    return false;
-
-  if (0 == strcmp(frame->function, "__kernel_vsyscall"))
-    return true;
-
-  if (0 == strcmp(frame->function, "__assert_fail"))
-    return true;
-
-  if (!frame->sourcefile)
-    return false;
-
-  /* GDK */
-  if (0 == strcmp(frame->function, "gdk_x_error")
-      && 0 == strcmp(frame->sourcefile, "gdkmain-x11.c"))
-    return true;
-
-  /* X.org */
-  if (0 == strcmp(frame->function, "_XReply")
-      && 0 == strcmp(frame->sourcefile, "xcb_io.c"))
-    return true;
-  if (0 == strcmp(frame->function, "_XError")
-      && 0 == strcmp(frame->sourcefile, "XlibInt.c"))
-    return true;
-  if (0 == strcmp(frame->function, "XSync")
-      && 0 == strcmp(frame->sourcefile, "Sync.c"))
-    return true;
-  if (0 == strcmp(frame->function, "process_responses")
-      && 0 == strcmp(frame->sourcefile, "xcb_io.c"))
-    return true;
-
-  /* glib */
-  if (0 == strcmp(frame->function, "IA__g_log")
-      && 0 == strcmp(frame->sourcefile, "gmessages.c"))
-    return true;
-  if (0 == strcmp(frame->function, "IA__g_logv")
-      && 0 == strcmp(frame->sourcefile, "gmessages.c"))
-    return true;
-  if (0 == strcmp(frame->function, "IA__g_assertion_message")
-      && 0 == strcmp(frame->sourcefile, "gtestutils.c"))
-    return true;
-  if (0 == strcmp(frame->function, "IA__g_assertion_message_expr")
-      && 0 == strcmp(frame->sourcefile, "gtestutils.c"))
-    return true;
-
-  /* DBus */
-  if (0 == strcmp(frame->function, "gerror_to_dbus_error_message")
-      && 0 == strcmp(frame->sourcefile, "dbus-gobject.c"))
-    return true;
-  if (0 == strcmp(frame->function, "dbus_g_method_return_error")
-      && 0 == strcmp(frame->sourcefile, "dbus-gobject.c"))
-    return true;
-
-  /* libstdc++ */
-  if (0 == strcmp(frame->function, "__gnu_cxx::__verbose_terminate_handler")
-      && NULL != strstr(frame->sourcefile, "/vterminate.cc"))
-    return true;
-  if (0 == strcmp(frame->function, "__cxxabiv1::__terminate")
-      && NULL != strstr(frame->sourcefile, "/eh_terminate.cc"))
-    return true;
-  if (0 == strcmp(frame->function, "std::terminate")
-      && NULL != strstr(frame->sourcefile, "/eh_terminate.cc"))
-    return true;
-  if (0 == strcmp(frame->function, "__cxxabiv1::__cxa_throw")
-      && NULL != strstr(frame->sourcefile, "/eh_throw.cc"))
-    return true;
-
-  return false;
-}
-
-struct thread *thread_new()
-{
-  struct thread *t = malloc(sizeof(struct thread));
-  if (!t)
-  {
-    puts("Error while allocating memory for backtrace thread.");
-    exit(5);
-  }
-
-  t->number = 0;
-  t->frames = NULL;
-  t->next = NULL;
-  return t;
-}
-
-void thread_free(struct thread *t)
-{
-  while (t->frames)
-  {
-    struct frame *rm = t->frames;
-    t->frames = rm->next;
-    frame_free(rm);
-  }
-
-  free(t);
-}
-
-struct thread *thread_add_sibling(struct thread *a, struct thread *b)
-{
-  struct thread *aa = a;
-  while (aa->next)
-    aa = aa->next;
-
-  aa->next = b;
-  return a;
-}
-
-static int thread_get_frame_count(struct thread *thread)
-{
-  struct frame *f = thread->frames;
-  int count = 0;
-  while (f)
-  {
-    f = f->next;
-    ++count;
-  }
-  return count;
-}
-
-/* Appends string representation of 'thread' to the 'str'. */
-static void thread_append_str(struct thread *thread, struct strbuf *str, bool verbose)
-{
-    int framecount = thread_get_frame_count(thread);
-    if (verbose)
-        strbuf_append_strf(str, "Thread no. %d (%d frames)\n", thread->number, framecount);
-    else
-        strbuf_append_str(str, "Thread\n");
-    struct frame *frame = thread->frames;
-    while (frame)
-    {
-        frame_append_str(frame, str, verbose);
-        frame = frame->next;
-    }
-}
-
-/*
- * Checks whether the thread it contains some known "abort" function.
- * If a frame with the function is found, it is returned.
- * If there are multiple frames with abort function, the lowest
- * one is returned.
- * Nonrecursive.
- */
-struct frame *thread_find_abort_frame(struct thread *thread)
-{
-  struct frame *frame = thread->frames;
-  struct frame *result = NULL;
-  while (frame)
-  {
-    if (frame_is_abort_frame(frame))
-      result = frame;
-
-    frame = frame->next;
-  }
-
-  return result;
-}
-
-static void thread_remove_exit_handlers(struct thread *thread)
-{
-  struct frame *frame = thread->frames;
-  while (frame)
-  {
-    if (frame_is_exit_handler(frame))
-    {
-      /* Delete all frames from the beginning to this frame. */
-      while (thread->frames != frame)
-      {
-        struct frame *rm = thread->frames;
-        thread->frames = thread->frames->next;
-        frame_free(rm);
-      }
-      return;
-    }
-
-    frame = frame->next;
-  }
-}
-
-static void thread_remove_noncrash_frames(struct thread *thread)
-{
-  struct frame *prev = NULL;
-  struct frame *cur = thread->frames;
-  while (cur)
-  {
-    if (frame_is_noncrash_frame(cur))
-    {
-      /* This frame must be skipped, because it will
-         be deleted. */
-      if (prev)
-	prev->next = cur->next;
-      else
-	thread->frames = cur->next;
-
-      frame_free(cur);
-
-      /* Set cur to be valid, as it will be used to
-         advance to next item. */
-      if (prev)
-	cur = prev;
-      else
-      {
-	cur = thread->frames;
-        continue;
-      }
-    }
-
-    prev = cur;
-    cur = cur->next;
-  }
-}
-
-/* Counts the number of quality frames and the number of all frames
- * in a thread.
- * @param ok_count
- * @param all_count
- *   Not zeroed. This function just adds the numbers to
- *   ok_count and all_count.
- */
-static void thread_rating(struct thread *thread, int *ok_count, int *all_count)
-{
-    struct frame *frame = thread->frames;
-    while (frame)
-    {
-        *all_count += 1;
-        if (frame->signal_handler_called ||
-            (frame->function && 0 != strcmp(frame->function, "??")))
-        {
-            *ok_count += 1;
-        }
-        frame = frame->next;
-    }
-}
-
-struct backtrace *backtrace_new()
-{
-  struct backtrace *bt = malloc(sizeof(struct backtrace));
-  if (!bt)
-  {
-    puts("Error while allocating memory for backtrace.");
-    exit(5);
-  }
-
-  bt->threads = NULL;
-  bt->crash = NULL;
-  return bt;
-}
-
-void backtrace_free(struct backtrace *bt)
-{
-  while (bt->threads)
-  {
-    struct thread *rm = bt->threads;
-    bt->threads = rm->next;
-    thread_free(rm);
-  }
-
-  if (bt->crash)
-    frame_free(bt->crash);
-
-  free(bt);
-}
-
-static int backtrace_get_thread_count(struct backtrace *bt)
-{
-  struct thread *t = bt->threads;
-  int count = 0;
-  while (t)
-  {
-    t = t->next;
-    ++count;
-  }
-  return count;
-}
-
-void backtrace_print_tree(struct backtrace *backtrace, bool verbose)
-{
-    struct strbuf *strbuf = backtrace_tree_as_str(backtrace, verbose);
-    puts(strbuf->buf);
-    strbuf_free(strbuf);
-}
-
-struct strbuf *backtrace_tree_as_str(struct backtrace *backtrace, bool verbose)
-{
-    struct strbuf *str = strbuf_new();
-    if (verbose)
-        strbuf_append_strf(str, "Thread count: %d\n", backtrace_get_thread_count(backtrace));
-
-    if (backtrace->crash && verbose)
-    {
-        strbuf_append_str(str, "Crash frame: ");
-        frame_append_str(backtrace->crash, str, verbose);
-    }
-
-    struct thread *thread = backtrace->threads;
-    while (thread)
-    {
-        thread_append_str(thread, str, verbose);
-        thread = thread->next;
-    }
-
-    return str;
-}
-
-void backtrace_remove_threads_except_one(struct backtrace *backtrace,
-					 struct thread *one)
-{
-  while (backtrace->threads)
-  {
-    struct thread *rm = backtrace->threads;
-    backtrace->threads = rm->next;
-    if (rm != one)
-      thread_free(rm);
-  }
-
-  one->next = NULL;
-  backtrace->threads = one;
-}
-
-/*
- * Loop through all threads and if a single one contains the crash frame on the top,
- * return it. Otherwise, return NULL.
- *
- * If require_abort is true, it is also required that the thread containing
- * the crash frame contains some known "abort" function. In this case there can be
- * multiple threads with the crash frame on the top, but only one of them might
- * contain the abort function to succeed.
- */
-static struct thread *backtrace_find_crash_thread_from_crash_frame(struct backtrace *backtrace,
-								   bool require_abort)
-{
-  /*
-   * This code can be extended to compare something else when the function
-   * name is not available.
-   */
-  if (!backtrace->threads || !backtrace->crash || !backtrace->crash->function)
-    return NULL;
-
-  struct thread *result = NULL;
-  struct thread *thread = backtrace->threads;
-  while (thread)
-  {
-    if (thread->frames
-	&& thread->frames->function
-	&& 0 == strcmp(thread->frames->function, backtrace->crash->function)
-        && (!require_abort || thread_find_abort_frame(thread)))
-    {
-      if (result == NULL)
-	result = thread;
-      else
-      {
-	/* Second frame with the same function. Failure. */
-	return NULL;
-      }
-    }
-
-    thread = thread->next;
-  }
-
-  return result;
-}
-
-struct thread *backtrace_find_crash_thread(struct backtrace *backtrace)
-{
-  /* If there is no thread, be silent and report NULL. */
-  if (!backtrace->threads)
-    return NULL;
-
-  /* If there is just one thread, it is simple. */
-  if (!backtrace->threads->next)
-    return backtrace->threads;
-
-  /* If we have a crash frame *and* there is just one thread which has
-   * this frame on the top, it is also simple.
-   */
-  struct thread *thread;
-  thread = backtrace_find_crash_thread_from_crash_frame(backtrace, false);
-  if (thread)
-    return thread;
-
-  /* There are multiple threads with a frame indistinguishable from
-   * the crash frame on the top of stack.
-   * Try to search for known abort functions.
-   */
-  thread = backtrace_find_crash_thread_from_crash_frame(backtrace, true);
-
-  return thread; /* result or null */
-}
-
-void backtrace_limit_frame_depth(struct backtrace *backtrace, int depth)
-{
-  if (depth <= 0)
-    return;
-
-  struct thread *thread = backtrace->threads;
-  while (thread)
-  {
-    struct frame *frame = thread_find_abort_frame(thread);
-    if (frame)
-      frame = frame->next; /* Start counting from the frame following the abort fr. */
-    else
-      frame = thread->frames; /* Start counting from the first frame. */
-
-    /* Skip some frames to get the required stack depth. */
-    int i = depth;
-    struct frame *last_frame = NULL;
-    while (frame && i)
-    {
-      last_frame = frame;
-      frame = frame->next;
-      --i;
-    }
-
-    /* Delete the remaining frames. */
-    if (last_frame)
-      last_frame->next = NULL;
-
-    while (frame)
-    {
-      struct frame *rm = frame;
-      frame = frame->next;
-      frame_free(rm);
-    }
-
-    thread = thread->next;
-  }
-}
-
-void backtrace_remove_exit_handlers(struct backtrace *backtrace)
-{
-  struct thread *thread = backtrace->threads;
-  while (thread)
-  {
-    thread_remove_exit_handlers(thread);
-    thread = thread->next;
-  }
-}
-
-void backtrace_remove_noncrash_frames(struct backtrace *backtrace)
-{
-  struct thread *thread = backtrace->threads;
-  while (thread)
-  {
-    thread_remove_noncrash_frames(thread);
-    thread = thread->next;
-  }
-}
-
-/* Belongs to independent_backtrace(). */
-struct header
-{
-  struct strbuf *text;
-  struct header *next;
-};
-
-/* Belongs to independent_backtrace(). */
-static struct header *header_new()
-{
-  struct header *head = malloc(sizeof(struct header));
-  if (!head)
-  {
-    puts("Error while allocating memory for backtrace header.");
-    exit(5);
-  }
-  head->text = NULL;
-  head->next = NULL;
-  return head;
-}
-
-/* Recursively frees siblings. */
-/* Belongs to independent_backtrace(). */
-static void header_free(struct header *head)
-{
-  if (head->text)
-    strbuf_free(head->text);
-  if (head->next)
-    header_free(head->next);
-  free(head);
-}
-
-/* Inserts new header to array if it is not already there. */
-/* Belongs to independent_backtrace(). */
-static void header_set_insert(struct header *cur, struct strbuf *new)
-{
-  /* Duplicate found case. */
-  if (strcmp(cur->text->buf, new->buf) == 0)
-    return;
-
-  /* Last item case, insert new header here. */
-  if (cur->next == NULL)
-  {
-    cur->next = header_new();
-    cur->next->text = new;
-    return;
-  }
-
-  /* Move to next item in array case. */
-  header_set_insert(cur->next, new);
-}
-
-struct strbuf *independent_backtrace(const char *input)
-{
-  struct strbuf *header = strbuf_new();
-  bool in_bracket = false;
-  bool in_quote = false;
-  bool in_header = false;
-  bool in_digit = false;
-  bool has_at = false;
-  bool has_filename = false;
-  bool has_bracket = false;
-  struct header *headers = NULL;
-
-  const char *bk = input;
-  while (*bk)
-  {
-    if (bk[0] == '#'
-	&& bk[1] >= '0' && bk[1] <= '7'
-	&& bk[2] == ' ' /* take only #0...#7 (8 last stack frames) */
-	&& !in_quote)
-    {
-      if (in_header && !has_filename)
-	strbuf_clear(header);
-      in_header = true;
-    }
-
-    if (!in_header)
-    {
-      ++bk;
-      continue;
-    }
-
-    if (isdigit(*bk) && !in_quote && !has_at)
-      in_digit = true;
-    else if (bk[0] == '\\' && bk[1] == '\"')
-      bk++;
-    else if (*bk == '\"')
-      in_quote = in_quote == true ? false : true;
-    else if (*bk == '(' && !in_quote)
-    {
-      in_bracket = true;
-      in_digit = false;
-      strbuf_append_char(header, '(');
-    }
-    else if (*bk == ')' && !in_quote)
-    {
-      in_bracket = false;
-      has_bracket = true;
-      in_digit = false;
-      strbuf_append_char(header, '(');
-    }
-    else if (*bk == '\n' && has_filename)
-    {
-      if (headers == NULL)
-      {
-	headers = header_new();
-	headers->text = header;
-      }
-      else
-	header_set_insert(headers, header);
-
-      header = strbuf_new();
-      in_bracket = false;
-      in_quote = false;
-      in_header = false;
-      in_digit = false;
-      has_at = false;
-      has_filename = false;
-      has_bracket = false;
-    }
-    else if (*bk == ',' && !in_quote)
-      in_digit = false;
-    else if (isspace(*bk) && !in_quote)
-      in_digit = false;
-    else if (bk[0] == 'a' && bk[1] == 't' && has_bracket && !in_quote)
-    {
-      has_at = true;
-      strbuf_append_char(header, 'a');
-    }
-    else if (bk[0] == ':' && has_at && isdigit(bk[1]) && !in_quote)
-      has_filename = true;
-    else if (in_header && !in_digit && !in_quote && !in_bracket)
-      strbuf_append_char(header, *bk);
-
-    bk++;
-  }
-
-  strbuf_free(header);
-
-  struct strbuf *result = strbuf_new();
-  struct header *loop = headers;
-  while (loop)
-  {
-    strbuf_append_str(result, loop->text->buf);
-    strbuf_append_char(result, '\n');
-    loop = loop->next;
-  }
-
-  if (headers)
-    header_free(headers); /* recursive */
-
-  return result;
-}
-
-/* Belongs to backtrace_rate_old(). */
-enum line_rating
-{
-    // RATING              EXAMPLE
-    MissingEverything = 0, // #0 0x0000dead in ?? ()
-    MissingFunction   = 1, // #0 0x0000dead in ?? () from /usr/lib/libfoobar.so.4
-    MissingLibrary    = 2, // #0 0x0000dead in foobar()
-    MissingSourceFile = 3, // #0 0x0000dead in FooBar::FooBar () from /usr/lib/libfoobar.so.4
-    Good              = 4, // #0 0x0000dead in FooBar::crash (this=0x0) at /home/user/foobar.cpp:204
-    BestRating = Good,
-};
-
-/* Belongs to backtrace_rate_old(). */
-static enum line_rating rate_line(const char *line)
-{
-#define FOUND(x) (strstr(line, x) != NULL)
-    /* see the comments at enum line_rating for possible combinations */
-    if (FOUND(" at "))
-        return Good;
-    const char *function = strstr(line, " in ");
-    if (function && function[4] == '?') /* " in ??" does not count */
-        function = NULL;
-    bool library = FOUND(" from ");
-    if (function && library)
-        return MissingSourceFile;
-    if (function)
-        return MissingLibrary;
-    if (library)
-        return MissingFunction;
-
-    return MissingEverything;
-#undef FOUND
-}
-
-/* just a fallback function, to be removed one day */
-int backtrace_rate_old(const char *backtrace)
-{
-    int i, len;
-    int multiplier = 0;
-    int rating = 0;
-    int best_possible_rating = 0;
-    char last_lvl = 0;
-
-    /* We look at the frames in reversed order, since:
-     * - rate_line() checks starting from the first line of the frame
-     * (note: it may need to look at more than one line!)
-     * - we increase weight (multiplier) for every frame,
-     *   so that topmost frames end up most important
-     */
-    len = 0;
-    for (i = strlen(backtrace) - 1; i >= 0; i--)
-    {
-        if (backtrace[i] == '#'
-            && (backtrace[i+1] >= '0' && backtrace[i+1] <= '9') /* #N */
-            && (i == 0 || backtrace[i-1] == '\n')) /* it's at line start */
-        {
-            /* For one, "#0 xxx" always repeats, skip repeats */
-            if (backtrace[i+1] == last_lvl)
-                continue;
-            last_lvl = backtrace[i+1];
-
-            char *s = xstrndup(backtrace + i + 1, len);
-            /* Replace tabs with spaces, rate_line() does not expect tabs.
-             * Actually, even newlines may be there. Example of multiline frame
-             * where " at SRCFILE" is on 2nd line:
-             * #3  0x0040b35d in __libc_message (do_abort=<value optimized out>,
-             *     fmt=<value optimized out>) at ../sysdeps/unix/sysv/linux/libc_fatal.c:186
-             */
-            char *p;
-            for (p = s; *p; p++)
-            {
-                if (*p == '\t' || *p == '\n')
-                    *p = ' ';
-            }
-            int lrate = rate_line(s);
-            multiplier++;
-            rating += lrate * multiplier;
-            best_possible_rating += BestRating * multiplier;
-            //log("lrate:%d rating:%d best_possible_rating:%d s:'%-.40s'",
-            //    lrate, rating, best_possible_rating, s);
-            free(s);
-            len = 0; /* starting new line */
-        }
-        else
-        {
-            len++;
-        }
-    }
-
-    /* Bogus 'backtrace' with zero frames? */
-    if (best_possible_rating == 0)
-        return 0;
-
-    /* Returning number of "stars" to show */
-    if (rating*10 >= best_possible_rating*8) /* >= 0.8 */
-        return 4;
-    if (rating*10 >= best_possible_rating*6)
-        return 3;
-    if (rating*10 >= best_possible_rating*4)
-        return 2;
-    if (rating*10 >= best_possible_rating*2)
-        return 1;
-
-    return 0;
-}
-
-float backtrace_quality(struct backtrace *backtrace)
-{
-    int ok_count = 0;
-    int all_count = 0;
-    struct thread *thread = backtrace->threads;
-    while (thread)
-    {
-        thread_rating(thread, &ok_count, &all_count);
-        thread = thread->next;
-    }
-
-    if (all_count == 0)
-        return 0;
-    return ok_count / (float)all_count;
-}
diff --git a/lib/utils/backtrace.h b/lib/utils/backtrace.h
deleted file mode 100644
index df5def5..0000000
--- a/lib/utils/backtrace.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
-    Backtrace parsing and processing.
-
-    If we transform analyzer plugins to separate applications one day,
-    this functionality should be moved to CCpp analyzer, which will
-    then easily provide what abrt-backtrace utility provides now. Currently
-    the code is used by abrt-backtrace, so it is shared in the utils
-    library.
-
-    Copyright (C) 2009, 2010  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 BACKTRACE_H
-#define BACKTRACE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdio.h>
-#include <stdbool.h>
-
-struct frame
-{
-  /* Function name, or NULL. */
-  char *function;
-  /* Frame number. */
-  int number;
-  /* Name of the source file, or binary file, or NULL. */
-  char *sourcefile;
-  bool signal_handler_called;
-  /* Sibling frame, or NULL if this is the last frame in a thread. */
-  struct frame *next;
-};
-
-struct thread
-{
-  int number;
-  struct frame *frames;
-  /* Sibling thread, or NULL if this is the last thread in a backtrace. */
-  struct thread *next;
-};
-
-struct backtrace
-{
-  struct thread *threads;
-  /*
-   * The frame where the crash happened according to GDB.
-   * It might be that we can not tell to which thread this frame belongs,
-   * because all threads end with mutually indistinguishable frames.
-   */
-  struct frame *crash;
-};
-
-extern struct frame *frame_new();
-extern void frame_free(struct frame *f);
-extern struct frame *frame_add_sibling(struct frame *a, struct frame *b);
-
-extern struct thread *thread_new();
-extern void thread_free(struct thread *t);
-extern struct thread *thread_add_sibling(struct thread *a, struct thread *b);
-extern struct frame *thread_find_abort_frame(struct thread *thread);
-
-extern struct backtrace *backtrace_new();
-extern void backtrace_free(struct backtrace *bt);
-
-/* Prints how internal backtrace representation looks to stdout. */
-extern void backtrace_print_tree(struct backtrace *backtrace, bool verbose);
-
-/* Returns the backtrace tree string representation. */
-extern struct strbuf *backtrace_tree_as_str(struct backtrace *backtrace, bool verbose);
-
-/*
- * Frees all threads except the one provided as parameters.
- * It does not check whether one is a member of backtrace.
- * Caller must know that.
- */
-extern void backtrace_remove_threads_except_one(struct backtrace *backtrace,
-						struct thread *one);
-
-/*
- * Search all threads and tries to find the one that caused the crash.
- * It might return NULL if the thread cannot be determined.
- */
-extern struct thread *backtrace_find_crash_thread(struct backtrace *backtrace);
-
-extern void backtrace_limit_frame_depth(struct backtrace *backtrace, int depth);
-
-/*
- * Exit handlers are all stack frames above  __run_exit_handlers()
- */
-extern void backtrace_remove_exit_handlers(struct backtrace *backtrace);
-
-/*
- * Removes frames known as not causing crash, but that are often
- * a part of a backtrace.
- */
-extern void backtrace_remove_noncrash_frames(struct backtrace *backtrace);
-
-/* Parses the backtrace and stores it to a structure.
- * @returns
- *    Returns the backtrace struct representation, or NULL if the parser failed.
- *    Caller of this function is responsible for backtrace_free()ing the returned value.
- * Defined in backtrace_parser.y.
- */
-extern struct backtrace *backtrace_parse(char *input, bool debug_parser, bool debug_scanner);
-
-/* Reads the input file and calculates "independent" backtrace from it. "Independent" means
- * that the memory addresses that differ from run to run are removed from the backtrace, and
- * also variable names and values are removed.
- *
- * This function can be called when backtrace_parse() call fails. It provides a shorter
- * version of backtrace, with a chance that hash calculated from the returned value can be used
- * to detect duplicates. However, this kind of duplicate detection is very low-quality.
- * @returns
- *   The independent backtrace. Caller is responsible for calling
- *   strbuf_free() on it.
- */
-extern struct strbuf *independent_backtrace(const char *input);
-
-/* Get the quality of backtrace, as a number of "stars".
- * @returns
- *   Value 0 to 4.
- */
-extern int backtrace_rate_old(const char *backtrace);
-
-/* Evaluates the quality of the backtrace, meaning the ratio of frames
- * with function name fully known to all frames.
- * @returns
- *   A number between 0 and 1. 0 means the lowest quality,
- *   1 means full backtrace is known.
- */
-extern float backtrace_quality(struct backtrace *backtrace);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/utils/backtrace_parser.y b/lib/utils/backtrace_parser.y
deleted file mode 100644
index 8e2fc2b..0000000
--- a/lib/utils/backtrace_parser.y
+++ /dev/null
@@ -1,684 +0,0 @@
-%{ /* -*- mode: yacc -*-
-    Copyright (C) 2009  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 <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "backtrace.h"
-#include "strbuf.h"
-
-struct backtrace *g_backtrace;
-
-#define YYDEBUG 1
-#define YYMAXDEPTH 10000000
-void yyerror(char const *s)
-{
-  fprintf (stderr, "\nParser error: %s\n", s);
-}
-
-int yylex();
-
-%}
-
-/* This defines the type of yylval */
-%union {
-  struct backtrace *backtrace;
-  struct thread *thread;
-  struct frame *frame;
-  char *str;
-  int num;
-  char c;
-
-  struct strbuf *strbuf;
-}
-
-/* Bison declarations.  */
-%token END 0 "end of file"
-
-%type <backtrace> backtrace
-%type <thread> threads
-               thread
-%type <frame>  frames
-               frame
-               frame_head
-               frame_head_1
-               frame_head_2
-               frame_head_3
-               frame_head_4
-               frame_head_5
-%type <strbuf> identifier
-               hexadecimal_digit_sequence
-               hexadecimal_number
-               file_name
-               file_location
-               function_call
-               function_name
-               digit_sequence
-               frame_address_in_function
-               identifier_braces
-               identifier_braces_inside
-               identifier_template
-               identifier_template_inside
-%type <c>      nondigit
-               digit
-               hexadecimal_digit
-               file_name_char
-               identifier_char
-               identifier_char_no_templates
-               identifier_first_char
-               identifier_braces_inside_char
-               identifier_template_inside_char
-               variables_char
-               variables_char_no_framestart
-               ws
-               ws_nonl
-               '(' ')' '+' '-' '/' '.' '_' '~' '[' ']' '\r' '?' '{' '}'
-               'a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l'
-               'm' 'n' 'o' 'p' 'q' 'r' 's' 't' 'u' 'v' 'w' 'x' 'y' 'z'
-               'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N'
-               'O' 'P' 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z'
-               '0' '1' '2' '3' '4' '5' '6' '7' '8' '9'
-               '\'' '`' ',' '#' '@' '<' '>' '=' ':' '"' ';' ' '
-               '\n' '\t' '\\' '!' '*' '%' '|' '^' '&' '$'
-%type <num>    frame_start
-
-%destructor { thread_free($$); } <thread>
-%destructor { frame_free($$); } <frame>
-%destructor { strbuf_free($$); } <strbuf>
-
-%start backtrace
-%glr-parser
-%error-verbose
-%locations
-
-%% /* The grammar follows.  */
-
-backtrace : /* empty */ %dprec 1
-             { $$ = g_backtrace = backtrace_new(); }
-          | threads wsa %dprec 2
-             {
-               $$ = g_backtrace = backtrace_new();
-               $$->threads = $1;
-             }
-          |  frame_head wss threads wsa %dprec 4
-             {
-               $$ = g_backtrace = backtrace_new();
-               $$->threads = $3;
-               $$->crash = $1;
-             }
-          | frame wss threads wsa %dprec 3
-             {
-               $$ = g_backtrace = backtrace_new();
-               $$->threads = $3;
-               $$->crash = $1;
-             }
-;
-
-threads   : thread
-          | threads '\n' thread { $$ = thread_add_sibling($1, $3); }
-;
-
-thread    : keyword_thread wss digit_sequence wsa '(' keyword_thread wss digit_sequence wsa ')' ':' wsa frames
-              {
-                $$ = thread_new();
-                $$->frames = $13;
-
-		if (sscanf($3->buf, "%d", &$$->number) != 1)
-		{
-		  printf("Error while parsing thread number '%s'", $3->buf);
-		  exit(5);
-		}
-		strbuf_free($3);
-		strbuf_free($8);
-              }
-;
-
-frames    : frame        { $$ = $1; }
-          | frames frame { $$ = frame_add_sibling($1, $2); }
-;
-
-frame : frame_head_1 wss variables %dprec 3
-      | frame_head_2 wss variables %dprec 4
-      | frame_head_3 wss variables %dprec 5
-      | frame_head_4 wss variables %dprec 2
-      | frame_head_5 wss variables %dprec 1
-;
-
-frame_head : frame_head_1 %dprec 3
-	   | frame_head_2 %dprec 4
-	   | frame_head_3 %dprec 5
-           | frame_head_4 %dprec 2
-           | frame_head_5 %dprec 1
-;
-
-frame_head_1 : frame_start wss function_call wsa keyword_at wss file_location
-             {
-               $$ = frame_new();
-               $$->number = $1;
-               $$->function = $3->buf;
-               strbuf_free_nobuf($3);
-	       $$->sourcefile = $7->buf;
-               strbuf_free_nobuf($7);
-             }
-;
-
-frame_head_2 : frame_start wss frame_address_in_function wss keyword_at wss file_location
-             {
-               $$ = frame_new();
-               $$->number = $1;
-               $$->function = $3->buf;
-               strbuf_free_nobuf($3);
-	       $$->sourcefile = $7->buf;
-               strbuf_free_nobuf($7);
-             }
-;
-
-frame_head_3 : frame_start wss frame_address_in_function wss keyword_from wss file_location
-             {
-               $$ = frame_new();
-               $$->number = $1;
-               $$->function = $3->buf;
-               strbuf_free_nobuf($3);
-	       $$->sourcefile = $7->buf;
-               strbuf_free_nobuf($7);
-             }
-;
-
-frame_head_4 : frame_start wss frame_address_in_function
-             {
-               $$ = frame_new();
-               $$->number = $1;
-               $$->function = $3->buf;
-               strbuf_free_nobuf($3);
-             }
-;
-
-frame_head_5 : frame_start wss keyword_sighandler
-             {
-               $$ = frame_new();
-               $$->number = $1;
-	       $$->signal_handler_called = true;
-             }
-
-frame_start: '#' digit_sequence
-                 {
-                   if (sscanf($2->buf, "%d", &$$) != 1)
-		   {
-		     printf("Error while parsing frame number '%s'.\n", $2->buf);
-		     exit(5);
-		   }
-		   strbuf_free($2);
-                 }
-;
-
-frame_address_in_function : hexadecimal_number wss keyword_in wss function_call
-                              {
-                                strbuf_free($1);
-                                $$ = $5;
-                              }
-                          | hexadecimal_number wss keyword_in wss keyword_vtable wss keyword_for wss function_call
-                              {
-                                strbuf_free($1);
-                                $$ = $9;
-                              }
-;
-
-file_location : file_name ':' digit_sequence
-                  {
-                    $$ = $1;
-                    strbuf_free($3); /* line number not needed for now */
-                  }
-              | file_name
-;
-
-variables : variables_line '\n'
-          | variables_line END
-          | variables_line wss_nonl '\n'
-          | variables_line wss_nonl END
-          | variables variables_line '\n'
-          | variables variables_line END
-          | variables variables_line wss_nonl '\n'
-          | variables variables_line wss_nonl END
-          | variables wss_nonl variables_line '\n'
-          | variables wss_nonl variables_line END
-          | variables wss_nonl variables_line wss_nonl '\n'
-          | variables wss_nonl variables_line wss_nonl END
-;
-
-variables_line : variables_char_no_framestart
-               | variables_line variables_char
-               | variables_line wss_nonl variables_char
-;
-
-variables_char : '#' | variables_char_no_framestart
-;
-
-/* Manually synchronized with function_args_char_base, except the first line. */
-variables_char_no_framestart : digit | nondigit | '"' | '(' | ')' | '\\'
-                             | '+' | '-' | '<' | '>' | '/' | '.'
-                             | '[' | ']' | '?' | '\'' | '`' | ','
-                             | '=' | '{' | '}' | '^' | '&' | '$'
-                             | ':' | ';' | '!' | '@' | '*'
-                             | '%' | '|' | '~'
-;
-
-function_call : function_name wss function_args %dprec 3
-              | return_type wss_nonl function_name wss function_args %dprec 2
-                  { $$ = $3; }
-              | function_name wss_nonl identifier_template wss function_args %dprec 1
-	      { $$ = $1; strbuf_free($3); }
-;
-
-return_type : identifier { strbuf_free($1); }
-;
-
-function_name : identifier
-              | '?' '?'
-                {
-                  $$ = strbuf_new();
-                  strbuf_append_str($$, "??");
-                }
-;
-
-function_args : '(' wsa ')'
-              | '(' wsa function_args_sequence wsa ')'
-;
-
-function_args_sequence : function_args_char
-                       | function_args_sequence wsa '(' wsa ')'
-                       | function_args_sequence wsa '(' wsa function_args_string wsa ')'
-                       | function_args_sequence wsa '(' wsa function_args_sequence wsa ')'
-                       | function_args_sequence wsa function_args_char
-                       | function_args_sequence wsa function_args_string
-;
-
-function_args_string : '"' wsa function_args_string_sequence wsa '"'
-                     | '"' wsa '"'
-;
-
-/* Manually synchronized with variables_char_no_framestart,
- * except the first line.
- */
-function_args_char_base : digit | nondigit | '#'
-                   | '+' | '-' | '<' | '>' | '/' | '.'
-                   | '[' | ']' | '?' | '\'' | '`' | ','
-                   | '=' | '{' | '}' | '^' | '&' | '$'
-                   | ':' | ';' | '!' | '@' | '*'
-                   | '%' | '|' | '~'
-;
-function_args_escaped_char : '\\' function_args_char_base
-                           | '\\' '\\'
-                           | '\\' '"'
-;
-function_args_char : function_args_char_base
-                   | function_args_escaped_char
-;
-
-
-function_args_string_sequence : function_args_string_char
-                    | function_args_string_sequence function_args_string_char
-                    | function_args_string_sequence wss_nonl function_args_string_char
-;
-
-function_args_string_char : function_args_char | '(' | ')'
-;
-
-file_name : file_name_char { $$ = strbuf_new(); strbuf_append_char($$, $1); }
-          | file_name file_name_char { $$ = strbuf_append_char($1, $2); }
-;
-
-file_name_char : digit | nondigit | '-' | '+' | '/' | '.'
-;
-
- /* Function name, sometimes mangled.
-  * Example: something@GLIB_2_2
-  * CClass::operator=
-  */
-identifier : identifier_first_char %dprec 1
-              {
-		$$ = strbuf_new();
-		strbuf_append_char($$, $1);
-	      }
-           | identifier_braces %dprec 1 /* e.g. (anonymous namespace)::WorkerThread */
-           | identifier identifier_char %dprec 1
-	      { $$ = strbuf_append_char($1, $2); }
-           | identifier identifier_braces %dprec 1
-              {
-		$$ = strbuf_append_str($1, $2->buf);
-		strbuf_free($2);
-	      }
-           | identifier identifier_template %dprec 2
-              {
-		$$ = strbuf_append_str($1, $2->buf);
-		strbuf_free($2);
-	      }
-;
-
-identifier_first_char: nondigit
-                     | '~' /* destructor */
-                     | '*'
-;
-
-identifier_char_no_templates : digit | nondigit | '@' | '.' | ':' | '='
-	                     | '!' | '*' | '+' | '-' | '[' | ']'
-                             | '~' | '&' | '/' | '%' | '^'
-                             | '|' | ','
-;
-
-/* Most of the special characters are required to support C++
- * operator overloading.
- */
-identifier_char : identifier_char_no_templates | '<'| '>'
-;
-
-identifier_braces : '(' ')'
-                      {
-			$$ = strbuf_new();
-			strbuf_append_char($$, $1);
-			strbuf_append_char($$, $2);
-		      }
-                  | '(' identifier_braces_inside ')'
-                      {
-			$$ = strbuf_new();
-			strbuf_append_char($$, $1);
-			strbuf_append_str($$, $2->buf);
-			strbuf_free($2);
-			strbuf_append_char($$, $3);
-                      }
-;
-
-identifier_braces_inside : identifier_braces_inside_char %dprec 1
-                            {
-	                      $$ = strbuf_new();
-		              strbuf_append_char($$, $1);
-	                    }
-                         | identifier_braces_inside identifier_braces_inside_char %dprec 1
-			    { $$ = strbuf_append_char($1, $2); }
-                         | identifier_braces_inside '(' identifier_braces_inside ')' %dprec 1
-			    {
-			      $$ = strbuf_append_char($1, $2);
-			      $$ = strbuf_append_str($1, $3->buf);
-			      strbuf_free($3);
-			      $$ = strbuf_append_char($1, $4);
-			    }
-                         | identifier_braces_inside '(' ')' %dprec 1
-			    {
-			      $$ = strbuf_append_char($1, $2);
-			      $$ = strbuf_append_char($1, $3);
-			    }
-                         | identifier_braces_inside identifier_template %dprec 2
-			    {
-			      $$ = strbuf_append_str($1, $2->buf);
-			      strbuf_free($2);
-			    }
-;
-
-identifier_braces_inside_char : identifier_char | ws_nonl
-;
-
-identifier_template : '<' identifier_template_inside '>'
-                      {
-			$$ = strbuf_new();
-			strbuf_append_char($$, $1);
-			strbuf_append_str($$, $2->buf);
-			strbuf_free($2);
-			strbuf_append_char($$, $3);
-		      }
-;
-
-identifier_template_inside : identifier_template_inside_char
-                              {
-	                        $$ = strbuf_new();
-		                strbuf_append_char($$, $1);
-	                      }
-                           | identifier_template_inside identifier_template_inside_char
-			      { $$ = strbuf_append_char($1, $2); }
-                           | identifier_template_inside '<' identifier_template_inside '>'
-			      {
-				$$ = strbuf_append_char($1, $2);
-				$$ = strbuf_append_str($1, $3->buf);
-				strbuf_free($3);
-				$$ = strbuf_append_char($1, $4);
-			      }
-                           | identifier_template_inside identifier_braces
-			      {
-				$$ = strbuf_append_str($1, $2->buf);
-				strbuf_free($2);
-			      }
-;
-
-identifier_template_inside_char : identifier_char_no_templates | ws_nonl
-;
-
-digit_sequence : digit { $$ = strbuf_new(); strbuf_append_char($$, $1); }
-               | digit_sequence digit { $$ = strbuf_append_char($1, $2); }
-;
-
-hexadecimal_number : '0' 'x' hexadecimal_digit_sequence
-                     {
-                       $$ = $3;
-                       strbuf_prepend_str($$, "0x");
-                     }
-                   | '0' 'X' hexadecimal_digit_sequence
-                     {
-                       $$ = $3;
-                       strbuf_prepend_str($$, "0X");
-                     }
-;
-
-hexadecimal_digit_sequence : hexadecimal_digit
-                               {
-                                 $$ = strbuf_new();
-                                 strbuf_append_char($$, $1);
-                               }
-                           | hexadecimal_digit_sequence hexadecimal_digit
-                               { $$ = strbuf_append_char($1, $2); }
-;
-
-hexadecimal_digit : digit
-                  | 'a' | 'b' | 'c' | 'd' | 'e' | 'f'
-                  | 'A' | 'B' | 'C' | 'D' | 'E' | 'F'
-;
-
-digit : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
-;
-
-nondigit : 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k'
-         | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w'
-         | 'x' | 'y' | 'z'
-         | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K'
-         | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W'
-         | 'X' | 'Y' | 'Z'
-         | '_'
-;
-
- /* whitespace */
-ws : ws_nonl | '\n' | '\r'
-;
-
- /* No newline.*/
-ws_nonl : '\t' | ' '
-;
-
- /* whitespace sequence without a newline */
-wss_nonl : ws_nonl
-         | wss_nonl ws_nonl
-;
-
- /* whitespace sequence */
-wss : ws
-    | wss ws
-;
-
- /* whitespace sequence allowed */
-wsa :
-    | wss
-;
-
-keyword_in : 'i' 'n'
-;
-
-keyword_at : 'a' 't'
-;
-
-keyword_for : 'f' 'o' 'r'
-;
-
-keyword_vtable : 'v' 't' 'a' 'b' 'l' 'e'
-;
-
-keyword_from : 'f' 'r' 'o' 'm'
-;
-
-keyword_thread: 'T' 'h' 'r' 'e' 'a' 'd'
-;
-
-keyword_sighandler: '<' 's' 'i' 'g' 'n' 'a' 'l' ' ' 'h' 'a' 'n' 'd' 'l' 'e' 'r' ' ' 'c' 'a' 'l' 'l' 'e' 'd' '>'
-;
-
-%%
-
-static bool scanner_echo = false;
-static char *yyin;
-
-int yylex()
-{
-  char c = *yyin;
-  if (c == '\0')
-    return END;
-  ++yyin;
-
-  /* Debug output. */
-  if (scanner_echo)
-    putchar(c);
-
-  yylval.c = c;
-
-  /* Return a single char. */
-  return c;
-}
-
-/* This is the function that is actually called from outside.
- * @returns
- *   Backtrace structure. Caller is responsible for calling
- *   backtrace_free() on this.
- *   Returns NULL when parsing failed.
- */
-struct backtrace *backtrace_parse(char *input, bool debug_parser, bool debug_scanner)
-{
-  /* Skip the backtrace header information. */
-  char *btnoheader_a = strstr(input, "\nThread ");
-  char *btnoheader_b = strstr(input, "\n#");
-  char *btnoheader = input;
-  if (btnoheader_a)
-  {
-    if (btnoheader_b && btnoheader_b < btnoheader_a)
-      btnoheader = btnoheader_b + 1;
-    else
-      btnoheader = btnoheader_a + 1;
-  }
-  else if (btnoheader_b)
-    btnoheader = btnoheader_b + 1;
-
-  /* Bug fixing hack for broken backtraces.
-   * Sometimes the empty line is missing before new Thread section.
-   * This is against rules, but a bug (now fixed) in Linux kernel caused
-   * this.
-   */
-  char *thread_fixer = btnoheader + 1;
-  while ((thread_fixer = strstr(thread_fixer, "\nThread")) != NULL)
-  {
-    if (thread_fixer[-1] != '\n')
-      thread_fixer[-1] = '\n';
-
-    ++thread_fixer;
-  }
-
-  /* Bug fixing hack for GDB - remove wrongly placed newlines from the backtrace.
-   * Sometimes there is a newline in the local variable section.
-   * This is caused by some GDB hooks.
-   * Example: rhbz#538440
-   * #1  0x0000000000420939 in sync_deletions (mse=0x0, mfld=0x1b85020)
-   *    at mail-stub-exchange.c:1119
-   *     status = <value optimized out>
-   *     iter = 0x1af38d0
-   *     known_messages = 0x1b5c460Traceback (most recent call last):
-   *  File "/usr/share/glib-2.0/gdb/glib.py", line 98, in next
-   *    if long (node["key_hash"]) >= 2:
-   * RuntimeError: Cannot access memory at address 0x11
-   *
-   *     __PRETTY_FUNCTION__ = "sync_deletions"
-   * #2  0x0000000000423e6b in refresh_folder (stub=0x1b77f10 [MailStubExchange],
-   * ...
-   *
-   * The code removes every empty line (also those containing only spaces),
-   * which is not followed by a new Thread section.
-   *
-   * rhbz#555251 contains empty lines with spaces
-   */
-  char *empty_line = btnoheader;
-  char *c = btnoheader;
-  while (*c)
-  {
-    if (*c == '\n')
-    {
-      char *cend = c + 1;
-      while (*cend == ' ' || *cend == '\t')
-        ++cend;
-      if (*cend == '\n' && 0 != strncmp(cend, "\nThread", strlen("\nThread")))
-        memmove(c, cend, strlen(cend) + 1);
-    }
-    ++c;
-  }
-  while ((empty_line = strstr(empty_line, "\n\n")) != NULL)
-  {
-    if (0 != strncmp(empty_line, "\n\nThread", strlen("\n\nThread")))
-    {
-      /* Remove the empty line by converting the first newline to char. */
-      empty_line[0] = 'X';
-    }
-    ++empty_line;
-  }
-
-  /* Prepare for running parser. */
-  g_backtrace = 0;
-  yyin = btnoheader;
-#if YYDEBUG == 1
-  if (debug_parser)
-    yydebug = 1;
-#endif
-  scanner_echo = debug_scanner;
-
-  /* Parse. */
-  int failure = yyparse();
-
-  /* Separate debugging output. */
-  if (scanner_echo)
-    putchar('\n');
-
-  if (failure)
-  {
-    if (g_backtrace)
-    {
-      backtrace_free(g_backtrace);
-      g_backtrace = NULL;
-    }
-    fprintf(stderr, "Error while parsing backtrace.\n");
-  }
-
-  return g_backtrace;
-}
diff --git a/scripts/abrt-bz-downloader b/scripts/abrt-bz-downloader
deleted file mode 100755
index d7f5a71..0000000
--- a/scripts/abrt-bz-downloader
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/usr/bin/python
-# -*- mode:python -*-
-# ABRT Bugzilla Backtrace Downloader
-# Downloads all backtraces reported by ABRT from Bugzilla.
-#
-# Please do not run this script unless it's neccessary to do so.
-# It forces Bugzilla to send data related to thousands of bug reports.
-
-from bugzilla import RHBugzilla
-from optparse import OptionParser
-import sys
-import os.path
-
-parser = OptionParser(version="%prog 1.0")
-parser.add_option("-u", "--user", dest="user",
-                  help="Bugzilla user name (REQUIRED)", metavar="USERNAME")
-parser.add_option("-p", "--password", dest="password",
-                  help="Bugzilla password (REQUIRED)", metavar="PASSWORD")
-parser.add_option("-b", "--bugzilla", dest="bugzilla",
-                  help="Bugzilla URL (defaults to Red Hat Bugzilla)", metavar="URL")
-parser.add_option("-f", "--fields",
-                  action="store_true", dest="fields", default=False,
-                  help="Print possible bug fields and exit.")
-
-(options, args) = parser.parse_args()
-
-if not options.user or len(options.user) == 0:
-  parser.error("User name is required.\nTry {0} --help".format(sys.argv[0]))
-
-if not options.password or len(options.password) == 0:
-  parser.error("Password is required.\nTry {0} --help".format(sys.argv[0]))
-
-if not options.bugzilla or len(options.bugzilla) == 0:
-  options.bugzilla = "https://bugzilla.redhat.com/xmlrpc.cgi"
-
-bz = RHBugzilla()
-bz.connect(options.bugzilla)
-bz.login(options.user, options.password)
-
-if options.fields:
-  print bz.bugfields
-  exit(0)
-
-buginfos = bz.query({'status_whiteboard_type':'allwordssubstr','status_whiteboard':'abrt_hash'})
-
-print "{0} bugs found.".format(len(buginfos))
-
-for buginfo in buginfos:
-  # Skip bugs with already downloaded backtraces.
-  filename = "{0}.bt".format(buginfo.bug_id)
-  if os.path.isfile(filename):
-    print "Skipping {0} (already exists).".format(filename)
-    continue
-
-  # Skip bugs with broken or Python backtraces
-  broken_backtrace_bugs = [ 517116, # binary file :)
-                            518516, # not a backtrace, GDB fail
-                            524259, # multiple backtraces in single file
-                            524427, # multiple backtraces in single file
-                            528529, # just [New Thread xx] lines
-                            #528915, 10000 frames, out of memory, to be fixed
-                            #529422, 10000 frames, out of memory, to be fixed
-                            #530239, 10000 frames, out of memory, to be fixed
-                            532264, # no header
-                            533475, # no backtrace
-                            #537819, 50000 frames, out of memory, to be fixed
-                            #539699, to be fixed, parser bug
-                            539992] # completely broken backtrace
-  if buginfo.bug_id in broken_backtrace_bugs:
-    continue
-
-  # Get backtrace from bug and store it as a file.
-  bug = bz.getbug(buginfo.bug_id)
-  for attachment in bug.attachments:
-    if attachment['filename'] == 'backtrace':
-      data = bz.openattachment(attachment['id'])
-      f = open(filename, 'w')
-      f.write(data.read())
-      f.close()
-      print "Attachment {0} downloaded.".format(filename)
-
-bz.logout()
diff --git a/scripts/abrt-bz-dupchecker b/scripts/abrt-bz-dupchecker
deleted file mode 100755
index 65e1153..0000000
--- a/scripts/abrt-bz-dupchecker
+++ /dev/null
@@ -1,281 +0,0 @@
-#!/usr/bin/python
-# -*- mode:python -*-
-# ABRT Bugzilla Duplication Checker
-# Downloads all backtraces reported by ABRT from Bugzilla,
-# and search for duplicates using the newest ABRT duplication
-# checker.
-#
-# Some bugs in Bugzilla were reported by older ABRT
-# versions, which had poor duplication detection.
-#
-# Please do not run this script unless it's neccessary to do so.
-# It forces Bugzilla to send data related to thousands of bug reports.
-#
-#
-# Useful text to be pasted to Bugzilla:
-"""
-This bug appears to have been filled using a buggy version of ABRT, because
-it contains unusable backtrace. Sorry for the inconvenience.
-Closing as INSUFFICIENT_DATA.
-"""
-
-from bugzilla import RHBugzilla
-from optparse import OptionParser
-import sys
-import os.path
-import subprocess
-import cPickle
-import urllib
-import json
-
-parser = OptionParser(version="%prog 1.0")
-parser.add_option("-u", "--user", dest="user",
-                  help="Bugzilla user name (REQUIRED)", metavar="USERNAME")
-parser.add_option("-p", "--password", dest="password",
-                  help="Bugzilla password (REQUIRED)", metavar="PASSWORD")
-parser.add_option("-b", "--bugzilla", dest="bugzilla", default="https://bugzilla.redhat.com/xmlrpc.cgi",
-                  help="Bugzilla URL (defaults to Red Hat Bugzilla)", metavar="URL")
-parser.add_option("-v", "--verbose", dest="verbose",
-                  help="Detailed output")
-parser.add_option("-c", "--close", help="Close some of the bugs in Bugzilla (DANGEROUS)",
-                  action="store_true", default=False, dest="close")
-parser.add_option("-i", "--wiki", help="Generate output in wiki syntax",
-                  action="store_true", default=False, dest="wiki")
-
-(options, args) = parser.parse_args()
-
-if not options.user or len(options.user) == 0:
-  parser.error("User name is required.\nTry {0} --help".format(sys.argv[0]))
-
-if not options.password or len(options.password) == 0:
-  parser.error("Password is required.\nTry {0} --help".format(sys.argv[0]))
-
-bz = RHBugzilla()
-bz.connect(options.bugzilla)
-bz.login(options.user, options.password)
-
-buginfos = bz.query({'status_whiteboard_type':'allwordssubstr','status_whiteboard':'abrt_hash', 'product':'Fedora'})
-
-print "{0} bugs found.".format(len(buginfos))
-
-#
-# Load cache from previous run. Speeds up the case Bugzilla closes connection.
-# The cache should be manually removed after a day or so, because the data in it
-# are no longer valid.
-#
-database = {}
-ids = {}
-CACHE_FILE = "abrt-bz-dupchecker-cache.tmp"
-if os.path.isfile(CACHE_FILE):
-  f = open(CACHE_FILE, 'r')
-  database = cPickle.load(f)
-  ids = cPickle.load(f)
-  f.close()
-
-def save_to_cache():
-  global database
-  f = open(CACHE_FILE, 'w')
-  cPickle.dump(database, f, 2)
-  cPickle.dump(ids, f, 2)
-  f.close()
-
-count = 0
-for buginfo in buginfos:
-  count += 1
-  print "{0}/{1}".format(count, len(buginfos))
-  if count % 100 == 0:
-    save_to_cache()
-
-  if ids.has_key(buginfo.bug_id):
-    continue
-
-  ids[buginfo.bug_id] = True
-
-  if not buginfo.bug_status in ["NEW", "ASSIGNED", "MODIFIED", "VERIFIED"]:
-    if options.verbose:
-      print "Bug {0} has status {1}, skipping.".format(buginfo.bug_id, buginfo.bug_status)
-    continue
-
-  bug = bz.getbug(buginfo.bug_id)
-
-  # Skip bugs with already downloaded backtraces.
-  filename = "{0}.bt".format(buginfo.bug_id)
-  if os.path.isfile(filename):
-    if options.verbose:
-      print "Skipping {0} (already exists).".format(filename)
-  else:
-    # Get backtrace from bug and store it as a file.
-    downloaded = False
-    for attachment in bug.attachments:
-      if attachment['filename'] == 'backtrace':
-        data = bz.openattachment(attachment['id'])
-        f = open(filename, 'w')
-        f.write(data.read())
-        f.close()
-        downloaded = True
-        if options.verbose:
-          print "Attachment {0} downloaded.".format(filename)
-
-    # Silently skip bugs without backtrace.
-    # Those are usually duplicates of bugs; the duplication copies
-    # abrt_hash, but it does not copy the attachment.
-    if not downloaded:
-      continue
-
-  command = ["abrt-backtrace"]
-  command.append(filename)
-  command.append("--single-thread")
-  command.append("--frame-depth=5")
-  command.append("--remove-exit-handlers")
-  command.append("--remove-noncrash-frames")
-
-  helper = subprocess.Popen(command, stdout=subprocess.PIPE)
-  backtrace, err = helper.communicate()
-  helper.wait()
-
-  if helper.returncode != 0:
-    print "Problems parsing {0}".format(filename)
-    continue
-
-  # Empty backtrace is provided by Python apps.
-  if len(backtrace) == 0:
-    continue
-
-  bugitem = {'id':buginfo.bug_id, 'comments':len(bug.longdescs)}
-  if backtrace in database:
-    components = database[backtrace]
-    if buginfo.component in components:
-      components[buginfo.component].append(bugitem)
-      if options.verbose:
-        print "Duplicate found: {0}".format(database[out]['id'])
-        print "Backtrace: {0}".format(out)
-    else:
-      components[buginfo.component] = [ bugitem ]
-  else:
-    database[backtrace] = { buginfo.component: [ bugitem ] }
-
-# The number of duplicates.
-dupcount = 0
-# The number of duplicates that can be closed.
-dupclosecount = 0
-for backtrace, components in database.items():
-  for component, bugitems in components.items():
-    dupcount += len(bugitems) - 1
-    dupclosecount += min(len(filter(lambda x: x <= 2,
-                                    map(lambda x: x["comments"],
-                                        bugitems))),
-                         len(bugitems) - 1)
-
-# Get the component owner.
-# Sort the duplicates by the component owner, and
-# filter out those which should not be printed.
-dups = []
-for backtrace, components in database.items():
-  for component, bugitems in components.items():
-    if len(bugitems) <= 1:
-      continue
-
-    # Get the component owner
-    owner = "Failed to get component owner"
-    try:
-      component_info = json.load(urllib.urlopen("https://admin.fedoraproject.org/pkgdb/acls/name/{0}?tg_format=json".format(component)))
-      component_packages = component_info['packageListings']
-      component_f12 = filter(lambda x:x["collection"]["version"]=="12", component_packages)
-      if len(component_f12) == 1:
-        owner = component_f12[0]["owner"]
-    except KeyError:
-      pass
-
-    dups.append((component, owner, bugitems, backtrace))
-    print "."
-
-# Close all bugs where it is appropriate.
-if options.close:
-  LIMIT = 10000 # infinite
-  counter = 0
-  for (component, owner, bugitems, backtrace) in dups:
-    # Find the master bug item
-    # Its the one with the most comments.
-
-    # Sort function sorting by comment count.
-    def commentCmp(x, y):
-      if x['comments'] < y['comments']:
-        return 1
-      elif x['comments'] == y['comments']:
-        # Sort by bug id, older bugs should became the master bug
-        if x['id'] > y['id']:
-          return 1
-        elif x['id'] == y['id']:
-          return 0
-        else:
-          return -1
-      else:
-        return -1
-
-    # Sort the duplicates by the number of comments.
-    # Select the bug with the highest number of comments as the master bug.
-    # All other bugs without user comments will be closed as a duplicate of
-    # the master bug.
-    sorteditems = sorted(bugitems, commentCmp)
-    master = sorteditems[0]
-
-    # Check the master bug status AGAIN to make sure the bug is still opened.
-    bug = bz.getbug(int(master['id']))
-    if not bug.bug_status in ["NEW", "ASSIGNED"]:
-      continue
-
-    for item in sorteditems[1:]:
-      if item['comments'] > 2:
-        continue
-
-      # Check the bug status AGAIN to make sure the bug is still opened.
-      bug = bz.getbug(int(item['id']))
-      if not bug.bug_status in ["NEW", "ASSIGNED"]:
-        continue
-
-      print "Closing bug #{0} with {1} comments as a duplicate of #{2}.".format(item['id'], item['comments'], master['id'])
-      bug.close("DUPLICATE", int(master['id']), "",
-                ("This bug appears to have been filled using a buggy version of ABRT, because\n" +
-                "it contains a backtrace which is a duplicate of backtrace from bug #{0}.\n\n" +
-                "Sorry for the inconvenience.").format(master['id']))
-
-      counter += 1
-      if counter > LIMIT:
-        sys.exit(0)
-
-bz.logout()
-
-print
-print "SUMMARY"
-print "=========================================================================="
-print "Total number of duplicate bugs detected: {0}".format(dupcount)
-print "Number of duplicate bugs that will be closed : {0}".format(dupclosecount)
-print "------------------------------"
-
-# Print the duplicates sorted by package owner.
-def cmp(x, y):
-  if x[1] < y[1]:
-    return -1
-  elif x[1] == y[1]:
-    return 0
-  else:
-    return 1
-
-for (component, owner, bugitems, backtrace) in sorted(dups, cmp):
-  if options.wiki:
-    print "----"
-    print "* component: '''{0}''' ({1})".format(component, owner)
-    print "* duplicates: {0}".format(
-      reduce(lambda x,y: x+", "+y,
-             map(lambda x: "#[https://bugzilla.redhat.com/show_bug.cgi?id={0} {0}] ({1} comments)".format(x['id'],x['comments']),
-                 bugitems)))
-    print "* backtrace:"
-    for line in backtrace.replace("Thread\n", "").splitlines():
-      print "*# {0}".format(line)
-  else:
-    print "Component: {0} ({1})".format(component, owner)
-    print "Duplicates: {0}".format(
-      reduce(lambda x,y: x+", "+y,
-             map(lambda x: "{0} ({1})".format(x['id'],x['comments']),
-                 bugitems)))
-    print "Backtrace: {0}".format(backtrace)
diff --git a/scripts/abrt-bz-hashchecker b/scripts/abrt-bz-hashchecker
deleted file mode 100755
index bb66c7d..0000000
--- a/scripts/abrt-bz-hashchecker
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/python
-# -*- mode:python -*-
-# Checks how many bugs in Bugzilla have the same hash.
-#
-# Please do not run this script unless it's neccessary to do so.
-# It forces Bugzilla to send data related to thousands of bug reports.
-
-from bugzilla import RHBugzilla
-from optparse import OptionParser
-import sys
-import os.path
-import subprocess
-import re
-
-parser = OptionParser(version="%prog 1.0")
-parser.add_option("-u", "--user", dest="user",
-                  help="Bugzilla user name (REQUIRED)", metavar="USERNAME")
-parser.add_option("-p", "--password", dest="password",
-                  help="Bugzilla password (REQUIRED)", metavar="PASSWORD")
-parser.add_option("-b", "--bugzilla", dest="bugzilla",
-                  help="Bugzilla URL (defaults to Red Hat Bugzilla)", metavar="URL")
-
-(options, args) = parser.parse_args()
-
-if not options.user or len(options.user) == 0:
-  parser.error("User name is required.\nTry {0} --help".format(sys.argv[0]))
-
-if not options.password or len(options.password) == 0:
-  parser.error("Password is required.\nTry {0} --help".format(sys.argv[0]))
-
-if not options.bugzilla or len(options.bugzilla) == 0:
-  options.bugzilla = "https://bugzilla.redhat.com/xmlrpc.cgi"
-
-bz = RHBugzilla()
-bz.connect(options.bugzilla)
-bz.login(options.user, options.password)
-
-buginfos = bz.query({'status_whiteboard_type':'allwordssubstr','status_whiteboard':'abrt_hash'})
-
-print "{0} bugs found.".format(len(buginfos))
-
-hashes = {}
-for buginfo in buginfos:
-    match = re.search("abrt_hash:([^ ]+)", buginfo.status_whiteboard)
-    if not match:
-      continue
-    hash = match.group(1)
-    if not hash:
-      continue
-    if hash in hashes:
-        hashes[hash].append(buginfo.bug_id)
-    else:
-        hashes[hash] = [ buginfo.bug_id ]
-    print hash
-bz.logout()
-
-for hash, ids in hashes.items():
-    if len(ids) > 1:
-      print "Duplicates found: ", reduce(lambda x,y: str(x)+", "+str(y), ids)
diff --git a/scripts/abrt-bz-ratingfixer b/scripts/abrt-bz-ratingfixer
deleted file mode 100755
index d788197..0000000
--- a/scripts/abrt-bz-ratingfixer
+++ /dev/null
@@ -1,210 +0,0 @@
-#!/usr/bin/python
-# -*- mode:python -*-
-#
-# Finds bugs with incomplete backtraces in Buzilla.
-# Incomplete backtraces are caused by missing debuginfo.
-#
-# Please do not run this script unless it's neccessary to do so. 
-# It forces Bugzilla to send data related to thousands of bug reports.
-
-from bugzilla import RHBugzilla
-from optparse import OptionParser
-import sys
-import os.path
-import subprocess
-import cPickle
-import urllib
-import json
-
-#
-# Parse command line options.
-# Exit if mandatory options are missing.
-#
-parser = OptionParser(version="%prog 1.0")
-parser.add_option("-u", "--user", dest="user",
-                  help="Bugzilla user name (REQUIRED)", metavar="USERNAME")
-parser.add_option("-p", "--password", dest="password",
-                  help="Bugzilla password (REQUIRED)", metavar="PASSWORD")
-parser.add_option("-b", "--bugzilla", dest="bugzilla", default="https://bugzilla.redhat.com/xmlrpc.cgi",
-                  help="Bugzilla URL (defaults to Red Hat Bugzilla)", metavar="URL")
-parser.add_option("-i", "--wiki", help="Generate output in wiki syntax", 
-                  action="store_true", default=False, dest="wiki")
-parser.add_option("-c", "--close", help="Close some of the bugs in Bugzilla (DANGEROUS)", 
-                  action="store_true", default=False, dest="close")
-(options, args) = parser.parse_args()
-
-if not options.user or len(options.user) == 0:
-  parser.error("User name is required.\nTry {0} --help".format(sys.argv[0]))
-
-if not options.password or len(options.password) == 0:
-  parser.error("Password is required.\nTry {0} --help".format(sys.argv[0]))
-
-#
-# Connect to the Bugzilla and get all bugs reported by ABRT
-#
-bz = RHBugzilla()
-bz.connect(options.bugzilla)
-bz.login(options.user, options.password)
-
-buginfos = bz.query({'status_whiteboard_type':'allwordssubstr','status_whiteboard':'abrt_hash'})
-print "{0} bugs found.".format(len(buginfos))
-
-#
-# Load cache from previous run. It speeds up the case Bugzilla closes connection.
-# The cache should be manually removed after a day or so, because the data in it 
-# are no longer valid.
-#
-ids = {}
-CACHE_FILE = "abrt-bz-ratingfixer-cache.tmp"
-if os.path.isfile(CACHE_FILE):
-  f = open(CACHE_FILE, 'r')
-  ids = cPickle.load(f)
-  f.close()
-
-def save_to_cache():
-  global database
-  f = open(CACHE_FILE, 'w')
-  cPickle.dump(ids, f, 2)
-  f.close()  
-
-#
-# Go through all bugs, and get the rating for their backtraces.
-# The result is stored into ids map.
-#
-count = 0
-for buginfo in buginfos:
-  # The progress indicator.
-  count += 1
-  print "{0}/{1}".format(count, len(buginfos))
-
-  # Save to cache for the case the connection will be closed by the Bugzilla.
-  # This happens pretty often.
-  if count % 100 == 0:
-    save_to_cache()
-
-  # Skip the bugs already loaded from cache.
-  if ids.has_key(buginfo.bug_id):
-    continue
-
-  # We handle only unprocessed bugs.
-  if not buginfo.bug_status in ["NEW", "ASSIGNED"]:
-    continue
-
-  # By default: rating 4, no comments. Do not touch strange bugs.
-  ids[buginfo.bug_id] = { 
-    'rating': 4, 
-    'comment_count': 0, 
-    'component': buginfo.component 
-    }
-
-  # Skip bugs with already downloaded backtraces.
-  filename = "{0}.bt".format(buginfo.bug_id)
-  if not os.path.isfile(filename):
-    # Get backtrace from bug and store it as a file.
-    downloaded = False
-    bug = bz.getbug(buginfo.bug_id)
-    for attachment in bug.attachments:
-      if attachment['filename'] == 'backtrace':
-        data = bz.openattachment(attachment['id'])
-        f = open(filename, 'w')
-        f.write(data.read())
-        f.close()
-        downloaded = True
-
-    # Silently skip bugs without backtrace.
-    # Those are usually duplicates of bugs; the duplication copies
-    # abrt_hash, but it does not copy the attachment.
-    if not downloaded:
-      continue
-
-  # Rate the backtrace using external program.
-  command = ["abrt-backtrace", "--rate"]
-  command.append(filename)
-  helper = subprocess.Popen(command, stdout=subprocess.PIPE)
-  rating, err = helper.communicate()
-  helper.wait()
-  if helper.returncode != 0:
-    print "Problems with rating {0}".format(filename)
-    continue
-
-  # Get the comment count. We do not want to close bugs which
-  # are in the middle of a discussion.
-  bug = bz.getbug(buginfo.bug_id)
-  comment_count = 0
-  for comment in bug.longdescs:
-    # Do not count "rawhide" comments from Bug Zappers
-    if comment["body"].find("against 'rawhide' during") > 0:
-      continue
-    comment_count += 1
-
-  # Put the result to the database.
-  ids[buginfo.bug_id] = { 
-    'rating': int(rating), 
-    'comment_count': comment_count, 
-    'component': buginfo.component 
-    }
-
-  # Close the bug if it's appropriate.
-  if options.close and comment_count <= 2 and int(rating) < 3:
-    print "Closing bug #{0} with {1} comments and rating {2}/4.".format(buginfo.bug_id, comment_count, int(rating))
-    bug.close("INSUFFICIENT_DATA", 0, "", 
-                "This bug appears to have been filled using a buggy version of ABRT, because\n" +
-                "it contains unusable backtrace. Sorry for the inconvenience.\n\n" +
-                "Closing as INSUFFICIENT_DATA.")
-
-bz.logout()
-
-#
-# Get the component owners
-#
-bugids = []
-for id, bug in ids.items():
-  # Skip bugs with good rating.
-  if bug['rating'] >= 3:
-    continue
-
-  # Get the component owner
-  owner = "Failed to get component owner"
-  try:
-    component_info = json.load(urllib.urlopen("https://admin.fedoraproject.org/pkgdb/acls/name/{0}?tg_format=json".format(bug['component'])))
-    component_packages = component_info['packageListings']
-    component_f12 = filter(lambda x:x["collection"]["version"]=="12", component_packages)
-    if len(component_f12) == 1:
-      owner = component_f12[0]["owner"]
-  except KeyError:
-    pass
-
-  bug['id'] = id
-  bug['owner'] = owner
-  bugids.append(bug)
-
-def ownerCmp(a, b):
-  if a['owner'] < b['owner']:
-    return -1
-  elif a['owner'] == b['owner']:
-    return 0
-  else:
-    return 1
-
-print "============= SUMMARY"
-closedcount = 0
-if options.wiki:
-  print "{|"
-  print " ! Bug !! Backtrace rating !! Comment count !! Component !! Owner"
-  print " |-"
-for bug in sorted(bugids, ownerCmp):
-  count += 1
-  if bug['comment_count'] <= 2:
-    closedcount += 1
-
-  if options.wiki:
-    print " | #[https://bugzilla.redhat.com/show_bug.cgi?id={0} {0}] || {1}/4 || {2} || {3} || {4}".format(bug['id'], bug['rating'], bug['comment_count'], bug['component'], bug['owner'])
-    print " |-"
-  else:
-    print "#{0} has a backtrace with rating {1}/4 and {2} comments, component {3}, owner {4}".format(bug['id'], bug['rating'], bug['comment_count'], bug['component'], bug['owner'])
-
-if options.wiki:
-  print " |}"
-
-print "{0} bugs are included.".format(len(bugids))
-print "{0} bugs should be closed.".format(closedcount)
diff --git a/scripts/abrt-bz-stats b/scripts/abrt-bz-stats
deleted file mode 100755
index ea44f5b..0000000
--- a/scripts/abrt-bz-stats
+++ /dev/null
@@ -1,313 +0,0 @@
-#!/usr/bin/python
-# -*- mode:python -*-
-# ABRT Bugzilla Statistics script
-#
-# Please do not run this script unless it's neccessary to do so.
-# It forces Bugzilla to send info about thousands of bug reports.
-
-from bugzilla import RHBugzilla
-from optparse import OptionParser
-import sys
-import os.path
-import subprocess
-from datetime import datetime
-import pickle
-
-#
-# Parse the command line input
-#
-parser = OptionParser(version="%prog 1.0")
-parser.add_option("-u", "--user", dest="user",
-                  help="Bugzilla user name (REQUIRED)", metavar="USERNAME")
-parser.add_option("-p", "--password", dest="password",
-                  help="Bugzilla password (REQUIRED)", metavar="PASSWORD")
-parser.add_option("-b", "--bugzilla", dest="bugzilla",
-                  help="Bugzilla URL (defaults to Red Hat Bugzilla)", metavar="URL")
-# Weekly stats shows the impact of changes in ABRT early.
-parser.add_option("-w", "--weekly", help="Generate weekly report instead of monthly",
-                  action="store_true", default=False, dest="weekly")
-# HTML output for blogs etc.
-parser.add_option("-t", "--html", help="Generate HTML output",
-                  action="store_true", default=False, dest="html")
-parser.add_option("-i", "--wiki", help="Generate output in wiki syntax",
-                  action="store_true", default=False, dest="wiki")
-# Newest stats first
-parser.add_option("-r", "--reversed", help="Display the newest stats first",
-                  action="store_true", default=False, dest="reversed")
-(options, args) = parser.parse_args()
-if not options.user or len(options.user) == 0:
-  parser.error("User name is required.\nTry {0} --help".format(sys.argv[0]))
-if not options.password or len(options.password) == 0:
-  parser.error("Password is required.\nTry {0} --help".format(sys.argv[0]))
-if not options.bugzilla or len(options.bugzilla) == 0:
-  options.bugzilla = "https://bugzilla.redhat.com/xmlrpc.cgi"
-
-#
-# Connect to Bugzilla and get the list of all bugs reported by ABRT
-#
-bz = RHBugzilla()
-bz.connect(options.bugzilla)
-bz.login(options.user, options.password)
-
-buginfos = bz.query({'status_whiteboard_type':'allwordssubstr','status_whiteboard':'abrt_hash'})
-total = len(buginfos)
-print "{0} bugs found.".format(total)
-
-#
-# Load cache from previous run. Speeds up the case Bugzilla closes connection.
-#
-buginfos_loaded = {}
-CACHE_FILE = "abrt-bz-stats-cache.tmp"
-if os.path.isfile(CACHE_FILE):
-  f = open(CACHE_FILE, 'r')
-  buginfos_loaded = pickle.load(f)
-  f.close()
-
-def save_to_cache():
-  global buginfos_loaded
-  f = open(CACHE_FILE, 'w')
-  pickle.dump(buginfos_loaded, f, 2)
-  f.close()
-
-#
-# Load data from Bugzilla
-#
-count = 0
-for buginfo in buginfos:
-  count += 1
-  print "{0}/{1}".format(count, total)
-
-  if count % 100 == 0:
-    save_to_cache()
-
-  if buginfos_loaded.has_key(buginfo.bug_id):
-    continue
-
-  # creation date, format YEAR-MONTH-DAY
-  created = buginfo.creation_ts[0:10].replace(".", "-")
-  # last change to bug, format YEAR-MONTH-DAY
-  lastchange = buginfo.delta_ts[0:10].replace(".", "-")
-  status = buginfo.bug_status # status during the last change
-  if buginfo.resolution != "":
-    status += "_" + buginfo.resolution
-  buginfos_loaded[buginfo.bug_id] = {
-    'created':created,
-    'lastchange':lastchange,
-    'status':status,
-    'component':buginfo.component}
-
-bz.logout()
-save_to_cache()
-
-#
-# Interpret data from Bugzilla
-#
-# Bugs reported this month/week by ABRT
-# Bugs closed as useful this month/week by ABRT
-# Bugs closed as waste this month/week by ABRT
-# Top crashers this month/week.
-#
-class TimeSpan:
-  """
-  It's either a week or month.
-  """
-  def __init__(self):
-    # Number of bugs reported to certain component this month.
-    self.components = {}
-
-    self.closed_as_useful = 0
-    self.closed_as_waste = 0
-    self.closed_as_other = 0
-
-  def bugs_reported(self):
-    result = 0
-    for component in self.components.values():
-      result += component
-    return result
-
-  def top_crashers(self, n = 10):
-    """
-    Top n components causing crash this month.
-    Returns list of tuples (component, number of crashes)
-    """
-    result = sorted(self.components.items(), key=lambda x: x[1])
-    result.reverse()
-    return result[0:n]
-
-  def closed_as_useful_percentage(self):
-    return int(100 * self.closed_as_useful / self.closed())
-
-  def closed_as_waste_percentage(self):
-    return int(100 * self.closed_as_waste / self.closed())
-
-  def closed_as_other_percentage(self):
-    return 100 - self.closed_as_useful_percentage() \
-        - self.closed_as_waste_percentage()
-
-  def closed(self):
-    return self.closed_as_useful + self.closed_as_waste + self.closed_as_other
-
-  def add_component_crash(self, component):
-    if component in self.components:
-      self.components[component] += 1
-    else:
-      self.components[component] = 1
-
-  def add_resolution(self, resolution):
-    # Catches only resolutions starting with "CLOSED_"
-    if resolution in ["CLOSED_CURRENTRELEASE", "CLOSED_RAWHIDE", "CLOSED_ERRATA",
-                      "CLOSED_UPSTREAM", "CLOSED_NEXTRELEASE"]:
-      self.closed_as_useful += 1
-    elif resolution in ["CLOSED_DUPLICATE", "CLOSED_CANTFIX",
-                        "CLOSED_INSUFFICIENT_DATA"]:
-      self.closed_as_waste += 1
-    elif resolution in ["CLOSED_NOTABUG", "CLOSED_WONTFIX",
-                           "CLOSED_DEFERRED", "CLOSED_WORKSFORME"]:
-      self.closed_as_other += 1
-
-  def __str__(self):
-    def bug(count):
-      if count == 1:
-        return "%d bug" % count
-      else:
-        return "%d bugs" % count
-
-    def crash(count):
-      if count == 1:
-        return "%d crash" % count
-      else:
-        return "%d crashes" % count
-
-    start = ""
-    bugs_reported = " - %s reported\n"
-    bugs_closed = " - %s closed\n"
-    bugs_cl_useful =  "   - %s (%d%%) as fixed, so ABRT was useful\n"
-    bugs_cl_notuseful = "   - %s (%d%%) as duplicate, can't fix, insuf. data, so ABRT was not useful\n"
-    bugs_cl_other = "   - %s (%d%%) as notabug, wontfix, worksforme\n"
-    bugs_closed_end = ""
-    top_crashers = " - top crashers:\n"
-    top_crasher_item = "    # %s: %s\n"
-    top_crashers_end = ""
-    end = ""
-    if options.html:
-      start = "<ul>\n"
-      bugs_reported = "<li>%s reported</li>\n"
-      bugs_closed = "<li>%s closed\n<ul>\n"
-      bugs_cl_useful = "  <li>%s (%d%%) as fixed, so ABRT was useful</li>\n"
-      bugs_cl_notuseful = "   <li>%s (%d%%) as duplicate, can't fix, insuf. data, so ABRT was not useful</li>\n"
-      bugs_cl_other = "   <li>%s (%d%%) as notabug, wontfix, worksforme</li>\n"
-      bugs_closed_end = "</ul></li>\n"
-      top_crashers = "<li>top crashers:\n<ol>\n"
-      top_crasher_item = "    <li>%s: %s</li>\n"
-      top_crashers_end = "</ol></li>\n"
-      end = "</ul>\n"
-    elif options.wiki:
-      start = ""
-      bugs_reported = "* %s reported\n"
-      bugs_closed = "* %s closed\n"
-      bugs_cl_useful =  "** %s (%d%%) as fixed, so ABRT was useful\n"
-      bugs_cl_notuseful = "** %s (%d%%) as duplicate, can't fix, insuf. data, so ABRT was not useful\n"
-      bugs_cl_other = "** %s (%d%%) as notabug, wontfix, worksforme\n"
-      bugs_closed_end = ""
-      top_crashers = "* top crashers:\n"
-      top_crasher_item = "*# %s: %s\n"
-      top_crashers_end = ""
-      end = ""
-
-
-    str = start
-    str += bugs_reported % bug(self.bugs_reported())
-    if self.closed() > 0:
-      str += bugs_closed % bug(self.closed())
-      if self.closed_as_useful > 0:
-        str += bugs_cl_useful % (bug(self.closed_as_useful), self.closed_as_useful_percentage())
-      if self.closed_as_waste > 0:
-        str += bugs_cl_notuseful % (bug(self.closed_as_waste), self.closed_as_waste_percentage())
-      if self.closed_as_other > 0:
-        str += bugs_cl_other % (bug(self.closed_as_other), self.closed_as_other_percentage())
-      str += bugs_closed_end
-    if len(self.top_crashers()) > 0:
-      str += top_crashers
-      for (component, num_crashes) in self.top_crashers():
-        str += top_crasher_item % (component, crash(num_crashes))
-      str += top_crashers_end
-    str += end
-    return str
-
-monthly_stats = {} # key == YEAR-MONTH, value == Month()
-weekly_stats = {} # key == YEAR-WEEK, value == Month()
-
-def get_month(month):
-  global monthly_stats
-  if month in monthly_stats:
-    return monthly_stats[month]
-  else:
-    monthly_stats[month] = TimeSpan()
-    return monthly_stats[month]
-
-def get_week(week):
-  global weekly_stats
-  if week in weekly_stats:
-    return weekly_stats[week]
-  else:
-    weekly_stats[week] = TimeSpan()
-    return weekly_stats[week]
-
-for buginfo in buginfos_loaded.values():
-  # Bugs reported this month by ABRT
-  # Top crashers this month
-  month_key = buginfo['created'][0:7]
-  month = get_month(month_key)
-  month.add_component_crash(buginfo['component'])
-
-  # Bugs reported this week by ABRT
-  # Top crashers this week
-  week_key = datetime.strptime(buginfo['created'], "%Y-%m-%d").strftime("%Y-%W")
-  week = get_week(week_key)
-  week.add_component_crash(buginfo['component'])
-
-  # Bugs closed as useful this month by ABRT
-  # Bugs closed as waste this month by ABRT
-  month_key = buginfo['lastchange'][0:7]
-  month = get_month(month_key)
-  month.add_resolution(buginfo['status'])
-
-  # Bugs closed as useful this week by ABRT
-  # Bugs closed as waste this week by ABRT
-  week_key = datetime.strptime(buginfo['lastchange'], "%Y-%m-%d").strftime("%Y-%W")
-  week = get_week(week_key)
-  week.add_resolution(buginfo['status'])
-
-#
-# Print interpreted data
-#
-print "STATS"
-print "=========================================================================="
-if not options.weekly:
-  months = monthly_stats.keys()
-  months.sort()
-  if options.reversed:
-    months.reverse()
-  for month in months:
-    m = monthly_stats[month]
-    if options.html:
-      print "<h2>Month %s</h2>" % month
-    elif options.wiki:
-      print "==Month %s==" % month
-    else:
-      print "MONTH %s" % month
-    print m
-else:
-  weeks = weekly_stats.keys()
-  weeks.sort()
-  if options.reversed:
-    weeks.reverse()
-  for week in weeks:
-    w = weekly_stats[week]
-    if options.html:
-      print "<h2>Week %s</h2>" % week
-    elif options.wiki:
-      print "==Week %s==" % week
-    else:
-      print "WEEK %s" % week
-    print w
diff --git a/scripts/check-bt-parsability b/scripts/check-bt-parsability
deleted file mode 100755
index b154ad8..0000000
--- a/scripts/check-bt-parsability
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash
-# -*- mode: bash -*-
-
-PASS=0
-FAIL=0
-for file in *.bt
-do
-  #echo "$file"
-  ./abrt-backtrace $file 1> /dev/null
-  if [ "$?" -eq "0" ]
-  then
-      echo -n "."
-      PASS=$(($PASS+1))
-  else
-      echo "-$file"
-      FAIL=$(($FAIL+1))
-  fi
-done
-echo ""
-echo "Passed $PASS and failed $FAIL."
diff --git a/src/Makefile.am b/src/Makefile.am
index c2576c4..f4f621c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1 +1 @@
-SUBDIRS = hooks daemon applet gui cli utils
+SUBDIRS = hooks daemon applet gui cli
diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am
deleted file mode 100644
index 29e0664..0000000
--- a/src/utils/Makefile.am
+++ /dev/null
@@ -1,11 +0,0 @@
-bin_PROGRAMS = abrt-backtrace
-abrt_backtrace_CFLAGS = -Wall
-abrt_backtrace_SOURCES = abrt-backtrace.c
-abrt_backtrace_CPPFLAGS = \
-    -I$(srcdir)/../../inc \
-    -I$(srcdir)/../../lib/utils
-abrt_backtrace_LDADD = \
-    ../../lib/utils/libABRTUtils.la
-
-man_MANS = abrt-backtrace.1
-EXTRA_DIST = $(man_MANS)
diff --git a/src/utils/abrt-backtrace.1 b/src/utils/abrt-backtrace.1
deleted file mode 100644
index 4383f1d..0000000
--- a/src/utils/abrt-backtrace.1
+++ /dev/null
@@ -1,59 +0,0 @@
-.TH abrt\-backtrace "1" "23 Nov 2009" ""
-.SH NAME
-abrt\-backtrace \- a backtrace analyzer for abrt
-.SH SYNOPSIS
-.B abrt\-backtrace
-[option]... [FILE]
-.SH DESCRIPTION
-.I abrt\-backtrace
-is a command line tool that analyzes backtraces produced by
-GDB and provides their textual representation useful for
-crash duplication detection.
-
-By default, abrt\-backtrace prints the backtrace tree created by
-parsing the input file.
-
-.SH OPTIONS
-.B Basic startup options
-.IP "\-V, \-\-version"
-Displays version of abrt\-backtrace.
-.IP "\-?, \-\-help"
-Print a help message describing all of abrt-backtrace’s command-line options.
-
-.PP
-.B Actions
-.IP "\-i, \-\-independent"
-Prints independent backtrace fallback. The "independent backtrace"
-is used as a fallback internal representation of backtrace
-when the internal parser fails to process the input due to
-unsupported format.
-
-.PP
-.B Various options
-.IP "\-n, \-\-single\-thread"
-Removes all threads except the one that caused the crash from
-the internal representation of the backtrace.
-.IP "\-d=N, \-\-frame\-depth=N"
-Display only the top N frames in every thread.
-Frames that are a part of system error handling do not count to the N.
-So more than N frames can be displayed, but N of them are useful for examination.
-N must be larger than 1.
-.IP "\-r, \-\-remove\-exit\-handlers"
-Do not display exit handlers and frames that comes after them in the backtrace.
-.IP "\-m, \-\-remove\-noncrash\-frames"
-Do not display frames known as not causing the crash, but which are a common 
-part of backtraces.
-.IP "\-a, \-\-rate"
-Print backtrace rating from 0 to 4.
-.IP "\-c, \-\-crash\-function"
-Print crash function if it's successfully detected.
-.IP "\-p, \-\-debug\-parser"
-Prints debug information when parsing the backtrace.
-.IP "\-s, \-\-debug\-scanner"
-Prints debug information when scanning the input file for the parser.
-
-.SH "SEE ALSO"
-.IR abrtd (8),
-.IR abrt.conf (5),
-.IR abrt-cli (1),
-.IR abrt-plugins (7)
diff --git a/src/utils/abrt-backtrace.c b/src/utils/abrt-backtrace.c
deleted file mode 100644
index d02c963..0000000
--- a/src/utils/abrt-backtrace.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
-    abrt-backtrace.c - parses command line arguments
-
-    Copyright (C) 2009  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 <argp.h>
-#include <stdlib.h>
-#include <sysexits.h>
-#include <string.h>
-#include "config.h"
-#include "backtrace.h"
-#include "strbuf.h"
-
-/* Too large files are trimmed. */
-#define FILE_SIZE_LIMIT 20000000 /* ~ 20 MB */
-
-#define EX_PARSINGFAILED EX__MAX + 1  /* = 79 */
-#define EX_THREADDETECTIONFAILED EX__MAX + 2 /* = 80 */
-
-const char *argp_program_version = "abrt-backtrace " VERSION;
-const char *argp_program_bug_address = "<crash-catcher@lists.fedorahosted.org>";
-
-static char doc[] = "abrt-backtrace -- backtrace analyzer";
-
-/* A description of the arguments we accept. */
-static char args_doc[] = "FILE";
-
-static struct argp_option options[] = {
-    {"independent"           , 'i', 0  , 0, "Prints independent backtrace (fallback)"},
-    {"single-thread"         , 'n', 0  , 0, "Display the crash thread only in the backtrace"},
-    {"frame-depth"           , 'd', "N", 0, "Display only top N frames under the crash frame"},
-    {"remove-exit-handlers"  , 'r', 0  , 0, "Removes exit handler frames from the displayed backtrace"},
-    {"remove-noncrash-frames", 'm', 0  , 0, "Removes common frames known as not causing crash"},
-    {"rate"                  , 'a', 0  , 0, "Prints the backtrace rating from 0 to 4"},
-    {"crash-function"        , 'c', 0  , 0, "Prints crash function"},
-    {"debug-parser"          , 'p', 0  , 0, "Prints parser debug information"},
-    {"debug-scanner"         , 's', 0  , 0, "Prints scanner debug information"},
-    {"verbose"               , 'v', 0  , 0, "Prints human-friendly superfluous output."},
-  { 0 }
-};
-
-struct arguments
-{
-    bool independent;
-    bool single_thread;
-    int frame_depth; /* negative == do not limit the depth */
-    bool remove_exit_handlers;
-    bool remove_noncrash_frames;
-    bool debug_parser;
-    bool debug_scanner;
-    bool verbose;
-    bool rate;
-    bool crash_function;
-    char *filename;
-};
-
-static error_t
-parse_opt (int key, char *arg, struct argp_state *state)
-{
-    /* Get the input argument from argp_parse, which we
-       know is a pointer to our arguments structure. */
-    struct arguments *arguments = (struct arguments*)state->input;
-
-    switch (key)
-    {
-    case 'i': arguments->independent = true; break;
-    case 'n': arguments->single_thread = true; break;
-    case 'd':
-        if (1 != sscanf(arg, "%d", &arguments->frame_depth))
-        {
-            /* Must be a number. */
-            argp_usage(state);
-            exit(EX_USAGE); /* Invalid argument */
-        }
-        break;
-    case 'r': arguments->remove_exit_handlers = true; break;
-    case 'm': arguments->remove_noncrash_frames = true; break;
-    case 'p': arguments->debug_parser = true; break;
-    case 's': arguments->debug_scanner = true; break;
-    case 'v': arguments->verbose = true; break;
-    case 'a': arguments->rate = true; break;
-    case 'c': arguments->crash_function = true; break;
-
-    case ARGP_KEY_ARG:
-        if (arguments->filename)
-        {
-            /* Too many arguments. */
-            argp_usage(state);
-            exit(EX_USAGE); /* Invalid argument */
-        }
-        arguments->filename = arg;
-        break;
-
-    case ARGP_KEY_END:
-        break;
-
-    default:
-        return ARGP_ERR_UNKNOWN;
-    }
-    return 0;
-}
-
-/* Our argp parser. */
-static struct argp argp = { options, parse_opt, args_doc, doc };
-
-#define PYTHON_BACKTRACE_ID1 "\n\nTraceback (most recent call last):\n"
-#define PYTHON_BACKTRACE_ID2 "\n\nLocal variables in innermost frame:\n"
-
-int main(int argc, char **argv)
-{
-    /* Set options default values and parse program command line. */
-    struct arguments arguments;
-    arguments.independent = false;
-    arguments.frame_depth = -1;
-    arguments.single_thread = false;
-    arguments.remove_exit_handlers = false;
-    arguments.remove_noncrash_frames = false;
-    arguments.debug_parser = false;
-    arguments.debug_scanner = false;
-    arguments.verbose = false;
-    arguments.filename = 0;
-    arguments.rate = false;
-    arguments.crash_function = false;
-    argp_parse(&argp, argc, argv, 0, 0, &arguments);
-
-    /* If we are about to rate a backtrace, the other values must be set accordingly,
-       no matter what the user set on the command line. */
-    if (arguments.rate)
-    {
-        arguments.independent = false;
-        arguments.frame_depth = 5;
-        arguments.single_thread = true;
-        arguments.remove_exit_handlers = true;
-        arguments.remove_noncrash_frames = true;
-    }
-
-    /* If we are about to print the crash function, the other values must be set 
-       accordingly. */
-    if (arguments.crash_function)
-    {
-        arguments.independent = false;
-        arguments.single_thread = true;
-    }
-
-    char *bttext = NULL;
-
-    /* If a filename was provided, read input from file.
-       Otherwise read from stdin. */
-    if (arguments.filename)
-    {
-        /* Open input file, and parse it. */
-        FILE *fp = fopen(arguments.filename, "r");
-        if (!fp)
-        {
-            fprintf(stderr, "Unable to open '%s'.\n", arguments.filename);
-            exit(EX_NOINPUT); /* No such file or directory */
-        }
-
-        /* Header and footer of the backtrace is stripped to simplify the parser.
-         * A drawback is that the backtrace must be loaded to memory.
-         */
-        fseek(fp, 0, SEEK_END);
-        size_t size = ftell(fp);
-        fseek(fp, 0, SEEK_SET);
-
-        if (size > FILE_SIZE_LIMIT)
-        {
-            fprintf(stderr, "Input file too big (%zd). Maximum size is %d.\n",
-                    size, FILE_SIZE_LIMIT);
-            exit(EX_IOERR);
-        }
-
-        /* Handle the case that the input file is empty.
-         * The code is not designed to support completely empty backtrace.
-         * Silently exit indicating success.
-         */
-        if (size == 0)
-        {
-            fclose(fp);
-            exit(0);
-        }
-
-        bttext = malloc(size + 1);
-        if (!bttext)
-        {
-            fclose(fp);
-            fputs("malloc failed", stderr);
-            exit(EX_OSERR);
-        }
-
-        if (1 != fread(bttext, size, 1, fp))
-        {
-            fclose(fp);
-            fprintf(stderr, "Unable to read from '%s'.\n", arguments.filename);
-            exit(EX_IOERR); /* IO Error */
-        }
-
-        bttext[size] = '\0';
-        fclose(fp);
-    }
-    else
-    {
-        struct strbuf *btin = strbuf_new();
-        int c;
-        while ((c = getchar()) != EOF && c != '\0')
-            strbuf_append_char(btin, (char)c);
-
-        strbuf_append_char(btin, '\0');
-        bttext = btin->buf;
-        strbuf_free_nobuf(btin); /* free btin, but not its internal buffer */
-    }
-
-    /* Detect Python backtraces. If it is a Python backtrace,
-     * silently exit for now.
-     */
-    if (strstr(bttext, PYTHON_BACKTRACE_ID1) != NULL
-        && strstr(bttext, PYTHON_BACKTRACE_ID2) != NULL)
-    {
-        if (arguments.rate)
-            puts("4");
-        exit(0);
-    }
-
-    /* Print independent backtrace and exit. */
-    if (arguments.independent)
-    {
-        struct strbuf *ibt = independent_backtrace(bttext);
-        puts(ibt->buf);
-        strbuf_free(ibt);
-        free(bttext);
-        return 0; /* OK */
-    }
-
-    /* Try to parse the backtrace. */
-    struct backtrace *backtrace;
-    backtrace = backtrace_parse(bttext, arguments.debug_parser, arguments.debug_scanner);
-
-    /* If the parser failed print independent backtrace. */
-    if (!backtrace)
-    {
-        if (arguments.rate)
-        {
-            free(bttext);
-            puts("0");
-            /* Parsing failed, but the output can be used. */
-            return EX_PARSINGFAILED;
-        }
-        struct strbuf *ibt = independent_backtrace(bttext);
-        puts(ibt->buf);
-        strbuf_free(ibt);
-        free(bttext);
-        /* Parsing failed, but the output can be used. */
-        return EX_PARSINGFAILED;
-    }
-
-    free(bttext);
-
-    /* [--rate] Get the quality of the full backtrace. */
-    float q1 = backtrace_quality(backtrace);
-
-    /* If a single thread is requested, remove all other threads. */
-    int retval = 0;
-    struct thread *crash_thread = NULL;
-    if (arguments.single_thread)
-    {
-        crash_thread = backtrace_find_crash_thread(backtrace);
-        if (crash_thread)
-            backtrace_remove_threads_except_one(backtrace, crash_thread);
-        else
-        {
-            fprintf(stderr, "Detection of crash thread failed.\n");
-            /* THREAD DETECTION FAILED, BUT THE OUTPUT CAN BE USED */
-            retval = EX_THREADDETECTIONFAILED;
-        }
-    }
-
-    /* [--rate] Get the quality of the crash thread. */
-    float q2 = backtrace_quality(backtrace);
-
-    if (arguments.remove_noncrash_frames)
-        backtrace_remove_noncrash_frames(backtrace);
-
-    /* If a frame removal is requested, do it now. */
-    if (arguments.frame_depth > 0)
-        backtrace_limit_frame_depth(backtrace, arguments.frame_depth);
-
-    /* Frame removal can be done before removing exit handlers */
-    if (arguments.remove_exit_handlers > 0)
-        backtrace_remove_exit_handlers(backtrace);
-
-    /* [--rate] Get the quality of frames around the crash. */
-    float q3 = backtrace_quality(backtrace);
-
-    if (arguments.rate)
-    {
-        /* Compute and store backtrace rating. */
-        /* Compute and store backtrace rating. The crash frame
-           is more important that the others. The frames around
-           the crash are more important than the rest.  */
-        float qtot = 0.25f * q1 + 0.35f * q2 + 0.4f * q3;
-
-        /* Turn the quality to rating. */
-        const char *rating;
-        if (qtot < 0.6f)      rating = "0";
-        else if (qtot < 0.7f) rating = "1";
-        else if (qtot < 0.8f) rating = "2";
-        else if (qtot < 0.9f) rating = "3";
-        else                  rating = "4";
-        puts(rating);
-    }
-
-    if (arguments.crash_function && crash_thread)
-    {
-        struct frame *crash_frame = crash_thread->frames;
-        struct frame *abort_frame = thread_find_abort_frame(crash_thread);
-        if (abort_frame)
-            crash_frame = abort_frame->next;
-        if (crash_frame && crash_frame->function)
-            puts(crash_frame->function);
-    }
-
-    backtrace_print_tree(backtrace, arguments.verbose);
-    backtrace_free(backtrace);
-    return retval;
-}
-- 
1.7.2.3

