|##########|
|#MAGIC   #|CKOLFLFP
|#PROJECT #|""
|#PATHS   #|"StdProject"
|#FLAGS   #|xx-x-x--x-----x-----------------
|#USERSW  #|--------------------------------
|#USERMASK#|--------------------------------
|#SWITCHES#|x----x----------
|##########|
DEFINITION MODULE OLists;

  DEFINITION MODULE BiLists(Node : POINTER TO NodeObj);

  TYPE
    NodeObj   = OBJECT
                  prev,next  : Node;
                  DEFERRED METHOD greater(as : Node):Node;
                  DESTRUCTOR Delete;
                  METHOD Clone():Node;
                END;

    Condition = PROCEDURE(n : Node):BOOLEAN;
    ApplyProc = PROCEDURE(n : Node);

    List    =   POINTER TO ListObj;
    ListObj =   OBJECT
                  first,last : Node;

                  CONSTRUCTOR Create(nodes : LIST OF Node);
                  DESTRUCTOR Delete;

                  METHOD Destruct;

                  METHOD InsertFirst(n : Node);
                  METHOD InsertLast(n : Node);
                  METHOD InsertAfter(n,after : Node);
                  METHOD InsertBefore(n,before : Node);

                  METHOD RemoveNode(n : Node);
                  METHOD DeleteNode(n : Node);

                  METHOD RemoveAll;
                  METHOD DeleteAll;

                  METHOD RemoveIF(if : Condition);
                  METHOD DeleteIF(if : Condition);

                  METHOD Sort;

                  METHOD Apply(app : ApplyProc);
                  METHOD ApplyIF(app : ApplyProc;if : Condition);

                  METHOD Find(if : Condition;from : Node := NIL):Node;

                  METHOD Clone():List;

                  METHOD Append(VAR l : List);
                END;

  END BiLists;

  DEFINITION MODULE BiLists2(Node : POINTER TO NodeObj);

    DEFINITION MODULE OldBiLists = BiLists(Node);

  TYPE
    List      = POINTER TO ListObj;
    NodeObj   = OBJECT OF OldBiLists.Node;
                  METHOD Destruct;
                  list    : List;
                END;

    Condition = PROCEDURE(n : Node):BOOLEAN;
    ApplyProc = PROCEDURE(n : Node);

    ListObj =   OBJECT OF OldBiLists.List;
                  first,last : Node;

                  METHOD Destruct;

                  METHOD InsertFirst(n : Node);
                  METHOD InsertLast(n : Node);
                  METHOD InsertAfter(n,after : Node);
                  METHOD InsertBefore(n,before : Node);

                  METHOD RemoveNode(n : Node);
                  METHOD DeleteNode(n : Node);

                  METHOD RemoveAll;
                  METHOD DeleteAll;
                END;

  END BiLists2;

  DEFINITION MODULE CLists(Node : POINTER TO NodeObj);

  IMPORT OBuffers;

  EXCEPTION
    OutOfList : "Cursor out of list";
    NotFound  : "Element not found";

  TYPE
    NodeObj  = OBJECT END;
    CNode    = POINTER TO CNodeObj;

    DEFINITION MODULE CLists   = BiLists(CNode);
    DEFINITION MODULE CStacks  = OBuffers.Stacks(CNode);

  TYPE
    CNodeObj = OBJECT OF CLists.Node;
                 data  : Node;
               END;
    Condition = PROCEDURE(n : Node):BOOLEAN;
    ApplyProc = PROCEDURE(n : Node);

    List     = POINTER TO ListObj;
    ListObj  = OBJECT OF CLists.List   AS clist,
                         CStacks.Stack AS stack;
                  cursor : CNode;

                  CONSTRUCTOR Create;
                  CONSTRUCTOR Delete;

                  METHOD First;
                  METHOD Last;
                  METHOD Next;
                  METHOD Prev;
                  METHOD Seek(n : Node);

                  METHOD Push;
                  METHOD Pop;
                  METHOD Swap;

                  METHOD isFirst():BOOLEAN;
                  METHOD isLast():BOOLEAN;
                  METHOD isEmpty():BOOLEAN;
                  METHOD isValid():BOOLEAN;

                  METHOD Destruct;

                  METHOD Get():Node;
                  METHOD Change(n : Node):Node;

                  METHOD InsertFirst(n : Node);
                  METHOD InsertLast(n : Node);
                  METHOD InsertAfter(n : Node);
                  METHOD InsertBefore(n : Node);

                  METHOD RemoveNode;
                  METHOD DeleteNode;

                  METHOD RemoveAll;
                  METHOD DeleteAll;

                  METHOD RemoveIF(if : Condition);
                  METHOD DeleteIF(if : Condition);

                  METHOD Sort;

                  METHOD Apply(app : ApplyProc);
                  METHOD ApplyIF(app : ApplyProc;if : Condition);

                  METHOD Find(if : Condition);

                  METHOD Clone():List;

                  METHOD Append(VAR l : List);

                END;
  END CLists;

END OLists.

