text:
//-*-c++-*-

/**************************************************************************/
/**
 **  @file tList.h
 **  @brief Header file for classes tList, tListNodeXXX, and tListIter.
 **
 **  A tList is an object that implements a general linked list NodeType
 **  objects, where NodeType can be any type (double, int, other objects,
 **  etc). The one caveat is that tLists are not designed to be lists of
 **  pointers, which have some unique requirements and are thus handled
 **  by tPtrList objects. (Specifically, in a normal list you want to
 **  retrieve the actual item in the list, whereas in a pointer list you
 **  want to retrieve the item to which the list entry points).
 **
 **  Lists can be either linear or circular. The tList class provides
 **  a variety of methods for adding, moving, and retrieving list elements.
 **  For moving back and forth in a tList and retrieving items, it's often
 **  most useful to use a tListIter object (q.v.).
 **
 **  tListNode objects are the nodes on the list; each contains an instance
 **  of the given data type (double, int, class, etc) and a pointer to the
 **  next node in the list.
 **
 **  A tListIter is an iterator for the linked list tList objects (and their
 **  descendants). Its services include fetching data from the current entry
 **  on the list, advancing to the next or previous item on the list, etc.
 **
 **  See also tPtrList, tArray, tMatrix
 **
 **  Changes:
 **    - GT added currentItem member and routines FirstP and NextP to
 **      track position on list w/o an iterator, 1/22/99
 **    - moved all functions into .h file and inlined them (GT 1/20/00)
 **    - AD - March 2004: tListNode is a template argument.
 **
 **  $Id: tList.h,v 1.57 2004/06/16 13:37:33 childcvs Exp $
 */
/**************************************************************************/

#ifndef TLIST_H
#define TLIST_H

#include "tListFwd.h"
#include "../compiler.h"

/**************************************************************************/
/**
 ** @class tListNodeBasic
 **
 ** Class tListNodeBasic represents the items (or "nodes") on the list. Each
 ** tListNodeBasic object has two parts: the data (of type NodeType) and a
 ** pointer to the next item on the list. Capabilities include copy
 ** construction (from either another tListNodeBasic or a NodeType),
 ** returning a pointer or reference to either the data or the tListNodeBasic
 ** itself, and assignment and equality/inequality operations.
 **
 */
/**************************************************************************/
template< class NodeType >
class tListNodeBasic
{
  friend class tList< NodeType, tListNodeBasic< NodeType > >;
  friend class tMeshList< NodeType, tListNodeBasic< NodeType > >;
  friend class tListIter< NodeType, tListNodeBasic< NodeType > >;
  friend class tMeshListIter< NodeType, tListNodeBasic< NodeType > >;
public:
  inline tListNodeBasic();                                // default constructor
  inline tListNodeBasic( const tListNodeBasic< NodeType > & ); // copy constructor #1
  inline tListNodeBasic( const NodeType & );              // copy constructor #2
  const tListNodeBasic< NodeType >
  &operator=( const tListNodeBasic< NodeType > & );           // assignment
  inline bool operator==( const tListNodeBasic< NodeType > & ) const; // equality
  inline bool operator!=( const tListNodeBasic< NodeType > & ) const; // inequality
  /*set*/
  inline NodeType getDataNC() const;               // returns copy of data item
  inline NodeType &getDataRefNC();                 // returns modifiable ref to data
  inline NodeType *getDataPtrNC();                 // returns modifiable ptr to data
  inline tListNodeBasic< NodeType > * getNextNC(); // returns ptr to next list node
  /*get*/
  inline NodeType getData() const;                     // returns const copy of data
  inline const NodeType &getDataRef() const;           // returns const ref to data
  inline const NodeType *getDataPtr() const;           // returns const ptr to data
  inline const tListNodeBasic< NodeType > * getNext() const;// returns const ptr to next
  inline const tListNodeBasic< NodeType > * getPrev() const;
  enum {
    isListable = false
  };
  static tListNodeBasic< NodeType > *getListPtr( NodeType const *ptr) {
    return 0;
  }

protected:
  NodeType data_;               // data item
  tListNodeBasic< NodeType > *next; // ptr to next node on list (=0 if end)
  tListNodeBasic< NodeType > *prev;
};

/**************************************************************************\
 **
 **         FUNCTIONS FOR CLASS tListNodeBasic< NodeType >
 **
 **         tListNodeBasics contain a data item and a pointer to the next
 **         tListNodeBasic in the tList (or tMeshList). The data item may
 **         be of any type, specified in the template brackets.
 **
 **         Some of the functions for retrieving the data are duplicated
 **         by tListIter.
 **
 **         Created: fall, 97, SL
 **
\**************************************************************************/

/**************************************************************************\
 **
 **  tListNodeBasic constructors:
 **
 **  Default constructor: sets next to null
 **  Copy constructor #1: makes a copy of a given tListNodeBasic
 **  Copy constructor #2: fills in data item w/ copy of given NodeType
 **
\**************************************************************************/

//default constructor
template< class NodeType >
inline tListNodeBasic< NodeType >::
tListNodeBasic() :
  next(0),
  prev(0)
{}

//copy constructor with data reference
template< class NodeType >
inline tListNodeBasic< NodeType >::
tListNodeBasic( const tListNodeBasic< NodeType > &original ) :
  data_(original.data_),
  next(original.next),
  prev(original.prev)
{}

//value (by reference) constructor
template< class NodeType >
inline tListNodeBasic< NodeType >::
tListNodeBasic( const NodeType &info ) :
  data_(info),
  next(0),
  prev(0)
{}

/**************************************************************************\
 **
 **  tListNodeBasic overloaded operators:
 **
 **  Assignment: makes a copy (including next ptr)
 **  Equality: compares both data contents and next ptr
 **  Inequality: compares both data contents and next ptr
 **
\**************************************************************************/

//overloaded assignment operator
template< class NodeType >
inline const tListNodeBasic< NodeType > &tListNodeBasic< NodeType >::
operator=( const tListNodeBasic< NodeType > &right )
{
  if( &right != this )
    {
      data_ = right.data_;
      next = right.next;
      prev = right.prev;
    }
  return *this;
}

//overloaded equality operator:
template< class NodeType >
inline bool tListNodeBasic< NodeType >::
operator==( const tListNodeBasic< NodeType > &right ) const
{
  if( next != right.next ) return false;
  if( prev != right.prev ) return false;
  if( &data_ != &(right.data_) ) return false;
  return true;
}

//overloaded inequality operator:
template< class NodeType >
inline bool tListNodeBasic< NodeType >::
operator!=( const tListNodeBasic< NodeType > &right ) const
{
  return ! operator==(right);
}

/**************************************************************************\
 **
 **  tListNodeBasic "get" functions:
 **  (note: to "set" an item, use non-const "get")
 **
 **  getDataNC: returns a non-const (modifiable) copy of data
 **  getDataRefNC: returns a non-const (modifiable) reference to data
 **  getDataPtrNC: returns a non-const (modifiable) pointer to data
 **  getNextNC: returns non-const ptr to next item on list
 **  getData: returns const copy of data
 **  getDataRef: returns const reference to data
 **  getDataPtr: returns const ptr to data
 **  getNext: returns const ptr to next item on list
 **
\**************************************************************************/

//set data by returning non-const
template< class NodeType >
inline NodeType tListNodeBasic< NodeType >::
getDataNC() const {return data_;}

template< class NodeType >
inline NodeType &tListNodeBasic< NodeType >::
getDataRefNC() {return data_;}

template< class NodeType >
inline NodeType *tListNodeBasic< NodeType >::
getDataPtrNC() {return &data_;}

template< class NodeType >
inline tListNodeBasic< NodeType > *tListNodeBasic< NodeType >::
getNextNC() {return next;}

//return data by value
template< class NodeType >
inline NodeType tListNodeBasic< NodeType >::
getData() const {return data_;}

//return data by reference
template< class NodeType >
inline const NodeType &tListNodeBasic< NodeType >::
getDataRef() const {return data_;}

//return data by pointer
template< class NodeType >
inline const NodeType *tListNodeBasic< NodeType >::
getDataPtr() const {return &data_;}

//return next pointer
template< class NodeType >
inline const tListNodeBasic< NodeType > *tListNodeBasic< NodeType >::
getNext() const {return next;}

//return prev pointer
template< class NodeType >
inline const tListNodeBasic< NodeType > *tListNodeBasic< NodeType >::
getPrev() const {return prev;}

/**************************************************************************/
/**
 ** @class tListable
 **
 ** Used by classes T that can be used by tList<T,tListNodeListable<T> >.
 **
 */
/**************************************************************************/
class tListable
{
public:
  tListable() : listPtr(0) {}
  // listPtr is not copied and set to 0.
  tListable(tListable const &) : listPtr(0) {}
  // listPtr is left identical.
  tListable& operator=(tListable const &) { return *this; }
  void setListPtr(void *ptr) { listPtr = ptr; }
  void *getListPtr() const { return listPtr; }
private:
  void *listPtr;  // Pointer to ListNode
};

/**************************************************************************/
/**
 ** @class tListNodeListable
 **
 ** Class tListNodeListable is similar to tListNode except that it sets
 ** a backpointer in NodeType.
 **
 */
/**************************************************************************/
template< class NodeType >
class tListNodeListable
{
  friend class tList< NodeType, tListNodeListable< NodeType > >;
  friend class tMeshList< NodeType, tListNodeListable< NodeType > >;
  friend class tListIter< NodeType, tListNodeListable< NodeType > >;
  friend class tMeshListIter< NodeType, tListNodeListable< NodeType > >;
public:
  inline tListNodeListable();                                // default constructor
  inline tListNodeListable( const tListNodeListable< NodeType > & ); // copy constructor #1
  inline tListNodeListable( const NodeType & );              // copy constructor #2
  const tListNodeListable< NodeType >
  &operator=( const tListNodeListable< NodeType > & );           // assignment
  inline bool operator==( const tListNodeListable< NodeType > & ) const; // equality
  inline bool operator!=( const tListNodeListable< NodeType > & ) const; // inequality
  /*set*/
  inline NodeType getDataNC() const;               // returns copy of data item
  inline NodeType &getDataRefNC();                 // returns modifiable ref to data
  inline NodeType *getDataPtrNC();                 // returns modifiable ptr to data
  inline tListNodeListable< NodeType > * getNextNC();// returns ptr to next list node
  /*get*/
  inline NodeType getData() const;                     // returns const copy of data
  inline const NodeType &getDataRef() const;           // returns const ref to data
  inline const NodeType *getDataPtr() const;           // returns const ptr to data
  inline const tListNodeListable< NodeType > * getNext() const;// returns const ptr to next
  inline const tListNodeListable< NodeType > * getPrev() const;
  enum {
    isListable = true
  };
  static tListNodeListable< NodeType > *getListPtr( NodeType const *dataPtr) {
    return static_cast<tListNodeListable< NodeType >*>(dataPtr->getListPtr());
  }

protected:
  NodeType data_;               // data item
  tListNodeListable< NodeType > *next; // ptr to next node on list (=0 if end)
  tListNodeListable< NodeType > *prev;
};

/**************************************************************************\
 **
 **         FUNCTIONS FOR CLASS tListNodeListable< NodeType >
 **
 **         tListNodeListables contain a data item and a pointer to the next
 **         tListNodeListable in the tList (or tMeshList). The data item may
 **         be of any type, specified in the template brackets.
 **
 **         Some of the functions for retrieving the data are duplicated
 **         by tListIter.
 **
 **         Created: fall, 97, SL
 **
\**************************************************************************/

