void gt_pck_count_nodes_dfs(const FMindex *index,
                        GtUword totallength,
                        unsigned int numofchars)
{
  GtStackNodecount stack;
  Nodecount root;
  Nodecount *current;
  Mbtab *tmpmbtab;
  GtUword *rangeOccs;
  GtUword resize = 128UL; /* TODO DW make this user definable, or dependable
                             on input data */

  GT_STACK_INIT(&stack, resize);
  rangeOccs = gt_malloc(sizeof (*rangeOccs) * GT_MULT2(numofchars));
  tmpmbtab = gt_malloc(sizeof (*tmpmbtab) * numofchars);

  root.lower = 0UL;
  root.upper = totallength + 1;
  root.leaves = 0UL;
  root.branching = 1UL;
  root.parentOffset = 0U;
  root.visited = false;
  root.on_branch = false;

  GT_STACK_PUSH(&stack, root);

  while (!GT_STACK_ISEMPTY(&stack))
  {
    current = &(stack.space[stack.nextfree -1]);
    if (current->visited)
    {
      current = &(GT_STACK_POP(&stack));
      if GT_STACK_ISEMPTY(&stack)
      {
        /* TODO DW change to gt_loger_log */
        gt_log_log("on root:\n "GT_WU" branching nodes\n "GT_WU" leaves\n",
           current->branching, current->leaves);
      }
      else
      {
        process_count_node(&stack, current);
      }
    }
static void gt_radixsort_inplace(GtRadixsortinfo *radixsortinfo,
                                 GtRadixvalues *radixvalues,
                                 GtUword len)
{
  const size_t shift = (sizeof (GtUword) - 1) * CHAR_BIT;
#ifdef GT_THREADS_ENABLED
  const unsigned int threads = GT_THREADS_JOBS;
#else
  const unsigned int threads = 1U;
#endif

  if (len > (GtUword) GT_COUNTBASETYPE_MAX)
  {
    fprintf(stderr,"%s, line %d: assertion failed: if you want to sort arrays "
                    "of length > 2^{32}-1, then recompile code by setting "
                   "#define GT_RADIX_LARGEARRAYS\n",__FILE__,__LINE__);
    exit(GT_EXIT_PROGRAMMING_ERROR);
  }
  gt_assert(radixsortinfo != NULL);
  if (radixsortinfo->pairs)
  {
    gt_radixsort_ulongpair_shuffle(radixsortinfo->rbuf,
                                   radixvalues->ulongpairptr,
                                   (GtCountbasetype) len,shift);
  } else
  {
    gt_radixsort_ulong_shuffle(radixsortinfo->rbuf,radixvalues->ulongptr,
                               (GtCountbasetype) len,shift);
  }
  GT_STACK_MAKEEMPTY(&radixsortinfo->stack);
  if (radixsortinfo->pairs)
  {
    gt_radixsort_ulongpair_process_bin(&radixsortinfo->stack,
                                       radixsortinfo->rbuf,
                                       radixvalues->ulongpairptr,
                                       shift);
  } else
  {
    gt_radixsort_ulong_process_bin(&radixsortinfo->stack,
                                   radixsortinfo->rbuf,
                                   radixvalues->ulongptr,shift);
  }
  if (threads == 1U || radixsortinfo->stack.nextfree < (GtUword) threads)
  {
    if (radixsortinfo->pairs)
    {
      gt_radixsort_ulongpair_sub_inplace(radixsortinfo->rbuf,
                                         &radixsortinfo->stack);
    } else
    {
      gt_radixsort_ulong_sub_inplace(radixsortinfo->rbuf,&radixsortinfo->stack);
    }
  } else
  {
#ifdef GT_THREADS_ENABLED
    GtUword last = 0, j;
    unsigned int t;

    gt_assert(radixsortinfo->stack.nextfree <= UINT8_MAX+1);
    for (j=0; j<radixsortinfo->stack.nextfree; j++)
    {
      radixsortinfo->lentab[j] = (GtUword)
                                              radixsortinfo->stack.space[j].len;
    }
    gt_evenly_divide_lentab(radixsortinfo->endindexes,
                            radixsortinfo->lentab,
                            radixsortinfo->stack.nextfree,len,threads);
    for (t = 0; t < threads; t++)
    {
      GT_STACK_MAKEEMPTY(&radixsortinfo->threadinfo[t].stack);
      for (j = last; j <= radixsortinfo->endindexes[t]; j++)
      {
        GT_STACK_PUSH(&radixsortinfo->threadinfo[t].stack,
                      radixsortinfo->stack.space[j]);
      }
      last = radixsortinfo->endindexes[t] + 1;
      radixsortinfo->threadinfo[t].thread
        = gt_thread_new (gt_radixsort_thread_caller,
                         radixsortinfo->threadinfo + t,NULL);
      gt_assert (radixsortinfo->threadinfo[t].thread != NULL);
    }
    for (t = 0; t < threads; t++)
    {
      gt_thread_join(radixsortinfo->threadinfo[t].thread);
      gt_thread_delete(radixsortinfo->threadinfo[t].thread);
    }
#endif
  }
}
static void visit_count_children(const FMindex *index,
                           Nodecount *parent,
                           GtStackNodecount *stack,
                           Mbtab *tmpmbtab,
                           GtUword *rangeOccs,
                           GT_UNUSED unsigned int numofchars)
{
  GtUword rangesize, idx, num_special;
  unsigned int offset;
  Nodecount child;

  gt_assert(parent->lower < parent->upper);
  rangesize = gt_bwtrangesplitallwithoutspecial(tmpmbtab,
                                             rangeOccs,
                                             index,
                                             parent->lower,
                                             parent->upper);
  gt_assert(rangesize <= (GtUword) numofchars);

  offset = 0U;
  num_special = parent->upper - parent->lower;
  for (idx = 0; idx < rangesize; idx++)
  {
    child.lower = tmpmbtab[idx].lowerbound;
    child.upper = tmpmbtab[idx].upperbound;
    child.leaves = 0UL;
    child.branching = 1UL;
    child.parentOffset = offset + 1U;
    child.visited = false;
    child.on_branch = false;

    /* check if child is part of a branch */
    if (child.upper - child.lower == parent->upper - parent->lower)
    {
      /* TODO DW do sth with non branching nodes */
      child.on_branch = true;
      parent->branching--;
      GT_STACK_PUSH(stack, child);
      num_special = 0UL;
      offset++;
    }
    else
    {
      /* we found a leave on parent*/
      if (child.lower + 1 == child.upper)
      {
        parent->leaves++;
        num_special--;
      }
      else
        /* child is a branch of parent node */
      {
        if (child.lower == child.upper)
        {
          /* do nothing, this is no node, this is a missing char */
        }
        else
        {
          GT_STACK_PUSH(stack, child);
          offset++;
          num_special -= (child.upper - child.lower);
        }
      }
    }
  }
  parent->leaves += num_special;
}