#ifndef BALL_DATATYPE_LISTSORT_MAC
#define BALL_DATATYPE_LISTSORT_MAC

#ifndef BALL_COMMON_H
#	include <BALL/common.h>
#endif

#ifndef BALL_CONCEPT_COMPARATOR_H
#	include <BALL/CONCEPT/comparator.h>
#endif

/* Sorts the null-terminated list that has head as the first */
/* node. Passes back the new head, as well as a pointer      */
/* to the last node (so you that you can make the list       */
/* circular afterwards if you want to.)                      */
/* adapted from: Practical Algorithms in C++, Bryan Flamig,  */
/*               John Wiley & Sons, Inc., 1993               */

///
#define BALL_IMPLEMENT_BALANCED_2_WAY_SINGLE_LINKED_LIST_MERGE_SORT(NodeType, next, head, tail, Comparator)\
{ \
  if (head == 0 \
      || head->next == 0) \
  { \
    return; \
  } \
 \
  NodeType heads[4]; \
  NodeType *tmp = 0; \
  NodeType *ih = heads; \
  NodeType *oh = heads + 2; \
  NodeType *a = head; \
  NodeType *b = head->next->next; \
  NodeType *c = 0; \
  NodeType *d = 0; \
  long a_cnt, b_cnt; \
  long n; \
 \
  while(b) \
  { \
    a = a->next; \
    b = b->next; \
    if (b) \
    { \
      b = b->next; \
    } \
  } \
 \
  ih->next = head; \
  (ih + 1)->next = a->next; \
  a->next = 0; \
 \
  for (n = 1; ; n <<= 1) \
  { \
    a = ih->next; \
    b = (ih + 1)->next; \
    if (b == 0) \
    { \
      break; \
    } \
    d = (c = oh) + 1; \
    a_cnt = b_cnt = 0; \
 \
    for (;;) \
    { \
      if (a_cnt >= 0) \
      { \
				a_cnt = n; \
      } \
 \
      if (b_cnt >= 0) \
      { \
				b_cnt = n; \
      } \
 \
      for (;;) \
      { \
        if (a_cnt > 0 \
						&& (b_cnt < 1 \
						|| (Comparator).isLessOrEqual(a, b))) \
				{ \
           c = c->next = a; \
					 a = a->next; \
											  \
           if (a == 0) \
				   { \
						 a_cnt = -1; \
				   } \
				   else \
				   { \
						 a_cnt--; \
				   } \
        } \
        else \
				{ \
				  if (b_cnt < 1) \
				  { \
				    break; \
				  } \
						 \
				  c = c->next = b; \
				  b = b->next; \
				  if (b == 0) \
				  { \
				    b_cnt = -1; \
				  } \
				  else \
				  { \
						b_cnt--; \
				  } \
        } \
      } \
			 \
      if (a_cnt < 0 \
				  && b_cnt < 0) \
      { \
				break; \
      } \
			 \
      tmp = c; \
      c = d; \
      d = tmp; \
    } \
		 \
    c->next = d->next = 0; \
		 \
    tmp = ih; \
    ih = oh; \
    oh = tmp; \
  } \
	 \
  head = a; \
  tail = c; \
}

#endif // BALL_DATATYPE_LISTSORT_MAC