/**************************************************************************\
 **
 **  tListNodeListable constructors:
 **
 **  Default constructor: sets next to null
 **  Copy constructor #1: makes a copy of a given tListNodeListable
 **  Copy constructor #2: fills in data item w/ copy of given NodeType
 **
\**************************************************************************/

//default constructor
template< class NodeType >
inline tListNodeListable< NodeType >::
tListNodeListable() :
  next(0),
  prev(0)
{
  data_.setListPtr(this);
}

//copy constructor with data reference
template< class NodeType >
inline tListNodeListable< NodeType >::
tListNodeListable( const tListNodeListable< NodeType > &original ) :
  data_(original.data_),
  next(original.next),
  prev(original.prev)
{
  data_.setListPtr(this);
}

//value (by reference) constructor
template< class NodeType >
inline tListNodeListable< NodeType >::
tListNodeListable( const NodeType &info ) :
  data_(info),
  next(0),
  prev(0)
{
  data_.setListPtr(this);
}

/**************************************************************************\
 **
 **  tListNodeListable overloaded operators:
 **
 **  Assignment: makes a copy (including next ptr)
 **  Equality: compares both data contents and next ptr
 **  Inequality: compares both data contents and next ptr
 **
\**************************************************************************/

//overloaded assignment operator
template< class NodeType >
inline const tListNodeListable< NodeType > &tListNodeListable< NodeType >::
operator=( const tListNodeListable< NodeType > &right )
{
  if( &right != this )
    {
      data_ = right.data_;
      next = right.next;
      prev = right.prev;
    }
  return *this;
}

//overloaded equality operator:
template< class NodeType >
inline bool tListNodeListable< NodeType >::
operator==( const tListNodeListable< NodeType > &right ) const
{
  if( next != right.next ) return false;
  if( prev != right.prev ) return false;
  if( &data_ != &(right.data_) ) return false;
  return true;
}

//overloaded inequality operator:
template< class NodeType >
inline bool tListNodeListable< NodeType >::
operator!=( const tListNodeListable< NodeType > &right ) const
{
  return ! operator==(right);
}

/**************************************************************************\
 **
 **  tListNodeListable "get" functions:
 **  (note: to "set" an item, use non-const "get")
 **
 **  getDataNC: returns a non-const (modifiable) copy of data
 **  getDataRefNC: returns a non-const (modifiable) reference to data
 **  getDataPtrNC: returns a non-const (modifiable) pointer to data
 **  getNextNC: returns non-const ptr to next item on list
 **  getData: returns const copy of data
 **  getDataRef: returns const reference to data
 **  getDataPtr: returns const ptr to data
 **  getNext: returns const ptr to next item on list
 **
\**************************************************************************/

//set data by returning non-const
template< class NodeType >
inline NodeType tListNodeListable< NodeType >::
getDataNC() const {
  NodeType aData(data_);
  aData.setListPtr(0);
  return aData;
}

template< class NodeType >
inline NodeType &tListNodeListable< NodeType >::
getDataRefNC() {return data_;}

template< class NodeType >
inline NodeType *tListNodeListable< NodeType >::
getDataPtrNC() {return &data_;}

template< class NodeType >
inline tListNodeListable< NodeType > *tListNodeListable< NodeType >::
getNextNC() {return next;}

//return data by value
template< class NodeType >
inline NodeType tListNodeListable< NodeType >::
getData() const {
  NodeType aData(data_);
  aData.setListPtr(0);
  return aData;
}

//return data by reference
template< class NodeType >
inline const NodeType &tListNodeListable< NodeType >::
getDataRef() const {return data_;}

//return data by pointer
template< class NodeType >
inline const NodeType *tListNodeListable< NodeType >::
getDataPtr() const {return &data_;}

//return next pointer
template< class NodeType >
inline const tListNodeListable< NodeType > *tListNodeListable< NodeType >::
getNext() const {return next;}

//return prev pointer
template< class NodeType >
inline const tListNodeListable< NodeType > *tListNodeListable< NodeType >::
getPrev() const {return prev;}

/**************************************************************************/
/**
 ** @class tList
 **
 ** Class tList implements a linked list. The class includes pointers to
 ** the first, last, and current list nodes (arg "ListNodeType").
 **
 */
/**************************************************************************/
template< class NodeType, class ListNodeType >
class tList
{
  friend class tListIter< NodeType, ListNodeType >;
  friend class tMeshListIter< NodeType, ListNodeType >;
  tList(const tList&);
public:
  inline tList();                     // default constructor
  tList( const tList< NodeType, ListNodeType > * ); // copy constructor
  ~tList();                           // destructor
  const tList< NodeType, ListNodeType >
  &operator=( const tList< NodeType, ListNodeType > & );           // assignment
  inline bool operator==( const tList< NodeType, ListNodeType > & ) const; // equality
  inline bool operator!=( const tList< NodeType, ListNodeType > & ) const; // inequality
  inline void insertAtFront( const NodeType & ); // puts copy of item at list front
  inline void insertAtBack( const NodeType & );  // puts copy of item at list back
  inline void insertAtNext( const NodeType &, ListNodeType * );
  inline void insertAtPrev( const NodeType &, ListNodeType * );
  inline int removeFromFront( NodeType & ); // removes 1st item, puts it in ref
  inline int removeFromBack( NodeType & );  // removes last item, puts it in ref
  inline int removeNext( NodeType &, ListNodeType * );
  inline int removePrev( NodeType &, ListNodeType * );
  void Flush();        // clears and reinitializes list
  inline bool isEmpty() const; // returns true is list is empty, false otherwise
#ifndef NDEBUG
  void print() const;  // prints contents of list - DEBUG ONLY
#endif
  inline int getSize() const; // returns # of items on list
  inline ListNodeType const * getFirst() const; // returns ptr to 1st list node
  inline ListNodeType const * getLast() const;  // returns ptr to last list node
  inline ListNodeType * getFirstNC(); // returns ptr to 1st list node
  inline ListNodeType * getLastNC();  // returns ptr to last list node
  inline NodeType * FirstP();  // returns ptr to 1st data item & sets current to 1st
  inline NodeType * NextP();   // moves to next node and returns ptr to data item
  inline void moveToBack( ListNodeType *  );  // move given node to back
  inline void moveToFront( ListNodeType *  ); // move given node to front
  inline void moveToBefore( ListNodeType *, ListNodeType * );
  inline void moveToAfter( ListNodeType *, ListNodeType * );
  inline void makeCircular();   // makes list circular (last points to first)
  inline const NodeType getIthData( int ) const;     // rtns copy of given item #
  inline const NodeType *getIthDataPtr( int ) const; // rtns ptr to given item #
  inline const NodeType &getIthDataRef( int ) const; // rtns ref to given item #
  inline NodeType getIthDataNC( int ) const;     // rtns modifiable copy of item #
  inline NodeType *getIthDataPtrNC( int ); // rtns modifiable ptr to item #
  inline NodeType &getIthDataRefNC( int ); // rtns modifiable ref to item #
  ListNodeType * getListNode( const NodeType * ); // rtns ptr to node #
  const ListNodeType * getIthListNode( int ) const;
  ListNodeType * getIthListNodeNC( int );

#ifndef NDEBUG
  void DebugTellPtrs() const;
#endif

protected:
  int nNodes;                          // # of items on list
  ListNodeType * first;       // ptr to first node
  ListNodeType * last;        // ptr to last node
  ListNodeType * currentItem; // ptr to current item
  ListNodeType * getNewNode( const NodeType & ); // makes new node
};

/**************************************************************************\
 **
 **         FUNCTIONS FOR CLASS tList< NodeType >
 **
 **         tList is a linked list of tListNodes. Functions to add and
 **         remove items to/from list, etc.
 **
 **         Again, some functions are duplicated by tListIter.
 **
 **         Created: fall, 97, SL
 **
\**************************************************************************/

/**************************************************************************\
 **
 **  tList constructors & destructor:
 **
 **  Default constructor: initializes all values to 0 (empty list)
 **  Copy constructor: makes a complete copy of another tList
 **  Destructor: deletes all nodes on list
 **
\**************************************************************************/

//default constructor
template< class NodeType, class ListNodeType >
inline tList< NodeType, ListNodeType >::tList() :
  nNodes(0), first(0), last(0), currentItem(0)
{}

//copy constructor
template< class NodeType, class ListNodeType >
tList< NodeType, ListNodeType >::
tList( const tList< NodeType, ListNodeType > *original ) :
  nNodes(0), first(0), last(0), currentItem(0)
{
  int i;

  assert( original != 0 );
  ListNodeType * current = original->first;
  for( i=0; i<original->nNodes; ++i )
    {
      insertAtBack( current->getDataRef() );
      current = current->next;
    }
  assert( nNodes == original->nNodes );
  if (0) //DEBUG
    std::cout << "list copy instantiated" << first << std::endl;
  current = first;

}

//destructor
template< class NodeType, class ListNodeType >
tList< NodeType, ListNodeType >::
~tList()
{
  if( !isEmpty() )
    {
      if (0) //DEBUG
	std::cout<<"Destroying nodes ... "<<std::endl;
      ListNodeType * current = first, * temp;
      while( current != 0 )
	{
	  temp = current;
	  current = current->next;
	  delete temp;
	}
    }
  first = 0;
  last = 0;
  currentItem = 0;
}

/**************************************************************************\
 **
 **  tList overloaded operators:
 **
 **  Assignment: clears the list and makes a copy of the right-hand list
 **  Equality: returns TRUE if first & last pointers are identical and
 **            nNodes is the same. Note that two lists with identical
 **            contents are still not considered equal! (TODO--makes sense?)
 **  Inequality: opposite of equality
 **
\**************************************************************************/

//overloaded assignment operator
template< class NodeType, class ListNodeType >
const tList< NodeType, ListNodeType > &tList< NodeType, ListNodeType >::
operator=( const tList< NodeType, ListNodeType > &right )
{
  if( this != &right )
    {
      // create an equivalent object rather than pointers to the original
      Flush();
      ListNodeType *cn = right.first;
      if( cn != 0 )
	{
          insertAtBack( cn->getDataRef() );
          for( cn = cn->next; cn != last->next; cn = cn->next )
	    insertAtBack( cn->getDataRef() );
	  if( right.last->next == right.first ) last->next = first;
	  if( right.first->prev == right.last ) first->prev = last;
	}
      assert( nNodes == right.nNodes );
    }
  return *this;
}

//overloaded equality operator:
template< class NodeType, class ListNodeType >
inline bool tList< NodeType, ListNodeType >::
operator==( const tList< NodeType, ListNodeType > &right ) const
{
  if( nNodes != right.nNodes ) return false;
  if( first != right.first ) return false;
  if( last != right.last ) return false;
  return true;
}

//overloaded inequality operator:
template< class NodeType, class ListNodeType >
inline bool tList< NodeType, ListNodeType >::
operator!=( const tList< NodeType, ListNodeType > &right ) const
{
  return ! operator==(right);
}

/**************************************************************************\
 **
 **  tList::getNewNode
 **
 **  Creates a new ListNodeType and returns a pointer to it. Used by list
 **  insertion routines (see below); not publically accessible.
 **
\**************************************************************************/
template< class NodeType, class ListNodeType >
inline ListNodeType * tList< NodeType, ListNodeType >::
getNewNode( const NodeType &value )
{
  ListNodeType * ptr =
    new ListNodeType( value );
  assert( ptr != 0 );
  ++nNodes;
  return ptr;
}

