#ifdef DOC_BUILD_INTERNAL
#endif
#include "list.h"
void list_Free(MEMORY Memory, LIST L)
{
  memory_Free(Memory, L, sizeof(LIST_NODE));
}
LIST list_Nil(void)
{
  return NULL;
}
BOOL list_Empty(LIST L)
{
  return L == NULL;
}
BOOL list_Exist(LIST L)
{
  return L != NULL;
}
POINTER list_Car(LIST L)
{
  return L->car;
}
POINTER list_NCar(MEMORY Memory, LIST *L)
{
  POINTER Result;
  LIST Help;
  Result = (*L)->car;
  Help = (*L)->cdr;
  list_Free(Memory, *L);
  *L = Help;
  return Result;
}
LIST list_Cdr(LIST L)
{
  return L->cdr;
}
POINTER list_First(LIST L)
{
  return list_Car(L);
}
POINTER list_Second(LIST L)
{
  return list_Car(list_Cdr(L));
}
POINTER list_Third(LIST L)
{
  return list_Car(list_Cdr(list_Cdr(L)));
}
POINTER list_Fourth(LIST L)
{
  return(list_Third(list_Cdr(L)));
}
POINTER list_Fifth(LIST L)
{
  return(list_Fourth(list_Cdr(L)));
}
void list_Rplacd(LIST L1, LIST L2)
{
  L1->cdr = L2;
}
void list_Rplaca(LIST L, POINTER P)
{
  L->car = P;
}
void list_RplacSecond(LIST L, POINTER P)
{
  list_Rplaca(list_Cdr(L), P);
}
LIST list_Cons(MEMORY Memory, POINTER Ptr, const LIST List)
{
  LIST Cell;
  Cell = (LIST)memory_Malloc(Memory, sizeof(LIST_NODE));
  Cell->car = Ptr;
  Cell->cdr = List;
  return Cell;
}
LIST list_List(MEMORY Memory, POINTER P)
{
  return list_Cons(Memory, P, list_Nil());
}
LIST list_Append(MEMORY Memory, LIST List1, LIST List2)
{
  LIST Result;
  if (list_Empty(List1))
    return List2;
  if (list_Empty(List2))
    return list_Copy(Memory, List1);
  Result = list_Copy(Memory, List1);
  for (List1 = Result; !list_Empty(list_Cdr(List1)); List1 = list_Cdr(List1))
               ;
  List1->cdr = List2;
  return Result;
}
void list_Delete(MEMORY Memory, LIST L)
{
  LIST Current;
  Current = L;
  while (!list_Empty(Current)) {
    L = list_Cdr(L);
    list_Free(Memory, Current);
    Current = L;
  }
}
BOOL list_Member(LIST List, POINTER Element,
       BOOL (*Test)(POINTER, POINTER))
{
  while (!list_Empty(List)) {
    if (Test(Element, list_Car(List)))
      return TRUE;
    List = list_Cdr(List);
  }
  return FALSE;
}
POINTER list_GetMember(LIST List, POINTER Element,
       BOOL (*Test)(POINTER, POINTER))
{
  while (!list_Empty(List)) {
    if (Test(Element, list_Car(List)))
      return list_Car(List);
    List = list_Cdr(List);
  }
  return NULL;
}
BOOL list_PointerMember(LIST List, POINTER Element)
{
  while (!list_Empty(List)) {
    if (Element == list_Car(List))
      return TRUE;
    List = list_Cdr(List);
  }
  return FALSE;
}
LIST list_StackBottom(void)
{
  return list_Nil();
}
BOOL list_StackEmpty(LIST S)
{
  return list_Empty(S);
}
LIST list_Push(MEMORY Memory, POINTER I, LIST L)
{
  return list_Cons(Memory, I, L);
}
POINTER list_Top(LIST L)
{
  return list_Car(L);
}
LIST list_Pop(MEMORY Memory, LIST L)
{
  LIST Aux = L;
  L = list_Cdr(L);
  list_Free(Memory, Aux);
  return L;
}
void list_RplacTop(LIST L, POINTER P)
{
  list_Rplaca(L, P);
}
LIST list_StackFree(MEMORY Memory, LIST L)
{
  while (!list_StackEmpty(L))
    L = list_Pop(Memory, L);
  return list_Nil();
}
LIST list_PairNull(void)
{
  return list_Nil();
}
LIST list_PairCreate(MEMORY Memory, POINTER P1, POINTER P2)
{
  return list_Cons(Memory, P1, P2);
}
void list_PairFree(MEMORY Memory, LIST L)
{
  list_Free(Memory, L);
}
POINTER list_PairFirst(LIST L)
{
  return list_Car(L);
}
POINTER list_PairSecond(LIST L)
{
  return (POINTER)list_Cdr(L);
}
void list_PairRplacSecond(LIST L, POINTER P)
{
  list_Rplacd(L,P);
}
void list_DeletePairList(MEMORY Memory, LIST L)
{
  list_DeleteWithElement(Memory, L, (void (*)(MEMORY, POINTER))list_PairFree);
}
void list_DeleteDistribution(MEMORY Memory, LIST L)
{
  list_DeletePairList(Memory, L);
}
LIST list_AssocCons(MEMORY Memory, LIST L, POINTER Key, POINTER Value)
{
  return list_Cons(Memory, list_PairCreate(Memory, Key, Value), L);
}
LIST list_Copy(MEMORY Memory, const LIST List)
{
  LIST Copy;
  LIST Scan1,Scan2;
  if (list_Empty(List))
    return list_Nil();
  Copy = list_List(Memory, list_Car(List));
  Scan1 = Copy;
  Scan2 = list_Cdr(List);
  while (!list_Empty(Scan2)) {
    list_Rplacd(Scan1, list_List(Memory, list_Car(Scan2)));
    Scan1 = list_Cdr(Scan1);
    Scan2 = list_Cdr(Scan2);
  }
  return Copy;
}
LIST list_CopyWithElement(MEMORY Memory, const LIST List, POINTER (*CopyElement)(MEMORY, POINTER))
{
  LIST Copy;
  LIST Scan1,Scan2;
  if (list_Empty(List))
    return list_Nil();
  Copy = list_List(Memory, CopyElement(Memory, list_Car(List)));
  Scan1 = Copy;
  Scan2 = list_Cdr(List);
  while (!list_Empty(Scan2)) {
    list_Rplacd(Scan1, list_List(Memory, CopyElement(Memory, list_Car(Scan2))));
    Scan1 = list_Cdr(Scan1);
    Scan2 = list_Cdr(Scan2);
  }
  return Copy;
}
void list_InsertNext(MEMORY Memory, LIST List, POINTER Pointer)
{
#ifdef CHECK
  if (Pointer == NULL) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: NULL Pointer. ", __func__);
    misc_FinishErrorReport();
  }