/**************************************************************************\
 **
 **  tList: list insertion and removal routines
 **
 **  A collection of routines to add nodes to the list, remove them from
 **  the list, and change the position of nodes on the list. In the case
 **  of insertion routines, a new copy of the given node is created first.
 **  The list removal routines take a reference to a NodeType variable;
 **  on return, this variable contains a copy of the data item removed.
 **  List removal routines return TRUE if there was an item to remove;
 **  FALSE otherwise.
 **
 **    insertAtFront: make a new node containing _value_ and put at top
 **    insertAtBack: make a new node containing _value_ and put at bottom
 **    insertAtNext: make new node containing _value_ and place it on the
 **                  list after _prev_
 **    insertAtPrev: make new node containing _value_ and place it on the
 **                  list before _node_
 **    removeFromFront: remove 1st item on list and place a copy in _value_
 **    removeFromBack: remove last item on list and place a copy in _value_
 **    removeNext: remove the node following node _ptr_ and place a copy
 **                in _value_
 **    removePrev: remove the node before node _ptr_ and place a copy
 **                in _value_
 **
\**************************************************************************/

//insert at front
template< class NodeType, class ListNodeType >
inline void tList< NodeType, ListNodeType >::
insertAtFront( const NodeType &value )
{
  if (0) //DEBUG
    std::cout << "ADD NEW NODE TO LIST AT FRONT" << std::endl;

  ListNodeType *newPtr = getNewNode( value );
  if( isEmpty() )
    first = last = currentItem = newPtr;
  else
    {
      newPtr->next = first;
      newPtr->prev = first->prev;
      first->prev = newPtr;
      if( last->next == first ) last->next = newPtr;
      first = newPtr;
    }
}

//insert at back
template< class NodeType, class ListNodeType >
inline void tList< NodeType, ListNodeType >::
insertAtBack( const NodeType &value )
{
  ListNodeType * newPtr = getNewNode( value );
  if( isEmpty() )
    {
      first = last = currentItem = newPtr;
    }
  else
    {
      newPtr->next = last->next;
      newPtr->prev = last;
      last->next = newPtr;
      if( first->prev == last )
	first->prev = newPtr;
      last = newPtr;
    }
}

//insert at next spot in list
template< class NodeType, class ListNodeType >
inline void tList< NodeType, ListNodeType >::
insertAtNext( const NodeType &value, ListNodeType * prev )
{
  if( prev != 0 )
    {
      if( prev == last )
	{
	  insertAtBack( value );
	  return;
	}
      ListNodeType * newPtr = getNewNode( value );
      newPtr->next = prev->next;
      newPtr->prev = prev;
      prev->next->prev = newPtr;
      prev->next = newPtr;
    }
}

//insert at previous spot in list
template< class NodeType, class ListNodeType >
inline void tList< NodeType, ListNodeType >::
insertAtPrev( const NodeType &value, ListNodeType * node )
{
  if( node != 0 )
    {
      if( node == first )
	{
	  insertAtFront( value );
	  return;
	}
      ListNodeType * newPtr = getNewNode( value );
      newPtr->next = node;
      newPtr->prev = node->prev;
      node->prev->next = newPtr;
      node->prev = newPtr;
    }
}

//delete from front
template< class NodeType, class ListNodeType >
inline int tList< NodeType, ListNodeType >::
removeFromFront( NodeType &value )
{
  if( isEmpty() ) return 0;
  ListNodeType * temp = first;
  if( first == last ) first = last = currentItem = 0;
  else
    {
      first->next->prev = first->prev;
      if( last->next == first ) last->next = first->next;
      if( currentItem==first ) currentItem = first->next;
      first = first->next;
    }
  value = temp->getData();
  delete temp;
  --nNodes;
  return 1;
}

//delete from back
template< class NodeType, class ListNodeType >
inline int tList< NodeType, ListNodeType >::
removeFromBack( NodeType &value )
{
  if( isEmpty() ) return 0;
  ListNodeType * temp = last;
  if( first == last ) first = last = currentItem = 0;
  else
    {
      last->prev->next = last->next;
      if( first->prev == last ) first->prev = last->prev;
      if( currentItem==last ) currentItem = last->prev;
      last = last->prev;
    }
  value = temp->getData();
  delete temp;
  --nNodes;
  return 1;
}

//delete next node
template< class NodeType, class ListNodeType >
inline int tList< NodeType, ListNodeType >::
removeNext( NodeType &value, ListNodeType * ptr )
{
  if( ptr == 0 ) return 0;
  if( ptr->next == 0 ) return 0;
  if( ptr->next == last ) return removeFromBack( value );
  if( ptr->next == first ) return removeFromFront( value );
  ListNodeType * temp = ptr->next;
  if( currentItem == temp ) currentItem = ptr->next->next;
  ptr->next = ptr->next->next;
  ptr->next->prev = ptr;
  value = temp->getData();
  delete temp;
  --nNodes;
  return 1;
}

//delete previous node
template< class NodeType, class ListNodeType >
inline int tList< NodeType, ListNodeType >::
removePrev( NodeType &value, ListNodeType * ptr )
{
  if( ptr == 0 ) return 0;
  if( ptr->prev == 0 ) return 0;
  if( ptr->prev == last ) return removeFromBack( value );
  if( ptr->prev == first ) return removeFromFront( value );
  ListNodeType* temp = ptr->prev;
  if( currentItem == ptr->prev ) currentItem = ptr->prev->prev;
  ptr->prev = ptr->prev->prev;
  ptr->prev->next = ptr;
  value = temp->getData();
  delete temp;
  --nNodes;
  return 1;
}

/**************************************************************************\
 **
 **  tList::Flush
 **
 **  Deletes all nodes on list.
 **
\**************************************************************************/
template< class NodeType, class ListNodeType >
void tList< NodeType, ListNodeType >::
Flush()
{
  ListNodeType * current = first, * temp;

  if( !isEmpty() )
    {
      while( current != 0 )
	{
	  temp = current;
	  current = current->next;
	  delete temp;
	}
      first = last = currentItem = 0;
    }
  assert( isEmpty() );
  nNodes = 0;
}

/**************************************************************************\
 **
 **  tList::isEmpty
 **
 **  Returns TRUE if first points to null; FALSE otherwise.
 **
\**************************************************************************/
template< class NodeType, class ListNodeType >
inline bool tList< NodeType, ListNodeType >::
isEmpty() const
{
  return BOOL( first == 0 );
}

//display list contents -- for debugging only

template< class NodeType, class ListNodeType >
void tList< NodeType, ListNodeType >::
print() const
{
  if( isEmpty() )
    {
      std::cout<<"The list is empty\n"<<std::endl;
      return;
    }
  ListNodeType * current = first;
  std::cout<<"The list is: ";
  while( current != 0 )
    {
      current = current->next;
    }
  std::cout<< '\n' <<std::endl;
}

/**************************************************************************\
 **
 **  tList "get" functions:
 **
 **  getSize: returns # of items on list
 **  getFirst: returns const ptr to first ListNodeType
 **  getLast: returns const ptr to last ListNodeType
 **  FirstP: returns ptr to first data item and sets currentItem to first
 **  NextP: returns ptr to data item following currentItem and advances
 **         currentItem to the next one on the list
 **  getIthData: returns const copy of list data item number _num_
 **  getIthDataRef: returns const reference to list data item number _num_
 **  getIthDataRef: returns const ptr to list data item number _num_
 **  getIthDataNC: returns non-const copy of list data item number _num_
 **  getIthDataRefNC: returns non-const ref to list data item number _num_
 **  getIthDataRefNC: returns non-const ptr to list data item number _num_
 **  (see also getListNode, below)
 **
\**************************************************************************/

template< class NodeType, class ListNodeType >
inline int tList< NodeType, ListNodeType >::
getSize() const {return nNodes;}

template< class NodeType, class ListNodeType >
inline ListNodeType const * tList< NodeType, ListNodeType >::
getFirst() const {return first;}

template< class NodeType, class ListNodeType >
inline ListNodeType const * tList< NodeType, ListNodeType >::
getLast() const {return last;}

template< class NodeType, class ListNodeType >
inline ListNodeType * tList< NodeType, ListNodeType >::
getFirstNC() {return first;}

template< class NodeType, class ListNodeType >
inline ListNodeType * tList< NodeType, ListNodeType >::
getLastNC() {return last;}

// Added by gt 1/99
template< class NodeType, class ListNodeType >
inline NodeType * tList< NodeType, ListNodeType >::
FirstP()
{
  assert( first!=0 );
  currentItem = first;
  return first->getDataPtrNC();
}

// Added by gt 1/99
template< class NodeType, class ListNodeType >
inline NodeType * tList< NodeType, ListNodeType >::
NextP()
{
  assert( currentItem!=0 );
  currentItem = currentItem->next;
  if( currentItem!=0 )
    return currentItem->getDataPtrNC();
  else return 0;
}

template< class NodeType, class ListNodeType >
inline const NodeType tList< NodeType, ListNodeType >::
getIthData( int num ) const
{
  assert( num >= 0 && num < nNodes );
  return getIthListNode(num)->getData();
}

template< class NodeType, class ListNodeType >
inline const NodeType &tList< NodeType, ListNodeType >::
getIthDataRef( int num ) const
{
  assert( num >= 0 && num < nNodes );
  return getIthListNode(num)->getDataRef();
}

template< class NodeType, class ListNodeType >
inline const NodeType *tList< NodeType, ListNodeType >::
getIthDataPtr( int num ) const
{
  assert( num >= 0 && num < nNodes );
  return getIthListNode(num)->getDataPtr();
}

//set
template< class NodeType, class ListNodeType >
inline NodeType tList< NodeType, ListNodeType >::
getIthDataNC( int num ) const
{
  assert( num >= 0 && num < nNodes );
  return getIthListNode(num)->getData();
}

template< class NodeType, class ListNodeType >
inline NodeType &tList< NodeType, ListNodeType >::
getIthDataRefNC( int num )
{
  assert( num >= 0 && num < nNodes );
  return getIthListNodeNC(num)->getDataRefNC();
}

template< class NodeType, class ListNodeType >
inline NodeType *tList< NodeType, ListNodeType >::
getIthDataPtrNC( int num )
{
  assert( num >= 0 && num < nNodes );
  return getIthListNodeNC(num)->getDataPtrNC();
}

/**************************************************************************\
 **
 **  tList::getListNode
 **
 **  Finds and returns the list node containing the data pointed to by
 **  desiredDatPtr, or zero if not found.
 **
 **  Parameters:  desiredDatPtr -- pointer to the data item sought after
 **  Returns:  pointer to the ListNodeType containing desiredDatPtr, or zero
 **            if not found
 **  Notes: might be safer to implement with a const return type
 **  Created: 4/29/98 GT
 **
\**************************************************************************/
template< class NodeType, class ListNodeType >
ListNodeType * tList< NodeType, ListNodeType >::
getListNode( const NodeType * desiredDatPtr )
{
  ListNodeType * listnode = first;

  if( listnode==0 ) return 0;
  while( listnode->getDataPtr() != desiredDatPtr )
    {
      listnode = listnode->next;
      if( listnode==0 ) return 0;
    }
  return listnode;

}

/**************************************************************************\
 **
 **  tList::getIthListNode( i )
 **
 **  Finds and returns the list node indicated by i [0,nnodes-1),
 **  or zero if not found.
 **
 **  Parameters:  i -- number of item sought after
 **  Returns:  pointer to the ith ListNodeType, or zero
 **            if not found
 **  Notes: might be safer to implement with a const return type
 **  Created: 4/29/98 GT
 **
\**************************************************************************/
template< class NodeType, class ListNodeType >
const ListNodeType* tList< NodeType, ListNodeType >::
getIthListNode( int num ) const
{
  if( num < 0 || num >= nNodes )
    return 0;
  int i;
  ListNodeType const * curPtr;
  if( num > nNodes / 2 )
    for( curPtr = last, i = nNodes-1; i>num; curPtr = curPtr->prev, --i );
  else
    for( curPtr = first, i = 0; i<num; curPtr = curPtr->next, ++i );
  return curPtr;
}

template< class NodeType, class ListNodeType >
ListNodeType* tList< NodeType, ListNodeType >::
getIthListNodeNC( int num )
{
  if( num < 0 || num >= nNodes )
    return 0;
  int i;
  ListNodeType * curPtr;
  if( num > nNodes / 2 )
    for( curPtr = last, i = nNodes-1; i>num; curPtr = curPtr->prev, --i );
  else
    for( curPtr = first, i = 0; i<num; curPtr = curPtr->next, ++i );
  return curPtr;
}

/**************************************************************************\
 **
 **  tList "move" functions:
 **
 **  moveToBack: looks for _mvnode_ on the list and moves it to the back
 **              of the list. Assumes that _mvnode_ IS an item on the list.
 **  moveToFront: same thing, but moves it to the front
 **
\**************************************************************************/

template< class NodeType, class ListNodeType >
inline void tList< NodeType, ListNodeType >::
moveToBack( ListNodeType * mvnode )
{
  if( mvnode != last )
    {
      if( mvnode == first )
	{
	  first->next->prev = first->prev;
	  first = first->next;
	}
      else
	{
	  mvnode->prev->next = mvnode->next;
	  mvnode->next->prev = mvnode->prev;
	}
      mvnode->next = last->next;
      mvnode->prev = last;
      if( first->prev != 0 ) first->prev = mvnode;
      last->next = mvnode;
      last = mvnode;
    }
}

template< class NodeType, class ListNodeType >
inline void tList< NodeType, ListNodeType >::
moveToFront( ListNodeType * mvnode )
{
  if( mvnode != first )
    {
      if( mvnode == last )
	{
	  last->prev->next = last->next;
	  last = last->prev;
	}
      else
	{
	  mvnode->prev->next = mvnode->next;
	  mvnode->next->prev = mvnode->prev;
	}
      mvnode->next = first;
      mvnode->prev = first->prev;
      if( last->next != 0 ) last->next = mvnode;
      first->prev = mvnode;
      first = mvnode;
    }
}

template< class NodeType, class ListNodeType >
inline void tList< NodeType, ListNodeType >::
moveToBefore( ListNodeType* mvnode,
              ListNodeType* plcnode )
{
  if( mvnode == plcnode ) return;
  if( plcnode == first )
    {
      moveToFront( mvnode );
      return;
    }
  if( mvnode == last )
    {
      last->prev->next = last->next;
      last = last->prev;
    }
  else if( mvnode == first )
    {
      first->next->prev = first->prev;
      first = first->next;
    }
  else
    {
      mvnode->prev->next = mvnode->next;
      mvnode->next->prev = mvnode->prev;
    }
  mvnode->next = plcnode;
  mvnode->prev = plcnode->prev;
  plcnode->prev->next = mvnode;
  plcnode->prev = mvnode;
}

template< class NodeType, class ListNodeType >
inline void tList< NodeType, ListNodeType >::
moveToAfter( ListNodeType* mvnode,
             ListNodeType* plcnode )
{
  if( mvnode == plcnode ) return;
  if( plcnode->next == mvnode ) return;
  if( plcnode == last )
    {
      moveToBack( mvnode );
      return;
    }
  if( mvnode == last )
    {
      last->prev->next = last->next;
      last = last->prev;
    }
  else if( mvnode == first )
    {
      first->next->prev = first->prev;
      first = first->next;
    }
  else
    {
      mvnode->prev->next = mvnode->next;
      mvnode->next->prev = mvnode->prev;
    }
  mvnode->next = plcnode->next;
  mvnode->prev = plcnode;
  plcnode->next->prev = mvnode;
  plcnode->next = mvnode;
}

/**************************************************************************\
 **
 **  tList::makeCircular
 **
 **  Converts the list into a circular list by having the last item point
 **  to the first.
 **
\**************************************************************************/
template< class NodeType, class ListNodeType >
inline void tList< NodeType, ListNodeType >::
makeCircular()
{
  assert( first != 0 && last != 0 );
  last->next = first;
  first->prev = last;
}

template< class NodeType, class ListNodeType >
void tList< NodeType, ListNodeType >::
DebugTellPtrs() const
{
  std::cout << "first: " << first << std::endl;
  std::cout << "last: " << last << std::endl;
}

/**************************************************************************/
/**
 ** @class tListIter
 **
 ** Helper class for tList. tListIters are "iterators" that walk up and
 ** down a tList, fetching items. Their chief advantage is that you can
 ** have multiple iterators on any given list at once, and thus multiple
 ** access points. Use of iterator classes is discussed by Deitel and
 ** Deitel, _C++ How to Program_, first edition, Prentice Hall, 1994.
 **
 ** Note that in the current implementation, list items are fetched by
 ** ID number, which presupposes that the list items have a member function
 ** getID. This restricts the generality of tList, and should be moved
 ** to tMeshList. (TODO)
 **
 */
/**************************************************************************/
//TO DO: make Get, Where, GetP, refer to place in list rather than use getID()
template< class NodeType, class ListNodeType >
class tListIter
{
  tListIter& operator=(const tListIter&);
  int NextIfNoCurrent();  // set 1st as current undefined
  int PrevIfNoCurrent();  // set last as current undefined
  void GetByPtrVerify( NodeType const *, ListNodeType const *);
public:
  inline tListIter();               // default constructor
  tListIter(const tListIter&);      // copy constructor
  tListIter( tList< NodeType, ListNodeType > & ); // constructor: reference to list
  tListIter( tList< NodeType, ListNodeType > * ); // constructor: ptr to list
  inline ~tListIter();   // destructor
  inline int First();    // sets position to 1st list item (rtns 0 on failure)
  inline int Last();     // sets position to last "    "     "
  int Get( int ); // use only if NodeType has member getID()!!
  inline int GetByPtr( NodeType const * );
  int GetByPtrSlow( NodeType const * );
  inline NodeType * GetByPtrP( NodeType const * );
  inline int Next();     // advances to next item (or 1st if current undefined)
  inline int Prev();     // moves to previous item (or last if current undef'd)
  inline int Where() const;  // use only if NodeType has member getID()!!
  inline bool AtEnd() const;  // returns true if at end of the list
  inline NodeType &DatRef();  // returns ref to current data item
  inline NodeType *DatPtr();  // returns ptr to current data item
  inline ListNodeType *NodePtr();  // returns ptr to current list node
  inline void Reset( tList< NodeType, ListNodeType > & ); // tells iterator to work on given list
  inline NodeType * FirstP();  // moves to 1st item and rtns ptr to it
  inline NodeType * LastP();   // moves to last  "   "
  inline NodeType * NextP();   // moves to next  "   "
  inline NodeType * PrevP();   // moves to previous " "
  inline NodeType * GetP( int num ); //use only if NodeType has member getID()!!

protected:
  ListNodeType * curnode;  // ptr to current list node
  tList< NodeType, ListNodeType > *listPtr;       // ptr to current list
  int counter;                      // current position on list (first=0)
};

/**************************************************************************\
 **
 **         FUNCTIONS FOR CLASS tListIter
 **
 **  A tListIter is an iterator for the linked list tList objects (and their
 **  descendants). Its services include fetching data from the current entry
 **  on the list, advancing to the next or previous item on the list, etc.
 **
 **  See also tMeshList.
 **
 **  Created: fall, 97, SL.
 **  Modifications:  added an "AtEnd" function that signals whether the
 **  the iterator has fallen off the end of the list, 11/17/97 gt.
 **
\**************************************************************************/

/**************************************************************************\
 **
 **  tListIter constructors & destructor:
 **
 **  Default constructor: initializes all values to 0
 **  Constructor (reference version): sets listPtr to point to _list_ and
 **                                   points curnode to 1st node on list
 **  Constructor (pointer version): same thing, but takes a pointer to a
 **                                 tList as an argument
 **
\**************************************************************************/

template< class NodeType, class ListNodeType >
inline tListIter< NodeType, ListNodeType >::
tListIter() :
  curnode(0),
  listPtr(0),
  counter(0)
{
  if (0) //DEBUG
    std::cout << "tListIter()" << std::endl;
}

template< class NodeType, class ListNodeType >
inline tListIter< NodeType, ListNodeType >::
tListIter(const tListIter& c) :
  curnode(c.curnode),
  listPtr(c.listPtr),
  counter(c.counter)
{
  if (0) //DEBUG
    std::cout << "tListIter(const tListIter&)" << std::endl;
}

template< class NodeType, class ListNodeType >
inline tListIter< NodeType, ListNodeType >::
tListIter( tList< NodeType, ListNodeType > &list ) :
  curnode(list.first),
  listPtr(&list),
  counter(0)
{
  //assert( curnode != 0 );
  if (0) //DEBUG
    std::cout << "tListIter( list )" << std::endl;
}

template< class NodeType, class ListNodeType >
inline tListIter< NodeType, ListNodeType >::
tListIter( tList< NodeType, ListNodeType > *ptr ) :
  curnode(0),
  listPtr(ptr),
  counter(0)
{
  assert( ptr != 0 );
  curnode = ptr->first;
}

template< class NodeType, class ListNodeType >
inline tListIter< NodeType, ListNodeType >::
~tListIter()
{
  listPtr = 0;
  curnode = 0;
  if (0) //DEBUG
    std::cout << "~tListIter()" << std::endl;
}

/**************************************************************************\
 **
 **  tListIter::Reset
 **
 **  Points iterator at the 1st node on _list_ (provides a way of telling
 **  an iterator which list to work on).
 **
\**************************************************************************/
template< class NodeType, class ListNodeType >
inline void tListIter< NodeType, ListNodeType >::
Reset( tList< NodeType, ListNodeType > &list )
{
  listPtr = &list;
  curnode = list.first;
  counter = 0;
}

/**************************************************************************\
 **
 **  tListIter::First and tListIter::Last
 **
 **  Move to the first or last item on the current list. Return TRUE if
 **  pointing to a valid list item, FALSE otherwise.
 **
\**************************************************************************/
template< class NodeType, class ListNodeType >
inline int tListIter< NodeType, ListNodeType >::
First()
{
  assert( listPtr != 0 );
  curnode = listPtr->first;
  counter = 0;
  if( curnode != 0 ) return 1;
  return ( curnode == 0 && listPtr->isEmpty() ) ? 1:0;
}

template< class NodeType, class ListNodeType >
inline int tListIter< NodeType, ListNodeType >::
Last()
{
  assert( listPtr != 0 );
  curnode = listPtr->last;
  counter = -1;
  return ( curnode != 0 ) ? 1:0;
}

/**************************************************************************\
 **
 **  tListIter::Get
 **
 **  Move to list item with ID number _num_. Note: assumes that list items
 **  have a member function getID()! Returns 1 if found, 0 if not.
 **
\**************************************************************************/
template< class NodeType, class ListNodeType >
int tListIter< NodeType, ListNodeType >::
Get( int num )
{
  assert( listPtr != 0 );
  if( num < 0 ) std::cout << "tListIter::Get(num): num < 0" << std::endl;
  ListNodeType *tempnodeptr;
  for( tempnodeptr = listPtr->first, counter = 0;
       counter <= listPtr->nNodes && tempnodeptr != 0;
       tempnodeptr = tempnodeptr->next, ++counter )
    {
      if( tempnodeptr->getDataPtr()->getID() == num ) break;
    }
  if( tempnodeptr == 0 ) return 0;
  if( tempnodeptr->getDataPtr()->getID() != num ) return 0;
  curnode = tempnodeptr;
  return 1;
}