#endif
  list_Rplacd(List, list_Cons(Memory, Pointer, list_Cdr(List)));
}
void list_NMapCar(LIST List, POINTER (*ElementFunc)(POINTER))
{
  LIST Scan;
  for (Scan = List; !list_Empty(Scan); Scan = list_Cdr(Scan))
    list_Rplaca(Scan, ElementFunc(list_Car(Scan)));
}
void list_Apply(void (*Function)(POINTER), LIST List)
{
  while (!list_Empty(List)) {
    Function(list_Car(List));
    List = list_Cdr(List);
  }
}
LIST list_Reverse(MEMORY Memory, const LIST List)
{
  LIST ReverseList;
  LIST Scan;
  ReverseList = list_Nil();
  for (Scan=List;!list_Empty(Scan);Scan=list_Cdr(Scan))
    ReverseList = list_Cons(Memory, list_Car(Scan), ReverseList);
  return ReverseList;
}
LIST list_NReverse(MEMORY Memory, LIST List)
{
  LIST ReverseList;
  LIST Scan, Result;
  if (list_Empty(List) || list_Empty(list_Cdr(List)))
    return List;
  Result = List;
  List = list_List(Memory, list_Car(List));
  list_Rplacd(List,list_Cdr(Result));
  ReverseList = list_Nil();
  while (!list_Empty(List)) {
    Scan = list_Cdr(List);
    list_Rplacd(List, ReverseList);
    ReverseList = List;
    List = Scan;
  }
  list_Rplaca(Result,list_Car(ReverseList));
  list_Rplacd(Result,list_Cdr(ReverseList));
  list_Free(Memory, ReverseList);
  return Result;
}
static BOOL list_PointerLower (POINTER A, POINTER B)
{
  return (NAT) A < (NAT) B;
}
LIST list_PointerSort(LIST List)
{
  return list_Sort(List, list_PointerLower);
}
BOOL list_SortedInOrder(LIST L, BOOL (*Test)(POINTER, POINTER))
{
  LIST Scan1, Scan2;
  if (!(list_Empty(L) || list_Empty(list_Cdr(L)))) {
    Scan1 = L;
    Scan2 = list_Cdr(Scan1);
    do {
      if (!Test(list_Car(Scan1), list_Car(Scan2)) &&
   Test(list_Car(Scan2), list_Car(Scan1)))
 return FALSE;
      Scan1 = list_Cdr(Scan1);
      Scan2 = list_Cdr(Scan1);
    } while (!list_Empty(Scan2));
  }
  return TRUE;
}
LIST list_Merge(LIST List1, LIST List2, BOOL (*Test)(POINTER, POINTER))
{
  LIST Scan1, Scan2, Result, ResultStart;
#ifdef CHECK
  if (!list_SortedInOrder(List1, Test)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: First argument is not sorted.", __func__);
    misc_FinishErrorReport();
  }
  else if (!list_SortedInOrder (List2, Test)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Second argument is not sorted.", __func__);
    misc_FinishErrorReport();
  }
#endif
  if (list_Empty(List1))
    return List2;
  if (list_Empty(List2))
    return List1;
  if (Test(list_Car(List1), list_Car(List2))) {
    ResultStart = List1;
    Scan1 = list_Cdr(List1);
    Scan2 = List2;
  }
  else {
    ResultStart = List2;
    Scan1 = List1;
    Scan2 = list_Cdr(List2);
  }
  Result = ResultStart;
  while (!list_Empty(Scan1) && !list_Empty(Scan2)) {
    if (Test(list_Car(Scan1), list_Car(Scan2))) {
      list_Rplacd(Result,Scan1);
      Scan1 = list_Cdr(Scan1);
    }
    else {
      list_Rplacd(Result,Scan2);
      Scan2 = list_Cdr(Scan2);
    }
    Result = list_Cdr(Result);
  }
  if (list_Empty(Scan1))
    list_Rplacd(Result, Scan2);
  else
    list_Rplacd(Result, Scan1);
  return ResultStart;
}
void list_Split(LIST L, LIST *Half1, LIST *Half2)
{
  LIST SingleStep, DoubleStep, Prev;
  if (list_Empty(L) || list_Empty(list_Cdr(L))) {
    *Half1 = list_Nil();
    *Half2 = L;
  }
  else {
    Prev = L;
    SingleStep = list_Cdr(L);
    DoubleStep = list_Cdr(SingleStep);
    while (!list_Empty(DoubleStep) && !list_Empty(list_Cdr(DoubleStep))) {
      Prev = SingleStep;
      SingleStep = list_Cdr(SingleStep);
      DoubleStep = list_Cdr(list_Cdr(DoubleStep));
    }
    *Half1 = L;
    *Half2 = SingleStep;
    list_Rplacd(Prev, list_Nil());
  }
}
LIST list_MergeSort (LIST L, BOOL (*Test) (POINTER, POINTER))
{
  LIST Result;
#ifdef CHECK
  NAT originallength;
  originallength = list_Length(L);
#endif
  if (!list_Empty(L) && !list_Empty(list_Cdr(L))) {
    LIST lowerhalf;
    LIST greaterhalf;
    LIST *lowerhalfptr;
    LIST *greaterhalfptr;
    lowerhalfptr = &lowerhalf;
    greaterhalfptr = &greaterhalf;
    list_Split(L, lowerhalfptr, greaterhalfptr);
#ifdef CHECK
    if((list_Length(lowerhalf) + list_Length(greaterhalf))
       != originallength) {
      misc_StartErrorReport();
      misc_ErrorReport("\n In %s: Split lists' total sizes", __func__);
      misc_ErrorReport("\n don't match original list's size.");
      misc_FinishErrorReport();
    }
#endif
    lowerhalf = list_MergeSort(lowerhalf, Test);
    greaterhalf = list_MergeSort(greaterhalf, Test);
#ifdef CHECK
    if((list_Length(lowerhalf) + list_Length(greaterhalf))
       != originallength) {
      misc_StartErrorReport();
      misc_ErrorReport("\n In %s: Mergesorted lists' total sizes", __func__);
      misc_ErrorReport("\n don't match original list's size.");
      misc_FinishErrorReport();
    }
#endif
    Result = list_Merge(lowerhalf, greaterhalf, Test);
#ifdef CHECK
    if(list_Length(Result) != originallength) {
      misc_StartErrorReport();
      misc_ErrorReport("\n In %s: Merged list's size doesn't match ", __func__);
      misc_ErrorReport("\n original list's size.");
      misc_FinishErrorReport();
    }
#endif
  }
  else {
    Result = L;
  }
  return Result;
}
LIST list_InsertionSort(LIST List, BOOL (*Test)(POINTER, POINTER))
{
  LIST Scan1,Scan2,Min;
  POINTER Exchange;
  for (Scan1=List; !list_Empty(Scan1); Scan1=list_Cdr(Scan1)) {
    Min = Scan1;
    for (Scan2 = list_Cdr(Scan1); !list_Empty(Scan2); Scan2 = list_Cdr(Scan2))
      if (Test(list_Car(Scan2), list_Car(Min))) {
 Exchange = list_Car(Min);
 list_Rplaca(Min, list_Car(Scan2));
 list_Rplaca(Scan2, Exchange);
      }
  }
  return List;
}
LIST list_Sort(LIST List, BOOL (*Test)(POINTER, POINTER))
{
  LIST Result;
#ifdef CHECK
  NAT originallength;
  originallength = list_Length(List);
#endif
  Result = list_MergeSort(List, Test);
#ifdef CHECK
  if (!list_SortedInOrder(Result, Test)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: list_MergeSort did not sort properly.", __func__);
    misc_FinishErrorReport();
  }
  if (list_Length(Result) != originallength) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: list_MergeSort lost elements. ", __func__);
    misc_FinishErrorReport();
  }