/**************************************************************************\
 **
 **  tListIter::GetByPtr
 **
 **  Move to list item with the same adress.
 **
\**************************************************************************/
template< class NodeType, class ListNodeType >
inline int tListIter< NodeType, ListNodeType >::
GetByPtr( NodeType const *dataPtr )
{
  assert( listPtr != 0 );
  assert( dataPtr != 0 );

  if (ListNodeType::isListable) {
    // ListNodeType is "listable". Therefore, we use the back pointer.
    ListNodeType *tempnodeptr = ListNodeType::getListPtr( dataPtr );
    if (0) //DEBUG
      GetByPtrVerify( dataPtr, tempnodeptr);
    if (tempnodeptr == 0)
      return 0;
    curnode = tempnodeptr;
    counter = -2;
    return 1;
  } else
    // linear search.
    return GetByPtrSlow( dataPtr );
}

template< class NodeType, class ListNodeType >
void tListIter< NodeType, ListNodeType >::
GetByPtrVerify( NodeType const *dataPtr, ListNodeType const *tempnodeptr )
{
  if (Get(dataPtr->getID()) != 0)
    assert(tempnodeptr == curnode);
  else
    assert(tempnodeptr == 0);
}

template< class NodeType, class ListNodeType >
int tListIter< NodeType, ListNodeType >::
GetByPtrSlow( NodeType const *dataPtr )
{
  assert( listPtr != 0 );
  if( dataPtr == NULL )
    std::cout << "tListIter::GetByPtr(ptr): ptr < 0" << std::endl;

  // linear search.
  ListNodeType *tempnodeptr;
  for( tempnodeptr = listPtr->first, counter = 0;
       counter <= listPtr->nNodes && tempnodeptr != 0;
       tempnodeptr = tempnodeptr->next, ++counter )
    {
      if( tempnodeptr->getDataPtr() == dataPtr ) break;
    }
  if( tempnodeptr == 0 ) return 0;
  if( tempnodeptr->getDataPtr() != dataPtr ) return 0;
  curnode = tempnodeptr;
  return 1;
}

/**************************************************************************\
 **
 **  tListIter::GetByPtrP
 **
 **  Similar to Get, but returns a pointer to the current data item (or
 **  0 if undefined).
 **
\**************************************************************************/
template< class NodeType, class ListNodeType >
inline NodeType * tListIter< NodeType, ListNodeType >::
GetByPtrP( NodeType const *dataPtr )
{
  return ( GetByPtr( dataPtr ) ) ?
    curnode->getDataPtrNC() : 0;
}

/**************************************************************************\
 **
 **  tListIter::Next and tListIter::Prev
 **
 **  Move to the next or previous item on the current list. Return TRUE if
 **  pointing to a valid list item, FALSE otherwise. If we're not
 **  initially pointing to any item, then move to the first or last item,
 **  respectively. Both assume we're working on a valid list.
 **
\**************************************************************************/
template< class NodeType, class ListNodeType >
inline int tListIter< NodeType, ListNodeType >::
Next()
{
  if( likely(curnode != 0) )
    {
      curnode = curnode->next;
      ++counter;
      return curnode != 0 ? 1:0;
    }
  // unlikely case
  return NextIfNoCurrent();
}

template< class NodeType, class ListNodeType >
int tListIter< NodeType, ListNodeType >::
NextIfNoCurrent()
{
  assert( listPtr != 0 );
  assert( curnode == 0 );
  curnode = listPtr->first;
  counter = 0;
  return curnode != 0 ? 1:0;
}

template< class NodeType, class ListNodeType >
inline int tListIter< NodeType, ListNodeType >::
Prev()
{
  if( likely(curnode != 0) )
    {
      curnode = curnode->prev;
      --counter;
      return curnode != 0 ? 1:0;
    }
  // unlikely case
  return PrevIfNoCurrent();
}

template< class NodeType, class ListNodeType >
int tListIter< NodeType, ListNodeType >::
PrevIfNoCurrent()
{
  assert( listPtr != 0 );
  assert( curnode == 0 );
  curnode = listPtr->last;
  counter = -1;
  return curnode != 0 ? 1:0;
}

/**************************************************************************\
 **
 **  tListIter::FirstP and tListIter::LastP
 **
 **  Move to the first or last item on the list and return a pointer to the
 **  data, or 0 if first/last item is empty.
 **
\**************************************************************************/
template< class NodeType, class ListNodeType >
inline NodeType * tListIter< NodeType, ListNodeType >::
FirstP()
{
  return ( First() ) ?
    curnode->getDataPtrNC() : 0;
}

template< class NodeType, class ListNodeType >
inline NodeType * tListIter< NodeType, ListNodeType >::
LastP()
{
  return ( Last() ) ?
    curnode->getDataPtrNC() : 0;
}

/**************************************************************************\
 **
 **  tListIter::NextP and tListIter::PrevP
 **
 **  Same as Next and Prev, except that the functions return a pointer to
 **  the current data item (or 0 if none exists).
 **
\**************************************************************************/

template< class NodeType, class ListNodeType >
inline NodeType * tListIter< NodeType, ListNodeType >::
NextP()
{
  return ( Next() ) ?
    curnode->getDataPtrNC() : 0;
}

template< class NodeType, class ListNodeType >
inline NodeType *tListIter< NodeType, ListNodeType >::
PrevP()
{
  return ( Prev() ) ?
    curnode->getDataPtrNC() : 0;
}

/**************************************************************************\
 **
 **  tListIter::GetP
 **
 **  Similar to Get, but returns a pointer to the current data item (or
 **  0 if undefined).
 **
\**************************************************************************/
template< class NodeType, class ListNodeType >
inline NodeType * tListIter< NodeType, ListNodeType >::
GetP( int num )
{
  return ( Get( num ) ) ?
    curnode->getDataPtrNC() : 0;
}

/**************************************************************************\
 **
 **  tListIter::Where
 **
 **  Returns the ID number of the current data item, or -1 if there is
 **  no current data item. Assumes data item has a getID() mbr function!
 **
\**************************************************************************/
template< class NodeType, class ListNodeType >
inline int tListIter< NodeType, ListNodeType >::
Where() const
{
  return ( curnode == 0 ) ?
    -1 : curnode->getDataPtr()->getID();
}

/**************************************************************************\
 **
 **  tListIter::AtEnd
 **
 **  Returns TRUE if:
 **   - the list is empty
 **   - the list is non-circular and the current item is null
 **   - the list is circular, the current item is the first, and the
 **     counter is nonzero (meaning we've gone all the way through the
 **     list and come back to the start)
 **
\**************************************************************************/
template< class NodeType, class ListNodeType >
inline bool tListIter< NodeType, ListNodeType >::
AtEnd() const
{
  if( listPtr->isEmpty() ) return true;
  if( listPtr->last->next == 0 ) return BOOL( curnode==0 );
  return BOOL( curnode == listPtr->first && counter != 0 );
}

/**************************************************************************\
 **
 **  tListIter::DatRef, DatPtr, and NodePtr
 **
 **  Returns a non-constant reference or pointer to the current data item
 **  or the current list node.
 **
\**************************************************************************/
template< class NodeType, class ListNodeType >
inline NodeType &tListIter< NodeType, ListNodeType >::
DatRef()
{
  return curnode->getDataRefNC();
}

template< class NodeType, class ListNodeType >
inline NodeType *tListIter< NodeType, ListNodeType >::
DatPtr()
{
  return ( curnode == 0 ) ?
    0 : curnode->getDataPtrNC();
}

template< class NodeType, class ListNodeType >
inline ListNodeType *tListIter< NodeType, ListNodeType >::
NodePtr()
{
  return curnode;
}

#endif


Resourcefulness has transformed Washington agriculture.
In only a few generations, Washington farm families transformed our state into one of the major food producers for the world. Washivore celebrates the "spirit" of Washington agriculture characterized by resourcefulness and innovation. While there are over 300 different crops grown here, wheat and apples are perhaps the most familiar and reflect the progress of agriculture over the last hundred years.
One job requiring skill back then was to sew bags shut as they were filled with ripe grain. The bags were then carted to sheds to be stored.
The grandfathers and great-grandfathers of today's farmers used to harvest wheat with a 22-horse team and a crew of about two dozen men and boys. Harvesting on slopes was very dangerous.
Grain harvested today is stored in elevators to await transportation to market by rail or barge.
Washington farmers have always been quick to adopt changes and embrace new knowledge. The video above explains how this characteristic has allowed farming to continue supporting communities into the future.
The charts below show the impact modern farming techniques have had on wheat harvest.
Statistics on historic wheat production in Washington available here.
Feeding the men it took to harvest wheat at the beginning of the 20th century took a special kind of resourcefulness. The cooks would drive the wagon out to the fields and have food ready by the time the horses came in for watering and feeding. The "spirit" of Washington agriculture permeated the noon-time meal.
Taste the past. The recipes below were popular with farm cooks in the 1890's.
After just a few generations of innovation and imaginative marketing, Washington farmers have had a powerful impact on today's popular food culture. Entire television shows are dedicated to showcasing food produced in Washington. Click on the video below to watch an episode of Washington Grown featuring our state's apple crop.
Celebrity chefs and nutrition-consciousness are hallmarks of these modern recipes.
Washington's oldest fruit orchards date back to the mid-1870's when pioneers brought fruit saplings from their farms in the Midwest. The fruit trees found ideal growing conditions in the long sunny days, cool summer nights and soils with volcanic ash in Central Washington. Soon, orchards were set up in the region and fruit packing houses sprang up in small towns along the railroad lines. As irrigation canals were dug, more water became available and apple orchards quickly spread.
Photo courtesy of the Yakima Valley Museum circa 1905.
Apple packing has seen a huge benefit from innovation in technological engineering. Apple grading, for example, no longer must be done entirely by hand. This has resulted in better quality fruit available to the markets with less labor cost.
The charts below show the impact modern farming techniques have had on apple production.
Not only have acres and pounds increased, a tremendous change has taken place in the many products we can make from apples now.
For historical data about Washington's apple crop click here.
More varieties of apples are available today for the fresh market. Methods for harvesting apples have not changed as significantly as other aspects of agriculture. In the future, innovative thinking could lead to dramatically different approaches to harvest.
Spokane Library NW History collection.
The Spirit of Washington agriculture has always been about innovation. It's about finding new ways of tackling old problems.
In the future, apples may be harvested by computer-aided robots controlled by one person at a computer screen. The human-robot partnership may allow fruit to be harvested by just a few orchard workers.


눈이 있어도 보지 못하고 귀가 있어도 듣지 못하는 이스라엘 백성은 하나님께 불순종함으로 바벨론 포로로 살았습니다. 그러나 그렇게 불순종한 이스라엘을 하나님은 아비와 에미의 마음으로 '보배롭고 존귀하게 여긴다'(사 43:4)고 하십니다. 그리고 저들을 사방에서 다 돌아오게 하십니다. 그것은 하나님이 하나님이심을 저들로 깨달아 알게하게 하심입니다. 곧 하나님이 구원자이심을 저들이 체험하고 증인이 되게 하려 하심입니다.
내가 낳은 자식은 부모에게 '보배롭고 존귀한자'입니다. 그래서 어떻게 하여서든지 잘되게 할려고 모든 것을 다하여 돕습니다. 이스라엘은 하나님이 택하시고 하나님이 부르셨기에 하나님이 끝까지 포기하지 않으시고 회복시키실 것입니다. 그래서 하나님의 능력을 체험하고 저들로 하나님을 증거하게 하십니다.
나같은 죄인을 끝까지 포기하지 않으시고 구원하신 주님을 찬양합니다. 그 주님의 증인으로 살게 하심을 참 감사드립니다. 나는 주님이 보시기에 '보배롭고 존귀한 자'입니다. 교만이 아닌 확신으로 오늘을 살게 하소서! 이제 내일은 유대인을 위하여 '죄송합니다'를 가지고 나갑니다. 성령님이 함께 하셔서 증인된 사명을 잘 감당하게 하소서!
Israelites had been taken into Babylonian captivity due to their disobedience caused by their spiritual blindness and deaf. However, God had considered them to be 'precious and honored' (Isaiah 43:4) in his sight with the heart of father and mother. And then God would led them back home from wherever they had been scattered. God would do that because God wanted them to know He was God. God wanted them to be God's witnesses after experiencing God's power.
My children whom I have given birth are 'precious and honored.' Therefore, the parents do their best to help their children advancing. Since God has chosen and called them to be Gods' children, God will do God's best to restore without abandoning them. Therefore, God wants them to be God's witnesses after experiencing God's might and power.
I praise the Lord who has never given upon me and saved me. And my gratitude to my Lord is beyond my description because the Lord has used me as his witness. I am 'precious and honored' in his sight. Therefore, I want to live today with assurance not pride. Tomorrow I will go to the Jews with 'I apologize' letter. Oh Holy Spirit please be with me so that I may be used as God's witness toward the multitude of Jews.


text:
Putin's Fairy Tale
Why Russia Will Try -- and Fail -- To Build a New Empire
By Alexander Kliment
ALEXANDER KLIMENT is Director of Russia and Emerging Markets research at the political risk analysis firm Eurasia Group.
More By Alexander Kliment
Vladimir Putin stands in front of a map of Russia in his residence outside of Moscow.
Since returning to the Russian presidency in 2012 amid stagnant economic growth and dropping poll numbers, Vladimir Putin has been grasping for a narrative that could legitimize a second decade of his rule. That search explains, in part, why Putin seized on the crisis in Ukraine. It has allowed him to present a bold new vision for Russia, one based on a promise of a national resurgence, a promise that is hugely appealing for Russians -- in the short term, at least. But in the long term, Putin's new national story has only set them up for disappointment and economic
Source URL: https://www.foreignaffairs.com/articles/russia-fsu/2014-03-31/putins-fairy-tale

redpajama_set_name: RedPajamaCommonCrawl


text:
The private chef runs a restaurant with a difference
Waitrose Weekend
Bleacher Report - Veganism in Football
Veganism in Football: Performance Game-Changer or Social Media-Fueled Fad?
Food for Footballers
Ever wondered what Premier League football players eat? This book tells you all you need to know to eat as well as you can to enable you to be the best that you can be.
The Performance Chef who keeps athletes on their toes
Click here to read an article on the BBC website, in which Rachel is interviewed about our work with elite athletes.
Traditional British food is evolving, not dying
Are British dishes soon to be a thing of the past?
Team GB Swimmers and Healthy Food TV Show
Chefs work with Team GB swimmers and star in healthy food TV programme.
Stonehenge The Kitchen Cabinet, Series 12
Jay Rayner hosts the culinary panel programme from Stonehenge. Audience questions are answered by food historian Dr Annie Gray, master of DIY cooking Tim Hayward, Scottish chef with a Catalan twist Rachel McCormack, and the singer-turned-chef Andi Oliver.
A Passion Never Bores
Rachel Muse is a chef from Salisbury who has recently started a pop-up restaurant in the city called Talk Eat Laugh. She first turned to food after graduating with a degree in maths and finding no jobs on offer. Here she explains more about her passion for food.
What's it like to be a woman in business in 2015?
We asked some of Salisbury's finest working women about their experiences....
Guest Blog of the Month!
Pop up restaurants are quickly becoming an alternative to traditional dining out. As the name suggests, pop up restaurants are literally eateries that pop up from nowhere, often at an unusual venue, or perhaps in the setting of a private home.
The private chef runs a restaurant with a difference – it's only open for one night every now and then


The only thing missing from Windsor developer Stan Everitt was a white beard. Complete with a Santa Claus hat over his cowboy hat, Everitt played Santa two days early.
Everitt, of Everitt Cos. in Fort Collins, donated about six acres of land in Severance to the Windsor-Severance Fire Protection District for a future fire station. The donation was announced Wednesday.
Everitt, 57, said the company founded by his dad, Bob, 81, makes it a point to donate to others.
The property is located off the west side of Timber Ridge Parkway. The land sits off Weld County Road 74, which will provide easy access for the fire trucks.


Cassilda's Song is a collection of weird fiction and horror stories based on the King in Yellow Mythos created by Robert W. Chambers—entirely authored by women. There are no pretenders here. The Daughters of the Yellow Sign, each a titan of unmasked fire in their own right, have parted the curtains. From Hali's deeps and Carcosa's gloomy balconies and Styx-black towers, come their lamentations and rage and the consequences of intrigues and follies born in Oblivion. Run into their embrace. Their carriages wait to take you from shadowed rooms and cobblestones to The Place Where the Black Stars Hang.
The 1895 release of Chambers' best-remembered work of weird fiction was salted with nihilism and ennui, and ripe with derangement, haunting beauty, and eerie torments. Poe's influence was present in the core tales and one could easily argue Chambers may have been influenced by the French Decadents and the disquieting transfigurations of the Symbolists. All this and more can be said of the works collected in this anthology. Carcosa, accursed and ancient, and cloud-misted Lake of Hali are here. The Hyades sing and the cloud waves break in these tales. The authority of Bierce's cosmic horror is here. The talismantic Yellow Sign, and the titular 'hidden' King, and The Imperial Dynasty of America, will influence and alter you, as they have the accounts by these writers. Cassilda and other unreliable narrators, government-sponsored Lethal Chambers, and the many mysteries of the mythical Play, are boldly represented in these tributes to Chambers.
Glorantha's Michael O'Brien talks to Joe Pulver, editor of the Chaosium anthology Cassilda's Song: Tales Inspired by Robert W. Chambers King in Yellow Mythos, in contention for two World Fantasy Awards later this month ("Best Anthology" and "Best Short Story" for 'The Neurastheniac' by Selena Chambers).
Cassilda's Song has been described as "featuring a who's who of not just the top women writing weird fiction today but some of the very best authors and stories of the year period".
Cassilda's Song has been nominated for two 2016 World Fantasy Awards. The WFA awards will be presented during the World Fantasy Convention, held October 27-30, 2016 in Columbus Ohio.
Are you accepting subs for it or is it strictly by invitation only?
I'm sorry for replying so late – wordpress hid your question from me.
The anthology that Mr. Pulver has been editing was by invitation only.


The biggest discounts this year.
Cellular operator "MegaFon" announced the launch of major sales "Cyberpowerinc". From 28 to 30 January 2019 in the online store "MegaFon" will be available powerful discounts on smartphones, smart watches, external batteries and other products.
28 Jan almost all the leading electronics stores launched sales, timed to coincide with "cyber Monday". "Megaphone" has decided not to lag behind from "Beeline", MTS and "Coherent", and announced the holding of its own shares with large discounts on various products.
Sale "Cyberpowerinc" from "MegaFon" will be held three days from 28 to 30 January. These days the buyers of the online store operator will be able to buy smartphones, smart watches, headphones, portable batteries, and other products with real discounts up to 30%.
Full list of products subject to discounts presented on this page. Note really have that, since this is the first massive discounts in the online store "MegaFon" in 2019.


Ooredoo has signed an agreement with the Ministry of Endowment and Religious Affairs to adopt and optimise artificial intelligence (AI) technologies for Big Data and the Internet of Things (IoT).
Oman Data Park (ODP) and Cisco have announced that ODP has deployed Cisco Advanced Malware Protection (AMP) as part of its ODP Managed Security Services for end point protection.
Omantel has reportedly partnered with Blockchain Solutions and Services (BSS) for mutual cooperation between the two companies, which include availing the smart solutions offered by BSS in logistic and commercial operations.


text:
Pubali bank to auction Keya factories, founder's luxury apartment complex
The bank has requested interested buyers to apply within 24 May
Failing to recover default loans from Keya Group despite several compromises, Pubali Bank Limited, a lender to the group, now prefers a tougher ending.
The commercial bank has already published an advertisement, inviting tenders for the planned auction of nearly 850 decimals of the land of Keya Group's factory complex along with the factory infrastructure and also the mortgaged luxury apartment complex owned by the sponsor-directors in the capital's Gulshan area.
The luxury apartment complex, where some foreign ambassadors also reside, is now worth around Tk270 crore, according to Pubali Bank's estimation.
The bank has requested interested buyers to apply within 24 May.
The auction schedule includes assets owned by Keya Group's flagship company Keya Cosmetics Ltd, Keya Yarn Mills Ltd and its founder Abdul Khalek Pathan and his family members.
With uncharged interests added, Keya Group and its sponsor-directors owe more than Tk800 crore to Pubali Bank, according to the bank's advertisement for auction.
However, the total liabilities to the commercial bank were resettled at around Tk500 crore and the client has been trying to tame the bank by paying a lump sum of the actual payable in instalments, according to Pubali Bank officials.
Pubali Bank Managing Director Safiul Alam Khan Chowdhury told The Business Standard, "Resettling debts, moratorium – nothing worked for recovering loans from the client, and with the central bank's relief period having ended recently, our board decided to try hard now."
"Recovering the bank's assets is part of our fiduciary duties," he said, replying to TBS queries on why the bank preferred the hard-line during the pandemic.
"We have full provision against the default loans as per the central bank instructions. We also have 42.39% of Keya Cosmetics' shares in lien," said the bank's top executive to assure his own shareholders.
"In the pandemic situation, we struggled to pay the promised sum of instalments recently and the partial payment resulted in a misunderstanding between the bank and us," said Homaun Kabir FCA, chief financial officer of Keya Group.
He has had a meeting with the bankers on Thursday and expects that the bank would withdraw its advertisement for auction.
The rise and fall of Keya
Keya Group is an example of how a business can grow fast in Bangladesh and fall at an even faster pace.
Abdul Khalek Pathan, a professional driver turned entrepreneur, founded his detergent and soap business in the 1990s, which grew to the top tier in the local market alongside achieving export trophies in the early 2000s when the business got listed on the stock market.
It expanded to export-oriented textile and apparel business seriously and bagged successes there too.
But, aggressive financial planning, misreporting of assets and liabilities, and the amalgamation of troubled assets with the listed company together resulted in the fall of the once-a-glorious entity.
Keya Cosmetics Ltd, which owns the group's soaps and detergent business alongside most of the textile units, had absorbed an asset meltdown in the fiscal 2018-19 since the accounting regulator ordered the company to write off fake assets amounting to over Tk1,000 crore.
Due to a one-off annual loss bigger than its paid-up capital, Keya Cosmetics' net asset value came down to near zero, which saw a slight improvement with some profits posted for the fiscal 2019-20.
On top of all the shocks, Keya Cosmetics' shareholders have now absorbed another fresh round of uncertainty following the Pubali Bank advertisement inviting tenders for auctioning Keya factories, its founder's luxury apartment complex, to recover default loans.
Keya's shares closed at Tk5.7 each, which is 1.7% down from the previous session's closing price.
Against the face value of Tk10 each, Keya Cosmetics' net asset value per share was Tk0.25 at the end of last fiscal year.
SOURCE: tbsnews