#endif
  return Result;
}
static NAT (*NumberFunction)(POINTER) = NULL;
static BOOL list_PointerNumberedLower(POINTER A, POINTER B)
{
  return (BOOL) (NumberFunction(A) < NumberFunction(B));
}
static BOOL list_PointerNumberedLowerOrEqual(POINTER A, POINTER B)
{
  return (BOOL) (NumberFunction(A) <= NumberFunction(B));
}
static BOOL list_PointerNumberedGreater(POINTER A, POINTER B)
{
  return (BOOL) (NumberFunction(A) > NumberFunction(B));
}
LIST list_NumberSort(LIST List, NAT (*Number)(POINTER))
{
  NumberFunction = Number;
  return list_Sort(List, list_PointerNumberedLower);
}
LIST list_GreaterNumberSort(LIST List, NAT (*Number)(POINTER))
{
  NumberFunction = Number;
  return list_Sort(List, list_PointerNumberedGreater);
}
LIST list_NNumberMerge(LIST List1, LIST List2, NAT (*Number)(POINTER))
{
  NumberFunction = Number;
  return list_Merge(List1, List2, list_PointerNumberedLowerOrEqual);
}
POINTER list_DequeueNext(MEMORY Memory, LIST List)
{
  POINTER Pointer;
  LIST Memo;
  if (list_Empty(List))
    return NULL;
  Memo = list_Cdr(List);
  if (list_Empty(Memo))
    return NULL;
  Pointer = list_Car(Memo);
  list_Rplacd(List, Memo->cdr);
  list_Free(Memory, Memo);
  return Pointer;
}
POINTER list_NthElement(LIST List, NAT Number)
{
  while (!list_Empty(List) && --Number > 0)
    List = list_Cdr(List);
  if (list_Empty(List))
    return NULL;
  else
    return list_Car(List);
}
void list_DeleteWithElement(MEMORY Memory, LIST List, void (*ElementDelete)(MEMORY, POINTER))
{
  LIST Scan;
  while (!list_Empty(List)) {
    Scan = list_Cdr(List);
    ElementDelete(Memory, list_Car(List));
    list_Free(Memory, List);
    List = Scan;
  }
}
NAT list_DeleteWithElementCount(MEMORY Memory, LIST List, void (*ElementDelete)(MEMORY, POINTER))
{
  int Result;
  LIST Scan;
  Result = 0;
  while (!list_Empty(List)) {
    Scan = list_Cdr(List);
    ElementDelete(Memory, list_Car(List));
    list_Free(Memory, List);
    List = Scan;
    Result++;
  }
  return Result;
}
LIST list_DeleteElement(MEMORY Memory, LIST List, POINTER Element, BOOL (*Test)(POINTER, POINTER))
{
  LIST Scan1,Scan2;
  while (!list_Empty(List) && Test(Element, list_Car(List))) {
    Scan1 = list_Cdr(List);
    list_Free(Memory, List);
    List = Scan1;
  }
  if (list_Empty(List))
    return list_Nil();
  Scan2 = List;
  Scan1 = list_Cdr(List);
  while (!list_Empty(Scan1)) {
    if (Test(Element, list_Car(Scan1))) {
      list_Rplacd(Scan2, list_Cdr(Scan1));
      list_Free(Memory, Scan1);
      Scan1 = list_Cdr(Scan2);
    }
    else {
      Scan2 = Scan1;
      Scan1 = list_Cdr(Scan1);
    }
  }
  return List;
}
LIST list_DeleteElementIf(MEMORY Memory, LIST List, BOOL (*Test)(POINTER))
{
  LIST Scan1,Scan2;
  while (!list_Empty(List) && Test(list_Car(List))) {
    Scan1 = list_Cdr(List);
    list_Free(Memory, List);
    List = Scan1;
  }
  if (list_Empty(List))
    return list_Nil();
  Scan2 = List;
  Scan1 = list_Cdr(List);
  while (!list_Empty(Scan1)) {
    if (Test(list_Car(Scan1))) {
      list_Rplacd(Scan2, list_Cdr(Scan1));
      list_Free(Memory, Scan1);
      Scan1 = list_Cdr(Scan2);
    }
    else {
      Scan2 = Scan1;
      Scan1 = list_Cdr(Scan1);
    }
  }
  return List;
}
LIST list_DeleteElementIfFree(MEMORY Memory, LIST List, BOOL (*Test)(POINTER),
         void (*Delete)(POINTER))
{
  LIST Scan1,Scan2;
  while (!list_Empty(List) && Test(list_Car(List))) {
    Scan1 = list_Cdr(List);
    Delete(list_Car(List));
    list_Free(Memory, List);
    List = Scan1;
  }
  if (list_Empty(List))
    return list_Nil();
  Scan2 = List;
  Scan1 = list_Cdr(List);
  while (!list_Empty(Scan1)) {
    if (Test(list_Car(Scan1))) {
      Delete(list_Car(Scan1));
      list_Rplacd(Scan2, list_Cdr(Scan1));
      list_Free(Memory, Scan1);
      Scan1 = list_Cdr(Scan2);
    }
    else {
      Scan2 = Scan1;
      Scan1 = list_Cdr(Scan1);
    }
  }
  return List;
}
LIST list_DeleteElementFree(MEMORY Memory, LIST List, POINTER Element,
       BOOL (*Test)(POINTER, POINTER),
       void (*Free)(MEMORY, POINTER))
{
  LIST Scan1,Scan2;
  while (!list_Empty(List) && Test(Element, list_Car(List))) {
    Scan1 = list_Cdr(List);
    Free(Memory, list_Car(List));
    list_Free(Memory, List);
    List = Scan1;
  }
  if (list_Empty(List))
    return list_Nil();
  Scan2 = List;
  Scan1 = list_Cdr(List);
  while (!list_Empty(Scan1)) {
    if (Test(Element, list_Car(Scan1))) {
      list_Rplacd(Scan2, list_Cdr(Scan1));
      Free(Memory, list_Car(Scan1));
      list_Free(Memory, Scan1);
      Scan1 = list_Cdr(Scan2);
    }
    else {
      Scan2 = Scan1;
      Scan1 = list_Cdr(Scan1);
    }
  }
  return List;
}
LIST list_DeleteOneElement(MEMORY Memory, LIST List, POINTER Element, BOOL (*Test)(POINTER, POINTER))
{
  LIST scan1, scan2;
  if (list_Empty(List))
    return List;
  else {
    if (Test(Element, list_Car(List)))
      return list_Pop(Memory, List);
  }
  for (scan2 = List, scan1 = list_Cdr(List); !list_Empty(scan1);
       scan2 = scan1, scan1 = list_Cdr(scan1)) {
    if (Test(Element, list_Car(scan1))) {
      list_Rplacd(scan2, list_Cdr(scan1));
      list_Free(Memory, scan1);
      scan1 = list_Cdr(scan2);
      return List;
    }
  }
  return List;
}
LIST list_PointerDeleteElement(MEMORY Memory, LIST List, POINTER Element)
{
  LIST Scan1,Scan2;
  while (!list_Empty(List) && Element == list_Car(List)) {
    Scan1 = list_Cdr(List);
    list_Free(Memory, List);
    List = Scan1;
  }
  if (list_Empty(List))
    return list_Nil();
  Scan2 = List;
  Scan1 = list_Cdr(List);
  while (!list_Empty(Scan1)) {
    if (Element == list_Car(Scan1)) {
      list_Rplacd(Scan2, list_Cdr(Scan1));
      list_Free(Memory, Scan1);
      Scan1 = list_Cdr(Scan2);
    }
    else {
      Scan2 = Scan1;
      Scan1 = list_Cdr(Scan1);
    }
  }
  return List;
}
LIST list_PointerDeleteElementFree(MEMORY Memory, LIST List, POINTER Element,
       void (*Free)(POINTER))
{
  LIST Scan1,Scan2;
  while (!list_Empty(List) && Element == list_Car(List)) {
    Scan1 = list_Cdr(List);
    Free(list_Car(List));
    list_Free(Memory, List);
    List = Scan1;
  }
  if (list_Empty(List))
    return list_Nil();
  Scan2 = List;
  Scan1 = list_Cdr(List);
  while (!list_Empty(Scan1)) {
    if (Element == list_Car(Scan1)) {
      list_Rplacd(Scan2, list_Cdr(Scan1));
      Free(list_Car(Scan1));
      list_Free(Memory, Scan1);
      Scan1 = list_Cdr(Scan2);
    }
    else {
      Scan2 = Scan1;
      Scan1 = list_Cdr(Scan1);
    }
  }
  return List;
}
LIST list_PointerDeleteOneElement(MEMORY Memory, LIST List, POINTER Element)
{
  LIST Scan1,Scan2;
  if (list_Empty(List))
    return List;
  else {
    if (Element == list_Car(List))
      return list_Pop(Memory, List);
  }
  Scan2 = List;
  Scan1 = list_Cdr(List);
  while (!list_Empty(Scan1)) {
    if (Element == list_Car(Scan1)) {
      list_Rplacd(Scan2, list_Cdr(Scan1));
      list_Free(Memory, Scan1);
      Scan1 = list_Cdr(Scan2);
      return List;
    }
    else {
      Scan2 = Scan1;
      Scan1 = list_Cdr(Scan1);
    }
  }
  return List;
}
BOOL list_DeleteFromList(MEMORY Memory, LIST* List, POINTER Element)
{
  BOOL Found;
  LIST Scan1;
  Found = FALSE;
  while (list_Exist(*List) && Element == list_Car(*List)) {
    Scan1 = list_Cdr(*List);
    list_Free(Memory, *List);
    *List = Scan1;
    Found = TRUE;
  }
  if (list_Exist(*List)) {
    LIST Scan2;
    Scan2 = *List;
    Scan1 = list_Cdr(*List);
    while (list_Exist(Scan1)) {
      if (Element == list_Car(Scan1)) {
 list_Rplacd(Scan2, list_Cdr(Scan1));
 list_Free(Memory, Scan1);
 Scan1 = list_Cdr(Scan2);
 Found = TRUE;
      } else {
 Scan2 = Scan1;
 Scan1 = list_Cdr(Scan1);
      }
    }
  }
  return Found;
}
BOOL list_DeleteOneFromList(MEMORY Memory, LIST* List, POINTER Element)
{
  if (list_Exist(*List)) {
    LIST Scan1;
    if (Element == list_Car(*List)) {
      Scan1 = list_Cdr(*List);
      list_Free(Memory, *List);
      *List = Scan1;
      return TRUE;
    } else {
      LIST Scan2;
      for (Scan2 = *List, Scan1 = list_Cdr(*List); list_Exist(Scan1); ) {
 if (Element == list_Car(Scan1)) {
   list_Rplacd(Scan2, list_Cdr(Scan1));
   list_Free(Memory, Scan1);
   Scan1 = list_Cdr(Scan2);
   return TRUE;
 } else {
   Scan2 = Scan1;
   Scan1 = list_Cdr(Scan1);
 }
      }
    }
  }
  return FALSE;
}
BOOL list_IsSetOfPointers(LIST L)
{
  for ( ; !list_Empty(L); L = list_Cdr(L)) {
    if (list_PointerMember(list_Cdr(L), list_Car(L)))
      return FALSE;
  }
  return TRUE;
}
LIST list_DeleteDuplicates(MEMORY Memory, LIST List, BOOL (*Test)(POINTER, POINTER))
{
  LIST Scan;
  Scan = List;
  while (!list_Empty(Scan)) {
    list_Rplacd(Scan,
  list_DeleteElement(Memory, list_Cdr(Scan), list_Car(Scan), Test));
    Scan = list_Cdr(Scan);
  }
  return List;
}
LIST list_DeleteDuplicatesFree(MEMORY Memory, LIST List, BOOL (*Test)(POINTER, POINTER),
          void (*Free)(MEMORY, POINTER))
{
  LIST Scan;
  Scan = List;
  while (!list_Empty(Scan)) {
    list_Rplacd(Scan, list_DeleteElementFree(Memory, list_Cdr(Scan), list_Car(Scan), Test, Free));
    Scan = list_Cdr(Scan);
  }
  return List;
}
LIST list_PointerDeleteDuplicates(MEMORY Memory, LIST List)
{
  LIST Scan;
  Scan = List;
  while (!list_Empty(Scan)) {
    list_Rplacd(Scan, list_PointerDeleteElement(Memory, list_Cdr(Scan), list_Car(Scan)));
    Scan = list_Cdr(Scan);
  }
  return List;
}
LIST list_NPointerUnion(MEMORY Memory, LIST List1, LIST List2)
{
  return list_PointerDeleteDuplicates(Memory, list_Nconc(List1,List2));
}
LIST list_NUnion(MEMORY Memory, LIST List1, LIST List2, BOOL (*Test)(POINTER, POINTER))
{
  return list_DeleteDuplicates(Memory, list_Nconc(List1,List2), Test);
}
LIST list_NListTimes(MEMORY Memory, LIST List1, LIST List2)
{
  LIST Result, Scan1, Scan2;
  Result = list_Nil();
  if (!list_Empty(List2)) {
    for (Scan1=List1; !list_Empty(Scan1); Scan1=list_Cdr(Scan1))
      for (Scan2=List2; !list_Empty(Scan2); Scan2=list_Cdr(Scan2))
 Result = list_Cons(Memory, list_Append(Memory, ((LIST)list_Car(Scan1)),
           list_Copy(Memory, (LIST)list_Car(Scan2))),
      Result);
  }
  list_DeleteWithElement(Memory, List1, (void (*)(MEMORY,POINTER))list_Delete);
  list_DeleteWithElement(Memory, List2, (void (*)(MEMORY,POINTER))list_Delete);
  return Result;
}
LIST list_NIntersect(MEMORY Memory, LIST List1, LIST List2, BOOL (*Test)(POINTER, POINTER))
{
  LIST Scan1, Scan2;
  while (!list_Empty(List1) && !list_Member(List2, list_Car(List1), Test)) {
    Scan1 = list_Cdr(List1);
    list_Free(Memory, List1);
    List1 = Scan1;
  }
  if (list_Empty(List1))
    return List1;
  Scan1 = List1;
  Scan2 = list_Cdr(List1);
  while (!list_Empty(Scan2)) {
    if (list_Member(List2, list_Car(Scan2), Test)) {
      Scan2 = list_Cdr(Scan2);
      Scan1 = list_Cdr(Scan1);
    }
    else {
      list_Rplacd(Scan1, list_Cdr(Scan2));
      list_Free(Memory, Scan2);
      Scan2 = list_Cdr(Scan1);
    }
  }
  return List1;
}
LIST list_NPointerIntersect(MEMORY Memory, LIST List1, LIST List2)
{
  LIST Scan1, Scan2;
  while (!list_Empty(List1) && !list_PointerMember(List2, list_Car(List1))) {
    Scan1 = list_Cdr(List1);
    list_Free(Memory, List1);
    List1 = Scan1;
  }
  if (list_Empty(List1))
    return List1;
  Scan1 = List1;
  Scan2 = list_Cdr(List1);
  while (!list_Empty(Scan2)) {
    if (list_PointerMember(List2, list_Car(Scan2))) {
      Scan2 = list_Cdr(Scan2);
      Scan1 = list_Cdr(Scan1);
    }
    else {
      list_Rplacd(Scan1, list_Cdr(Scan2));
      list_Free(Memory, Scan2);
      Scan2 = list_Cdr(Scan1);
    }
  }
  return List1;
}
LIST list_Nconc(LIST List1, LIST List2)
{
  LIST Result;
  if (list_Empty(List1))
    return List2;
  if (list_Empty(List2))
    return List1;
  Result = List1;
  for (List1 = Result; !list_Empty(list_Cdr(List1)); List1 = list_Cdr(List1))
               ;
  List1->cdr = List2;
  return Result;
}
void list_NInsert(LIST List1, LIST List2)
{
  LIST Help;
#ifdef CHECK
  if (list_Empty(List1)) {
    misc_StartErrorReport();
    misc_ErrorReport("\n In %s: Empty list argument.", __func__);
    misc_FinishErrorReport();
  }
#endif
  Help = list_Cdr(List1);
  list_Rplacd(List1,List2);
  List2 = List1;
  while (!list_Empty(list_Cdr(List2)))
    List2 = list_Cdr(List2);
  list_Rplacd(List2,Help);
}
BOOL list_HasIntersection(LIST List1, LIST List2)
{
  LIST Scan;
  if (!list_Empty(List2)) {
    for (Scan=List1; !list_Empty(Scan); Scan=list_Cdr(Scan))
      if (list_PointerMember(List2, list_Car(Scan)))
 return TRUE;
  }
  return FALSE;
}
LIST list_NPointerDifference(MEMORY Memory, LIST List1, LIST List2)
{
  LIST Scan;
  if (!list_Empty(List1)) {
    for (Scan=List2; !list_Empty(Scan) && !list_Empty(List1); Scan=list_Cdr(Scan))
      List1 = list_PointerDeleteElement(Memory, List1, list_Car(Scan));
  }
  return List1;
}
LIST list_NDifference(MEMORY Memory, LIST List1, LIST List2, BOOL (*Test)(POINTER, POINTER))
{
  LIST Scan;
  if (!list_Empty(List1)) {
    for (Scan=List2; !list_Empty(Scan); Scan=list_Cdr(Scan))
      List1 = list_DeleteElement(Memory, List1, list_Car(Scan), Test);
  }
  return List1;
}
LIST list_NMultisetDifference(MEMORY Memory, LIST List1, LIST List2, BOOL (*Test)(POINTER, POINTER))
{
  LIST scan;
  if (!list_Empty(List1)) {
    for (scan = List2; !list_Empty(scan); scan = list_Cdr(scan))
      List1 = list_DeleteOneElement(Memory, List1, list_Car(scan), Test);
  }
  return List1;
}
BOOL list_PointerReplaceMember(LIST List, POINTER Old, POINTER New)
{
  while (!list_Empty(List)) {
    if (Old == list_Car(List)) {
      list_Rplaca(List, New);
      return TRUE;
    }
    List = list_Cdr(List);
  }
  return FALSE;
}
void list_DeleteAssocListWithValues(MEMORY Memory, LIST List, void (*ValueDelete)(MEMORY, POINTER))
{
  LIST Scan;
  for (Scan=List;!list_Empty(Scan);Scan = list_Cdr(Scan)) {
    ValueDelete(Memory, list_PairSecond(list_Car(Scan)));
    list_PairFree(Memory, list_Car(Scan));
  }
  list_Delete(Memory, List);
}
POINTER list_AssocListValue(LIST List, POINTER Key)
{
  LIST Scan;
  for (Scan=List;!list_Empty(Scan);Scan = list_Cdr(Scan))
    if (Key == list_PairFirst(list_Car(Scan)))
      return list_PairSecond(list_Car(Scan));
  return NULL;
}
LIST list_AssocListPair(LIST List, POINTER Key)
{
  LIST Scan;
  for (Scan=List;!list_Empty(Scan);Scan = list_Cdr(Scan))
    if (Key == list_PairFirst(list_Car(Scan)))
      return list_Car(Scan);
  return list_PairNull();
}
LIST list_MultisetDistribution(MEMORY Memory, LIST Multiset)
{
  LIST Distribution;
  LIST Scan;
  Distribution = list_PairNull();
  for (Scan = Multiset; !list_Empty(Scan); Scan = list_Cdr(Scan)) {
    LIST Count;
    POINTER Element;
    intptr_t Occurences;
    Element = list_Car(Scan);
    Count = list_AssocListPair(Distribution, Element);
    if (Count != list_PairNull()) {
      Occurences = (intptr_t)list_PairSecond(Count);
      list_PairRplacSecond(Count, (POINTER) (Occurences + 1));
    }
    else {
      Distribution = list_AssocCons(Memory, Distribution, Element, (POINTER) 1);
    }
  }
  return Distribution;
}
int list_CompareElementDistribution(LIST LeftPair, LIST RightPair)
{
  if ((intptr_t) list_PairSecond(LeftPair) < (intptr_t) list_PairSecond(RightPair)) {
    return -1;
  }
  else if ((intptr_t) list_PairSecond(LeftPair) > (intptr_t)list_PairSecond(RightPair)) {
    return 1;
  }
  return 0;
}
BOOL list_CompareElementDistributionLEQ(LIST LeftPair, LIST RightPair) {
  return (list_CompareElementDistribution(LeftPair, RightPair) <= 0);
}
int list_CompareDistributions(LIST Left, LIST Right)
{
  LIST scan, scan2;
  int result;
  result = 0;
  scan = Left;
  scan2 = Right;
  while ( !(list_Empty(scan) || list_Empty(scan2))) {
    result = list_CompareElementDistribution(list_Car(scan), list_Car(scan2));
    if (result != 0) {
      break;
    }
    scan = list_Cdr(scan);
    scan2 = list_Cdr(scan2);
  }
  if (result == 0) {
    if (list_Empty(scan) && !list_Empty(scan2))
      result = -1;
    else if (!list_Empty(scan) && list_Empty(scan2))
      result = 1;
  }
  return result;
}
int list_CompareMultisetsByElementDistribution(MEMORY Memory, LIST Left, LIST Right)
{
  LIST lmsd, rmsd;
  int result;
  lmsd = list_MultisetDistribution(Memory,Left);
  rmsd = list_MultisetDistribution(Memory,Right);
  lmsd = list_Sort(lmsd, (BOOL (*) (POINTER, POINTER)) list_CompareElementDistributionLEQ);
  rmsd = list_Sort(rmsd, (BOOL (*) (POINTER, POINTER)) list_CompareElementDistributionLEQ);
  result = list_CompareDistributions(lmsd, rmsd);
  list_DeleteDistribution(Memory, lmsd);
  list_DeleteDistribution(Memory, rmsd);
  return result;
}
NAT list_Length(LIST List)
{
  NAT Result;
  Result = 0;
  while (!list_Empty(List)) {
    Result++;
    List = list_Cdr(List);
  }
  return Result;
}
NAT list_Bytes(LIST List)
{
  return (list_Length(List)*sizeof(LIST_NODE));
}