text:
Grand delirium: I Will Dump Buhari And APC If My Son-In-law Is Denied Imo Governorship Ticket. – Rochas Okorocha.
The Chairman Of All Progressives Governors' Forum and Governor of Imo State, Rochas Okorocha has threatened to dump the ruling party, the APC if his preferred Governorship candidate and son-in-law, Uche Nwosu is denied ticket.
Governor Okorocha made this disclosure during the swearing in of new Commissioners in the state at Nicks Banquet Hall, Government House, Owerri.
The two time Governor also vowed to dump President Muhammadu Buhari's re-election should any attempt was made to drop his son-in-law in the 2019 governorship election.
According to him, President Buhari cannot win any election in the South East geo-political zone in particular and Nigeria at large in 2019 without his contribution, warning that any attempt to subvert his choice candidate would be counter productive to the party in the country.
He boasted that if not by his personal recognition and connection, President Buhari would not have been allowed into the South East to canvass for vote, let alone winning the general election in 2015.
He therefore challenged President Buhari, Chairman of APC, Adams Oshiemole and members of the National Working Committee of the ruling party to dare him and see if the party would not record total failure in 2019.
Governor Okorocha while charging the new Commissioners to inject their wealth of experience to ensure the development of the state, further told them to remain calm and wait for any possible directive from him should the party fails to give Uche Nwosu Governorship ticket.
Meanwhile, Adviser to Governor Okorocha on Electoral Matters, Barrister Steve Asinobi has blasted the National Chairman of APC, Adams Oshiomole over what he called orchestrated plan to relegate his boss politically, describing him as a Biblical Nichodemus who should not be trusted.
Barr Asinobi warned that if his boss son-in-law, Uche Nwosu is denied party ticket, their followers would not hesitate to destroy APC not only in Imo State but the entire South East.
He gave this warning during his outing on a live TV and Radio programmes on AIT and Imo Broadcasting Corporation (IBC) respectively. Barr Asinobi threated that APC would become a history in the state once Uche Nwosu's name is expunged as Governorship candidate of the party in 2019.
PreviousIGBO MUST VOTE OVERWHELMINGLY FOR BUHARI IN 2019 TO GET 2023 TICKET' – NGIGE. YORUBA MUST VOTE OVERWHELMINGLY FOR BUHARI IN 2019 TO GET 2023 TICKET'- FASHOLA
NextNDIGBO AND THE UNFOLDING DRAMA OF 2019.


text:
Lucille "Lucy" Kostecki
Mrs. Lucy Kostecki, age 79, passed away Wednesday, December 8, 2021, surrounded by her family at home. Lucy moved from St. Louis, MO with her husband, Stan Kostecki; children: Chris Kostecki, Margaret (Bob) Wurn, and Kathy Deal. Lucy enjoyed spending time with her grandchildren and was a proud grandma of five grandchildren and seven great-grandchildren. Lucy greatly enjoyed the tri-cities communities and the many friendships she developed over the past 45 years. A memorial service will take place Thursday, May 26, 2022, at St. Mary's Catholic Church in Spring Lake. Memorial contributions in memory of Lucy may be given to Alzheimer's Association. Please sign the family's online guestbook at www.sytsemafh.com.
Mrs. Lucy Kostecki, age 79, passed away Wednesday, December 8, 2021, surrounded by her family at home. Lucy moved from St. Louis, MO with her husband, Stan Kostecki; children: Chris Kostecki, Margaret (Bob) Wurn, and Kathy Deal. Lucy enjoyed... View Obituary & Service Information
The family of Lucille "Lucy" Kostecki created this Life Tributes page to make it easy to share your memories.
Mrs. Lucy Kostecki, age 79, passed away Wednesday, December 8,...
Send flowers to the Kostecki family.
© 2022 Sytsema Funeral & Cremation Services. All Rights Reserved.


text:
<?php

/*
 * This file is part of PHP CS Fixer.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *     Dariusz Rumiński <dariusz.ruminski@gmail.com>
 *
 * This source file is subject to the MIT license that is bundled
 * with this source code in the file LICENSE.
 */

namespace PhpCsFixer\Fixer\PhpUnit;

use PhpCsFixer\AbstractFixer;
use PhpCsFixer\Fixer\ConfigurationDefinitionFixerInterface;
use PhpCsFixer\FixerConfiguration\FixerConfigurationResolverRootless;
use PhpCsFixer\FixerConfiguration\FixerOptionBuilder;
use PhpCsFixer\FixerConfiguration\FixerOptionValidatorGenerator;
use PhpCsFixer\FixerDefinition\CodeSample;
use PhpCsFixer\FixerDefinition\FixerDefinition;
use PhpCsFixer\Tokenizer\Token;
use PhpCsFixer\Tokenizer\Tokens;

/**
 * @author SpacePossum
 * @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
 */
final class PhpUnitDedicateAssertFixer extends AbstractFixer implements ConfigurationDefinitionFixerInterface
{
    private static $fixMap = [
        'array_key_exists' => ['assertArrayNotHasKey', 'assertArrayHasKey'],
        'empty' => ['assertNotEmpty', 'assertEmpty'],
        'file_exists' => ['assertFileNotExists', 'assertFileExists'],
        'is_array' => true,
        'is_bool' => true,
        'is_boolean' => true,
        'is_callable' => true,
        'is_dir' => ['assertDirectoryNotExists', 'assertDirectoryExists'],
        'is_double' => true,
        'is_float' => true,
        'is_infinite' => ['assertFinite', 'assertInfinite'],
        'is_int' => true,
        'is_integer' => true,
        'is_long' => true,
        'is_nan' => [false, 'assertNan'],
        'is_null' => ['assertNotNull', 'assertNull'],
        'is_numeric' => true,
        'is_object' => true,
        'is_readable' => ['assertNotIsReadable', 'assertIsReadable'],
        'is_real' => true,
        'is_resource' => true,
        'is_scalar' => true,
        'is_string' => true,
        'is_writable' => ['assertNotIsWritable', 'assertIsWritable'],
    ];

    /**
     * @var string[]
     */
    private $functions = [];

    /**
     * {@inheritdoc}
     */
    public function configure(array $configuration = null)
    {
        parent::configure($configuration);

        if (isset($this->configuration['functions'])) {
            @trigger_error('Option "functions" is deprecated and will be removed in 3.0, use option "target" instead.', E_USER_DEPRECATED);
            $this->functions = $this->configuration['functions'];

            return;
        }

        // assertions added in 3.0: assertArrayNotHasKey assertArrayHasKey assertFileNotExists assertFileExists assertNotNull, assertNull
        $this->functions = [
            'array_key_exists',
            'file_exists',
            'is_null',
        ];

        if (PhpUnitTargetVersion::fulfills($this->configuration['target'], PhpUnitTargetVersion::VERSION_3_5)) {
            // assertions added in 3.5: assertInternalType assertNotEmpty assertEmpty
            $this->functions = array_merge($this->functions, [
                'empty',
                'is_array',
                'is_bool',
                'is_boolean',
                'is_callable',
                'is_double',
                'is_float',
                'is_int',
                'is_integer',
                'is_long',
                'is_numeric',
                'is_object',
                'is_real',
                'is_resource',
                'is_scalar',
                'is_string',
            ]);
        }

        if (PhpUnitTargetVersion::fulfills($this->configuration['target'], PhpUnitTargetVersion::VERSION_5_0)) {
            // assertions added in 5.0: assertFinite assertInfinite assertNan
            $this->functions = array_merge($this->functions, [
                'is_infinite',
                'is_nan',
            ]);
        }

        if (PhpUnitTargetVersion::fulfills($this->configuration['target'], PhpUnitTargetVersion::VERSION_5_6)) {
            // assertions added in 5.6: assertDirectoryExists assertDirectoryNotExists assertIsReadable assertNotIsReadable assertIsWritable assertNotIsWritable
            $this->functions = array_merge($this->functions, [
                'is_dir',
                'is_readable',
                'is_writable',
            ]);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function isCandidate(Tokens $tokens)
    {
        return $tokens->isTokenKindFound(T_STRING);
    }

    /**
     * {@inheritdoc}
     */
    public function isRisky()
    {
        return true;
    }

    /**
     * {@inheritdoc}
     */
    public function getDefinition()
    {
        return new FixerDefinition(
            'PHPUnit assertions like "assertInternalType", "assertFileExists", should be used over "assertTrue".',
            [
                new CodeSample(
                    '<?php
$this->assertTrue(is_float( $a), "my message");
$this->assertTrue(is_nan($a));
'
                ),
                new CodeSample(
                    '<?php
$this->assertTrue(is_dir($a));
$this->assertTrue(is_writable($a));
$this->assertTrue(is_readable($a));
',
                    ['target' => PhpUnitTargetVersion::VERSION_5_6]
                ),
            ],
            null,
            'Fixer could be risky if one is overriding PHPUnit\'s native methods.'
        );
    }

    /**
     * {@inheritdoc}
     */
    public function getPriority()
    {
        // should be run after the PhpUnitConstructFixer.
        return -15;
    }

    /**
     * {@inheritdoc}
     */
    protected function applyFix(\SplFileInfo $file, Tokens $tokens)
    {
        static $searchSequence = [
            [T_VARIABLE, '$this'],
            [T_OBJECT_OPERATOR, '->'],
            [T_STRING],
        ];

        $index = 1;
        $candidate = $tokens->findSequence($searchSequence, $index);
        while (null !== $candidate) {
            end($candidate);
            $index = $this->getAssertCandidate($tokens, key($candidate));
            if (is_array($index)) {
                $index = $this->fixAssert($tokens, $index);
            }

            ++$index;
            $candidate = $tokens->findSequence($searchSequence, $index);
        }
    }

    /**
     * {@inheritdoc}
     */
    protected function createConfigurationDefinition()
    {
        $values = [
            'array_key_exists',
            'empty',
            'file_exists',
            'is_array',
            'is_bool',
            'is_boolean',
            'is_callable',
            'is_double',
            'is_float',
            'is_infinite',
            'is_int',
            'is_integer',
            'is_long',
            'is_nan',
            'is_null',
            'is_numeric',
            'is_object',
            'is_real',
            'is_resource',
            'is_scalar',
            'is_string',
        ];

        sort($values);

        return new FixerConfigurationResolverRootless('functions', [
            (new FixerOptionBuilder('functions', '(deprecated, use `target` instead) List of assertions to fix (overrides `target`).'))
                ->setAllowedTypes(['null', 'array'])
                ->setAllowedValues([
                    null,
                    (new FixerOptionValidatorGenerator())->allowedValueIsSubsetOf($values),
                ])
                ->setDefault(null)
                ->getOption(),
            (new FixerOptionBuilder('target', 'Target version of PHPUnit.'))
                ->setAllowedTypes(['string'])
                ->setAllowedValues([
                    PhpUnitTargetVersion::VERSION_3_0,
                    PhpUnitTargetVersion::VERSION_3_5,
                    PhpUnitTargetVersion::VERSION_5_0,
                    PhpUnitTargetVersion::VERSION_5_6,
                    PhpUnitTargetVersion::VERSION_NEWEST,
                ])
                ->setDefault(PhpUnitTargetVersion::VERSION_5_0) // @TODO 3.x: change to `VERSION_NEWEST`
                ->getOption(),
        ]);
    }

    /**
     * @param Tokens $tokens
     * @param int    $assertCallIndex Token index of assert method call
     *
     * @return int|int[] indexes of assert call, test call and positive flag, or last index checked
     */
    private function getAssertCandidate(Tokens $tokens, $assertCallIndex)
    {
        $content = strtolower($tokens[$assertCallIndex]->getContent());
        if ('asserttrue' === $content) {
            $isPositive = 1;
        } elseif ('assertfalse' === $content) {
            $isPositive = 0;
        } else {
            return $assertCallIndex;
        }

        // test candidate for simple calls like: ([\]+'some fixable call'(...))
        $assertCallOpenIndex = $tokens->getNextMeaningfulToken($assertCallIndex);
        if (!$tokens[$assertCallOpenIndex]->equals('(')) {
            return $assertCallIndex;
        }

        $testDefaultNamespaceTokenIndex = false;
        $testIndex = $tokens->getNextMeaningfulToken($assertCallOpenIndex);

        if (!$tokens[$testIndex]->isGivenKind([T_EMPTY, T_STRING])) {
            if (!$tokens[$testIndex]->isGivenKind(T_NS_SEPARATOR)) {
                return $testIndex;
            }

            $testDefaultNamespaceTokenIndex = $testIndex;
            $testIndex = $tokens->getNextMeaningfulToken($testIndex);
        }

        $testOpenIndex = $tokens->getNextMeaningfulToken($testIndex);
        if (!$tokens[$testOpenIndex]->equals('(')) {
            return $testOpenIndex;
        }

        $testCloseIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $testOpenIndex);

        $assertCallCloseIndex = $tokens->getNextMeaningfulToken($testCloseIndex);
        if (!$tokens[$assertCallCloseIndex]->equalsAny([')', ','])) {
            return $assertCallCloseIndex;
        }

        return [
            $isPositive,
            $assertCallIndex,
            $assertCallOpenIndex,
            $testDefaultNamespaceTokenIndex,
            $testIndex,
            $testOpenIndex,
            $testCloseIndex,
            $assertCallCloseIndex,
        ];
    }

    /**
     * @param Tokens $tokens
     * @param array  $assertIndexes
     *
     * @return int index up till processed, number of tokens added
     */
    private function fixAssert(Tokens $tokens, array $assertIndexes)
    {
        list(
            $isPositive,
            $assertCallIndex,
            ,
            $testDefaultNamespaceTokenIndex,
            $testIndex,
            $testOpenIndex,
            $testCloseIndex,
            $assertCallCloseIndex
        ) = $assertIndexes;

        $content = strtolower($tokens[$testIndex]->getContent());
        if (!in_array($content, $this->functions, true)) {
            return $assertCallCloseIndex;
        }

        if (is_array(self::$fixMap[$content])) {
            if (false !== self::$fixMap[$content][$isPositive]) {
                $tokens[$assertCallIndex] = new Token([T_STRING, self::$fixMap[$content][$isPositive]]);
                $this->removeFunctionCall($tokens, $testDefaultNamespaceTokenIndex, $testIndex, $testOpenIndex, $testCloseIndex);
            }

            return $assertCallCloseIndex;
        }

        $type = substr($content, 3);

        $tokens[$assertCallIndex] = new Token([T_STRING, $isPositive ? 'assertInternalType' : 'assertNotInternalType']);
        $tokens[$testIndex] = new Token([T_CONSTANT_ENCAPSED_STRING, "'".$type."'"]);
        $tokens[$testOpenIndex] = new Token(',');

        $tokens->clearTokenAndMergeSurroundingWhitespace($testCloseIndex);

        if (!$tokens[$testOpenIndex + 1]->isWhitespace()) {
            $tokens->insertAt($testOpenIndex + 1, new Token([T_WHITESPACE, ' ']));
        }

        if (false !== $testDefaultNamespaceTokenIndex) {
            $tokens->clearTokenAndMergeSurroundingWhitespace($testDefaultNamespaceTokenIndex);
        }

        return $assertCallCloseIndex;
    }

    /**
     * @param Tokens    $tokens
     * @param false|int $callNSIndex
     * @param int       $callIndex
     * @param int       $openIndex
     * @param int       $closeIndex
     */
    private function removeFunctionCall(Tokens $tokens, $callNSIndex, $callIndex, $openIndex, $closeIndex)
    {
        $tokens->clearTokenAndMergeSurroundingWhitespace($callIndex);
        if (false !== $callNSIndex) {
            $tokens->clearTokenAndMergeSurroundingWhitespace($callNSIndex);
        }

        $tokens->clearTokenAndMergeSurroundingWhitespace($openIndex);
        $tokens->clearTokenAndMergeSurroundingWhitespace($closeIndex);
    }
}

redpajama_set_name: RedPajamaGithub


(Hollywood, CA--April 11, 2017) -- Light Iron – a leading post production solutions provider and member of the Panavision family of companies – has appointed Rick Anthony to the newly created role of General Manager in its New York facility. The addition comes after Light Iron added a second floor in 2016 to triple its inventory of editorial suites.
Light Iron's New York facility offers 20 premium editorial suites from its SoHo location, as well as in-house and mobile dailies services, HDR-ready episodic timing bays, and a 4K DI theater. The facility recently serviced Panavision's first US- production shot on the new Millennium DXL camera.
Light Iron, a Panavision company, specializes in mobile dailies, digital intermediate, archival, and data services for projects originated on file-based motion cameras. With facilities in Hollywood, New York City and New Orleans, Light Iron serves projects at both the independent and studio level. The company distinguishes itself by providing clients post production workflows that minimize time, maximize image fidelity, and increase creative control. Recent credits include features such as CHiPs, Youth in Oregon and Oscar-nominated Hell or High Water, commercial campaigns for Gap and Jaguar, and the television series The Walking Dead, Baskets, and Red Oaks. Follow the company on Facebook,Twitter, Instagram, Vimeo, or LinkedIn.


text:
Q: What does the software updater popup that says "OK" with a circled "X" mean when nothing changes? This is the message I get when I try to switch to nvidia-driver-510 but it doesn't change the driver when I click on "OK".  What does "OK" mean here?

UPDATE: I was able to escape this state by downloading the nvidia driver install script from the nvidia site, booting to root prompt to install it, rebooting and then executing the nvidia driver install script again with the '--uninstall' option set, and rebooting.

redpajama_set_name: RedPajamaStackExchange


The best applicator for applying a ceramic coating to your vehicle!
Ceramic coatings are the best choice for the longest lasting protection, but they can be frustrating to apply without the right tools for the job. Having the proper applicator sponge makes all the difference in the world, which is why we spent countless hours developing the McKee's 37 Coating Applicator. This specially designed, closed-cell applicator features a high-tech European foam that eliminates streaking and high spots, delivering a smooth application for your favorite ceramic coating. Are you thinking about applying a paint, wheel, or glass coating to your vehicle? Reduce the chance of mistakes by using the McKee's 37 Coating Applicator to apply your coating of choice!
Our Coating Applicator is easy to hold onto, even when your hands are sweaty from a long day of detailing! The soft, closed-cell European foam is attached to a coarse grey foam that won't accidentally slip out of your hand.
If you've read this far, chances are pretty good that you've been seriously considering applying a ceramic coating (hopefully ours!) to your vehicle. Don't take a chance using that old, tatty applicator pad that's been hanging out in the back of your tool chest for the last couple years. Equip yourself with the McKee's 37 Coating Applicator to guarantee smooth, effortless application of your ceramic coating!


text:
Editorial: Are the Clintons imitating art?
This year in politics has made it seem like we're all living in an alternative reality.
A reality TV star is the presumptive GOP presidential candidate, while the Clintons seem to be doing their best rendition of a fictional television couple.
In February of 2013, a new series premiered on Netflix that changed the way that political dramas are viewed. "House of Cards" became an instant hit and a major influence in pop culture. The web television series is set in present-day Washington and centers on the lives of a married couple, Frank and Claire Underwood.
Frank started out as the House majority whip and is a Southern Democrat from South Carolina. But after he was passed over for an appointment to become the new secretary of state, Frank and Claire come up with a shrewd, manipulative and ruthless plan to take down everyone who has ever wronged them and anything that's in their way. Through four seasons of the show, the Underwoods have gone from little-known politicians to being household names. The Underwoods now live in the White House as the president and first lady without a single vote being cast in their favor.
At the end of the most recent season, the duo decided to politically join at the hip as Frank is currently running for re-election, with his wife by his side as his running mate for vice president. The show is intriguing, complex, entertaining and purely fiction.
EDITORIAL: The parallels of Delaware's gubernatorial race
COLUMN: FBI's reputation crumbles with Clinton email fumble
Because if you've paid attention to the recent happenings and are a fan of the show, then you realize that some of the cunning tactics that the Underwoods love to use are eerily similar to some of Hillary and Bill Clinton's campaign strategies.
From the outside, Claire and Frank can seem cold; however, they're fiercely loyal to one another. Public displays of affection aren't their thing, but they are the true definition of a team. Frank and Claire sacrifice for one another and take turns at being the public face of their union.
Similarly, the former first lady stood at the side of her charismatic husband, another Southern Democrat, who became a governor, and then one of the country's most beloved presidents. So, when it was Hillary's turn to become a senator, then secretary of state, and now the Democratic presumptive nominee for president, it's Bill who is in the back seat.
Consequently, when Bill Clinton just happened to run into Attorney General Loretta Lynch on a tarmac, some wondered if it was planned or a coincidence. No matter the answer, it was something straight out of the Frank Underwood playbook.
And on Tuesday, when Bernie Sanders took the stage next to Hillary Clinton, it almost seemed like it was the complete opposite of what Sanders has preached for the last year.
"I have come here today not to talk about the past but to focus on the future," he said. "That future will be shaped more by what happens on Nov. 8 in voting booths across our nation than by any other event in the world. I have come here to make it as clear as possible as to why I am endorsing Hillary Clinton and why she must become our next president."
Maybe Sanders eventually "saw the light," and maybe Lynch and Clinton just happened to be in the same place at the same time; but all of this just makes you wonder if the Clintons are the new Underwoods, and if we're seeing art imitate life, or vice versa.


text:
Trusting your strengths is the way to stop batsmen, reveals speedster Naveen-ul-Haq
What is the best way to plug the flow of runs when batters just smash bowlers left, right and centre?
For Team Abu Dhabi speedster Naveen-ul-Haq, reverting to his strengths when put under testing conditions is the best way to apply the brakes on the scoring rate.
"I always work on my strengths irrespective of formats," Naveen-ul-Haq revealed.
And for Naveen, that strength comes from his variations, as seen in the ongoing Abu Dhabi T10 season.
"You must also be unpredictable as a bowler," he said.
A yorker, a bouncer, a slower one – the 22-year-old Afghan international does it all, that too with the perfection of a seasoned veteran.
Interestingly, four of Naveen's seven wickets this season have come through slower deliveries. He has picked a brace in two matches and one wicket each in three other games.
When the Kabul-born bowler did not take a wicket in the opening match of the season, he compensated it with an enviable economy, giving only seven runs in his quota of 12 balls.
"Every dot ball is gold in this format, and I try for that. I also try to save myself from big hits."
However, Naveen-ul-Haq, who has played franchise cricket across the world, is also aware of how quickly things can go south for bowlers in the T10 format.
"Both T10 and T20 are different formats. In T20s, a player gets time to change things to help his team recover in a match. In T10, even if one over goes wrong with the bat or bowl, the pressure increases," he explained.
But when things don't work out for the Afghan international, the team has his back. The philosophy of Team Abu Dhabi to play a fearless brand of cricket is what pushes players like Naveen-ul-Haq even when the cards are stacked against them.
"During the tournament, we may also have a game where everything might work against us. But we still have to continue playing with the same intensity. We have seen the capability of our team and we still have to keep self-belief that we can win the game," he said.
The belief has worked in Team Abu Dhabi's favour till now. The home side has won seven of their nine matches this season and are one of the favourites to lift the trophy for the first time.
Hitting sixes part of my role in T10 cricket, says Gladiators pacer Odean Smith
Matchday 12: Deccan Gladiators ride Cadmore storm against Bangla Tigers