
// search_full.cpp

// includes

#include "attack.h"
#include "board.h"
#include "colour.h"
#include "eval.h"
#include "list.h"
#include "move.h"
#include "move_check.h"
#include "move_do.h"
#include "option.h"
#include "piece.h"
#include "pst.h"
#include "pv.h"
#include "recog.h"
#include "search.h"
#include "search_full.h"
#include "see.h"
#include "sort.h"
#include "trans.h"
#include "util.h"
#include "value.h"

// kh 10.04.07 start Thomas Gaksch
#include "pawn.h"
#include "probe.h"

#define ABS(x) ((x)<0?-(x):(x))
#define MIN(X, Y)  ((X) < (Y) ? (X) : (Y))
#define R_adpt(max_pieces, depth, Reduction) (Reduction + ((depth) > (9 + ((max_pieces<3) ? 2 : 0))))

// kh 02.06.08 Thomas Gaksch 14b5c
//#define WIN_PLY            100

// kh 10.04.07 end Thomas Gaksch

#include "YBWCManager.h"
extern YBWCManager* g_pYBWCManagerInstance;

#include "Stack.h"

// constants and variables

// main search

static const bool UseDistancePruning = true;

// transposition table

static /* const */ bool UseTrans = true;

static const int TransDepth = 1;

// kh 02.06.08 Thomas Gaksch 14b5c
static const bool UseExact = true;

static const bool UseMateValues = true; // use mate values from shallower searches?

// null move

static /* const */ bool UseNull = true;
static /* const */ bool UseNullEval = true; // true

// kh 10.04.07 Thomas Gaksch
static const int NullDepth = 2; // was 2

static /* const */ int NullReduction = 3;

static /* const */ bool UseVer = true;
static /* const */ bool UseVerEndgame = true; // true
static /* const */ int VerReduction = 5; // was 3

// move ordering

static /* const */ bool UseIID = true;
static const int IIDDepth = 3;
static const int IIDReduction = 2;

// extensions

static const bool ExtendSingleReply = true; // true

// kh 02.06.08 Thomas Gaksch 14b5c
// razoring

static const int RazorDepth = 3;
static const int RazorMargin = 300;

// history pruning

//static /* const */ bool UseHistory = true;

/*
// kh 10.04.07 Thomas Gaksch
static /* const * / bool UseHistoryPruning = true;
static const int HistoryDepth = 3; // was 3

// kh 19.03.08
static const int HistoryMoveNb = 3; // was 3

static /* const * / int HistoryValue = 9830; // 60%
*/

// kh 02.06.08 Thomas Gaksch 14b5c
//static /* const */ int HistoryBound = 2458; // * 16384 + 50) / 100 10%=1638 15%=2458 20%=3277
static /* const */ int HistoryBound = 6400; // * 16384 + 50) / 100 10%=1638 15%=2458 20%=3277
static /* const */ bool UseExtendedHistory = true;

// kh 02.06.08 Thomas Gaksch 14b5c
//static /* const */ bool UseExtendedHistory = false;

static const bool HistoryReSearch = true;

// futility pruning

// kh 10.04.07 Thomas Gaksch
static /* const */ bool UseFutility = true; // false
static /* const */ int FutilityMargin = 100;
static /* const */ int FutilityMargin1 = 100;

// kh 02.06.08 Thomas Gaksch 14b5c
//static /* const */ int FutilityMargin2 = 200;
static /* const */ int FutilityMargin2 = 300;

// kh 02.06.08 Thomas Gaksch 14b5c
//static /* const */ int FutilityMargin3 = 300;
static /* const */ int FutilityMargin3 = 950;

// quiescence search

// kh 10.04.07 Thomas Gaksch
static /* const */ bool UseDelta = true; // false

static /* const */ int DeltaMargin = 50;

static /* const */ int CheckNb = 1;
static /* const */ int CheckDepth = 0; // 1 - CheckNb

// misc

// kh 07.09.06
/*
static const int NodeAll = -1;
static const int NodePV  =  0;
static const int NodeCut = +1;
*/

// macros

#define NODE_OPP(type)     (-(type))
#define DEPTH_MATCH(d1,d2) ((d1)>=(d2))

// prototypes

// kh 26.07.06
//static int  full_root            (list_t * list, board_t * board, int alpha, int beta, int depth, int height, int search_type);

// kh 24.07.06
//static int  full_search          (board_t * board, int alpha, int beta, int depth, int height, mv_t pv[], int node_type);
static int  fullSearch           (void);

// kh 26.07.06
//static int  full_no_null         (board_t * board, int alpha, int beta, int depth, int height, mv_t pv[], int node_type, int trans_move, int * best_move);

// kh 07.08.06
//static int  full_quiescence      (board_t * board, int alpha, int beta, int depth, int height, mv_t pv[], bool in_pv); // kh 10.04.07 Thomas Gaksch

// kh 03.06.08 Thomas Gaksch 14b5c
//static int  full_new_depth       (int depth, int move, board_t* board, bool single_reply, bool in_pv, int height, bool extended, bool* cap_extended);

static bool do_null              (const board_t * board);
static bool do_ver               (const board_t * board);

static void pv_fill              (const mv_t pv[], board_t * board);

// kh 19.03.08
//static bool move_is_dangerous    (int move, const board_t * board);

static bool capture_is_dangerous (int move, const board_t * board);

static bool simple_stalemate     (const board_t * board);

// kh 10.04.07 start Thomas Gaksch
static bool passed_pawn_move     (int move, const board_t * board);

static bool is_passed				(const board_t * board, int to);
// kh 10.04.07 end Thomas Gaksch

// functions

// search_full_init()

void search_full_init(list_t* list, board_t* board) 
{
  const char* string;
  int         trans_move;

// kh 02.06.08 start Thomas Gaksch 14b5c
  int         trans_depth;
  int         trans_flags;
  int         trans_value;
  entry_t*    found_entry;
// kh 02.06.08 end Thomas Gaksch 14b5c

  ASSERT(list_is_ok(list));
  ASSERT(board_is_ok(board));

  // null-move options

  string = option_get_string("NullMove Pruning");

  if(false) 
  {
  } 
  else if(my_string_equal(string, "Always")) 
  {
    UseNull = true;
    UseNullEval = false;
  } 
  else if(my_string_equal(string, "Fail High")) 
  {
    UseNull = true;
    UseNullEval = true;
  } 
  else if(my_string_equal(string, "Never")) 
  {
    UseNull = false;
    UseNullEval = false;
  } 
  else 
  {
    ASSERT(false);
    UseNull     = true;
    UseNullEval = true;
  }

  NullReduction = option_get_int("NullMove Reduction");

  string = option_get_string("Verification Search");

  if(false) 
  {
  } 
  else if (my_string_equal(string, "Always")) 
  {
    UseVer = true;
    UseVerEndgame = false;
  } 
  else if(my_string_equal(string, "Endgame")) 
  {
    UseVer = true;
    UseVerEndgame = true;
  } 
  else if(my_string_equal(string, "Never")) 
  {
    UseVer = false;
    UseVerEndgame = false;
  } 
  else
  {
    ASSERT(false);
    UseVer = true;
    UseVerEndgame = true;
  }

  VerReduction = option_get_int("Verification Reduction");

  // history-pruning options

  UseHistory    = option_get_bool("History Pruning");
  HistoryValue  = (option_get_int("History Threshold") * 16384 + 50) / 100;

  if(g_pYBWCManagerInstance->pFruitConfiguration->bForceReproducibleEvaluation)
  {
    UseHistory = false;
  }

// kh 10.04.07 Thomas Gaksch
   UseExtendedHistory = option_get_bool("Toga Extended History Pruning");
   HistoryBound       = (option_get_int("Toga History Threshold") * 16384 + 50) / 100;

  // futility-pruning options

  UseFutility     = option_get_bool("Futility Pruning");

// kh 10.04.07 Thomas Gaksch
  FutilityMargin1 = option_get_int("Futility Margin");
  FutilityMargin2 = option_get_int("Extended Futility Margin");

  // delta-pruning options

  UseDelta    = option_get_bool("Delta Pruning");
  DeltaMargin = option_get_int("Delta Margin");

  // quiescence-search options

  CheckNb     = option_get_int("Quiescence Check Plies");
  CheckDepth  = 1 - CheckNb;

  // standard sort

  list_note(list);
  list_sort(list);

  // basic sort

  trans_move = MoveNone;
  if(UseTrans) 
  {

// kh 02.06.08 Thomas Gaksch 14b5c
    trans_retrieve(Trans, &found_entry, board->key, &trans_move, &trans_depth, &trans_flags, &trans_value);
  }

  note_moves(list, board, 0, trans_move);
  list_sort(list);
}

// search_full_root()

int search_full_root(list_t* list, board_t* board, int depth, int search_type)
{
  int value;

  int nRootAlphaStart;
  int nRootBetaStart;

  int i;
  int j;
  int nHeight;

// kh 10.04.07 Thomas Gaksch
  int a;
  int b;

  UseHistoryPruning   = g_pYBWCManagerInstance->pFruitConfiguration->bUseHistoryPruning     != 0;
  UseIID              = g_pYBWCManagerInstance->pFruitConfiguration->bUseIID                != 0;
  UseTrans            = g_pYBWCManagerInstance->pFruitConfiguration->bUseTranspositionTable != 0;

  ASSERT(list_is_ok (list));
  ASSERT(board_is_ok(board));
  ASSERT(depth_is_ok(depth));
  ASSERT(search_type == SearchNormal || search_type == SearchShort);

  ASSERT(list == SearchRoot->list);
  ASSERT(!LIST_IS_EMPTY(list));
  ASSERT(board == SearchCurrent->board);
  ASSERT(board_is_legal(board));
  ASSERT(depth >= 1);

// kh 26.07.06
//value = full_root(list, board, -ValueInf, +ValueInf, depth, 0, search_type);

  ASSERT(g_Stack.nCount == 0);

  if(g_pYBWCManagerInstance->bSearchingSubproblem)
  {
    ASSERT(SearchNormal == SearchNormal);

    nRootAlphaStart = g_pYBWCManagerInstance->pWorkAvailableResult->nAlpha;
    nRootBetaStart  = g_pYBWCManagerInstance->pWorkAvailableResult->nBeta;

    SearchInfo->nHeightOffset = g_pYBWCManagerInstance->pWorkAvailableResult->nHeight;

// kh 14.02.07 install killer moves
    nHeight = 1; // kh 14.02.07 start with height 1, ignore the root (killer has no meaning for the only searched move)
    i       = 0;
    while(i < g_pYBWCManagerInstance->pWorkAvailableResult->nKillerListCount)
    {
      for(j = 0; j < KILLER_ENTRIES_PER_HEIGHT; j++)
      {
        Killer[nHeight][j] = g_pYBWCManagerInstance->pWorkAvailableResult->KillerList[i];
        i++;
      }

      nHeight++;

    } // while(i < g_pYBWCManagerInstance->pWorkAvailableResult->nKillerListCount)
  } // if(g_pYBWCManagerInstance->bSearchingSubproblem)
  else
  {

// kh 03.06.08 Thomas Gaksch 14b5c
// kh 20.04.07 this leads to problems for the range_is_ok(... assertions

// kh 18.06.08 support nMinimumBrothersFinishedRoot = 0, i.e. the second (third...) root move is e.g. searched before the first root move
//  a = SearchBest[SearchCurrent->multipv].value - 30;
// kh 18.06.08 use -ValueInf to avoid research on fail low at the moment (not fully handled for nMinimumBrothersFinishedRoot = 0)
    a = -ValueInf; 

	  b = SearchBest[SearchCurrent->multipv].value + 30;

// kh 03.06.08 Thomas Gaksch 14b5c
    if(SearchInput->multipv > 0)
    {
	    a = -ValueInf;
      b = +ValueInf;
    }

    if(    (g_pYBWCManagerInstance->nSize <= 1) 
        || (g_pYBWCManagerInstance->pFruitConfiguration->nMinimumBrothersFinishedRoot > 0))
    {

// kh 10.06.08 only used for full compatibility with the original sequential 14b5c version 
// but keep small windows otherwise for YBWC to better support also nMinimumBrothersFinishedRoot = 0

// kh 03.06.08 Thomas Gaksch 14b5c
      a = -ValueInf;
      b = +ValueInf;
    }

    nRootAlphaStart = a;
    nRootBetaStart  = b;

    SearchInfo->nHeightOffset = 0;
  } // !if(g_pYBWCManagerInstance->bSearchingSubproblem)

  SearchBestLast[SearchCurrent->multipv].depth = SearchBest[SearchCurrent->multipv].depth;
  SearchBestLast[SearchCurrent->multipv].flags = SearchBest[SearchCurrent->multipv].flags;
  SearchBestLast[SearchCurrent->multipv].move  = SearchBest[SearchCurrent->multipv].move;
  SearchBestLast[SearchCurrent->multipv].value = SearchBest[SearchCurrent->multipv].value;
  pv_copy(SearchBestLast[SearchCurrent->multipv].pv, SearchBest[SearchCurrent->multipv].pv); 

  g_pYBWCManagerInstance->bRestoreBestFromBestLast = FALSE;

  Stack_PushFullRoot(/* g_pYBWCManagerInstance->pStack, */
                     list,
                     board, 
                     nRootAlphaStart, 
                     nRootBetaStart, 
                     depth, 
                     0, 
                     search_type, 
                     RETURN_POSITION_FUNCTION_END);

// kh 26.07.06 fullSearch(... now contains full_root(..., full_search(... , full_no_null(...
// and full_quiescence(...
  value = fullSearch(); 

  ASSERT(g_Stack.nCount == 0);
  Stack_Clear(/* g_pYBWCManagerInstance->pStack */);

  ASSERT(value_is_ok(value));

// kh 12.04.07 use implication
  ASSERT(    (LIST_VALUE(list, 0) == value) 
          || (SearchBest[SearchCurrent->multipv].flags != SearchExact)
          || (SearchCurrent->multipv > 0));
//ASSERT(LIST_VALUE(list, 0) == value);

  return value;
}

// full_root()

// kh 26.07.06 full_root(... is now included in fullSearch(... (via switch statement)

// full_search()

// kh 21.07.06 
//static int full_search(board_t * board, int alpha, int beta, int depth, int height, mv_t pv[], int node_type) 

// kh 26.07.06 fullSearch now contains additionally full_root(..., full_no_null(... 
// and full_quiescence(... (separated via switch)
static int fullSearch(void)
{

// kh 21.07.06 local data is moved to appropriate LocalData of StackEntry
/*
  bool in_check;
  bool single_reply;
  int trans_move, trans_depth, trans_min_depth, trans_max_depth, trans_min_value, trans_max_value;
  int min_value, max_value;
  int old_alpha;
  int value, best_value;
  int move, best_move;
  int new_depth;
  int played_nb;
  int i;
  int opt_value;
  bool reduced;
  attack_t attack[1];
  sort_t sort[1];
  undo_t undo[1];
  mv_t new_pv[HeightMax];
  mv_t played[256];
*/

  int                       nStopResult;

  int                       nTmpResult;
  int                       nTmpReturnPosition;

  bool                      bTmpBreak;
  int                       nTmpIndex;

  int                       nTmpIndex2;
  bool                      bTmpFirst;

#if DEBUG
  char                      sTmpMoveString[256];
#endif

  bool                      bTmpSkipMove;
  bool                      bTmpInPV;
  bool                      bTmpInCheck;
  int                       nTmpNodeType;
  bool                      bTmpExtended;

// kh 17.06.08 $$$ temp only
//bool                      bTmpForcedFirst;

  bool                      bTmpTotalSkip;
  bool                      bTmpFailLowSkip;

//bool                      bTmpGoodCap;

//int                       nTmpPlayed;

  int                       nTmpUpdateSearchWindowResult;

/*
  int                       nTmpTransMove; 
  int                       nTmpTransDepth; 
  int                       nTmpTransMinValue;
  int                       nTmpTransMaxValue;
*/

  int                       nTmpBetaLimit;

  StackEntry*               pStackEntry;

  while(g_Stack.nCount > 0) 
  {

L_CALL_FULL_SEARCH:

// kh 16.03.76 should make stopping faster (in more defensive way)
    if(g_pYBWCManagerInstance->bStoppingActive)
    {
      search_check();
    }

// kh 01.08.06 first try of a "good place" to service the messages
    if(SearchInfo->check_nb_mpi_poll <= 0) 
    {
      if(SearchInfo->check_nb_mpi_poll < SearchInfo->check_nb_mpi_poll_min)
      {
        SearchInfo->check_nb_mpi_poll_min = SearchInfo->check_nb_mpi_poll;
        if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_INFO_PRIO_1)
        {
          YBWCManager_Printf(g_pYBWCManagerInstance, 
                             "SearchInfo->check_nb_mpi_poll_min = %d\n", 
                             SearchInfo->check_nb_mpi_poll_min);
        }
      }

      SearchInfo->check_nb_mpi_poll += SearchInfo->check_inc_mpi_poll;
//    search_check();
      YBWCManager_ServiceMessages(g_pYBWCManagerInstance);

// kh 07.12.06 should make stopping faster
      if(g_pYBWCManagerInstance->bStoppingActive)
      {
        search_check();
      }
    }

    pStackEntry = Stack_Peek(/* pStack */);

    switch(pStackEntry->nCallType)
    {
    case CALL_TYPE_UNDEFINED:
      ASSERT(false);
      break;

    case CALL_TYPE_FULL_ROOT:

#if DEBUG
      pStackEntry->nAlphaParameterOnEntry = pStackEntry->parameters.fullRootPar.alpha;
      pStackEntry->nBetaParameterOnEntry  = pStackEntry->parameters.fullRootPar.beta;
#endif

      ASSERT(list_is_ok   (pStackEntry->parameters.fullRootPar.list));
      ASSERT(board_is_ok  (pStackEntry->parameters.fullRootPar.board));

// kh 20.04.07 assertion does not hold any longer for toga
// (range_is_ok is temporarily disabled)
      ASSERT(range_is_ok  (pStackEntry->parameters.fullRootPar.alpha, pStackEntry->parameters.fullRootPar.beta));

      ASSERT(depth_is_ok  (pStackEntry->parameters.fullRootPar.depth));
      ASSERT(height_is_ok (pStackEntry->parameters.fullRootPar.height + SearchInfo->nHeightOffset));
      ASSERT(    pStackEntry->parameters.fullRootPar.search_type == SearchNormal 
              || pStackEntry->parameters.fullRootPar.search_type == SearchShort);

      ASSERT(pStackEntry->parameters.fullRootPar.list == SearchRoot->list);
      ASSERT(!LIST_IS_EMPTY(pStackEntry->parameters.fullRootPar.list));
      ASSERT(pStackEntry->parameters.fullRootPar.board == SearchCurrent->board);
      ASSERT(board_is_legal(pStackEntry->parameters.fullRootPar.board));
      ASSERT(pStackEntry->parameters.fullRootPar.depth >= 1);

// kh 23.04.07 this lines are potentially not reachable for the "next level", because there is only 
// one (special) root level
      ASSERT(pStackEntry->bIsAlive);

      // init

      SearchInfo->check_nb--;
      SearchInfo->check_nb_mpi_poll--;

      if(SearchCurrent->multipv == 0) // kh 10.04.07 Thomas Gaksch
      {
        for(pStackEntry->localData.fullRootDat.i = 0; pStackEntry->localData.fullRootDat.i < LIST_SIZE(pStackEntry->parameters.fullRootPar.list); pStackEntry->localData.fullRootDat.i++)
        {
          pStackEntry->parameters.fullRootPar.list->value[pStackEntry->localData.fullRootDat.i] = ValueNone;
        }
      }

      if(g_pYBWCManagerInstance->bSearchingSubproblem)
      {
        if(    (g_pYBWCManagerInstance->pWorkAvailableResult->nCallType == CALL_TYPE_FULL_SEARCH)
            || (!g_pYBWCManagerInstance->pWorkAvailableResult->bAlphaBoundIsEstimated))
        {
          pStackEntry->localData.fullRootDat.old_alpha                          = pStackEntry->parameters.fullRootPar.alpha;
          pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv] = pStackEntry->parameters.fullRootPar.alpha;
        }
        else
        {

// kh 17.06.08 support nMinimumBrothersFinishedRoot = 0 
          pStackEntry->localData.fullRootDat.old_alpha                          = pStackEntry->parameters.fullRootPar.alpha;
          pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv] = ValueNone;
        }
      }
      else
      {

// kh 14.12.06 count only the root node for the root master
        SearchCurrent->node_nb++;
        SearchCurrent->node_local_nb++;
        g_pYBWCManagerInstance->nTotalNodes++;

        pStackEntry->localData.fullRootDat.old_alpha                          = pStackEntry->parameters.fullRootPar.alpha;
        pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv] = ValueNone;
      }

      // move loop

      pStackEntry->localData.fullRootDat.opt_value = +ValueInf;

// kh 26.07.06 for loop is replaced by while loop (more defensive for the gotos)
//    for(pStackEntry->localData.fullRootDat.i = 0; pStackEntry->localData.fullRootDat.i < LIST_SIZE(pStackEntry->parameters.fullRootPar.list); pStackEntry->localData.fullRootDat.i++) 

      pStackEntry->bMoveListBreak           = false;
      pStackEntry->nMoveListIndex           = 0;

// kh 04.05.07 "net" move list index, not counting the filtered moves in multipv mode (if > 0)
// used only for testing the YBWC condition in Stack_HasSendWorkToSlave(...
      pStackEntry->nNetMoveListIndex        = 0; 

      pStackEntry->nMoveListTotalCount      = 0;

#if DEBUG
      pStackEntry->nMemoMoveListTotalCount  = -1;
#endif

      pStackEntry->bIsAlive                 = true; // kh 07.09.06 asynchronous cutoff by a slave result is signaled
      if(g_pYBWCManagerInstance->bSearchingSubproblem)
      {
        // kh 20.10.06 do not try to distribute any moves when searching for a subproblem at the root level
      } // if(g_pYBWCManagerInstance->bSearchingSubproblem)
      else
      {
        if(g_pYBWCManagerInstance->pFruitConfiguration->bSuppressDistributionOfRootMoves)
        {
        } // if(g_pYBWCManagerInstance->pFruitConfiguration->bSuppressDistributionOfRootMoves)
        else
        {

// kh 10.11.06 defensive, in case of SearchShort the MINIMUM_REMOTE_SEARCH_DEPTH will later not be reached anyway
// when a check is performed if any work can be sent to a slave
// (if ShortSearchDepth (initialized to 1 by fruit original) is set to value >= MINIMUM_REMOTE_SEARCH_DEPTH the
// test for "search type is normal" is really necessary)
          if(pStackEntry->parameters.fullRootPar.search_type == SearchNormal) 
          {
            pStackEntry->bTryToDistribute = true;
          }
        } // !if(g_pYBWCManagerInstance->pFruitConfiguration->bSuppressDistributionOfRootMoves)
      } // ! if(g_pYBWCManagerInstance->bSearchingSubproblem)

      pStackEntry->bMoveListFullyGenerated  = false; // kh 20.09.06 defensive

// kh 07.09.06 copy move list 
      for(nTmpIndex = 0; nTmpIndex < LIST_SIZE(pStackEntry->parameters.fullRootPar.list); nTmpIndex++)
      {
        ASSERT(nTmpIndex == pStackEntry->nMoveListTotalCount);

        StackEntry_AddMove(pStackEntry, LIST_MOVE(pStackEntry->parameters.fullRootPar.list, nTmpIndex));
      }

      pStackEntry->bMoveListFullyGenerated = true; // kh 11.09.06 defensive

#if DEBUG
      pStackEntry->nMemoMoveListTotalCount = pStackEntry->nMoveListTotalCount; // kh 18.03.07 for debug purposes only
#endif

      if(g_pYBWCManagerInstance->bSearchingSubproblem || (SearchCurrent->multipv > 0))
      {
        pStackEntry->localData.fullRootDat.bIterationConfirmed = true;
      }
      else
      {
        pStackEntry->localData.fullRootDat.bIterationConfirmed = false;
      }

      pStackEntry->localData.fullRootDat.i = 0; 
      pStackEntry->nMoveListIndex = pStackEntry->localData.fullRootDat.i; // kh 07.09.06 defensive

// kh 07.09.06 start of special root real main search loop 
//    while(pStackEntry->localData.fullRootDat.i < LIST_SIZE(pStackEntry->parameters.fullRootPar.list))
      while(pStackEntry->bIsAlive && (pStackEntry->localData.fullRootDat.i < LIST_SIZE(pStackEntry->parameters.fullRootPar.list)))
      {

// kh 06.07.06 the source code below could be refactored to use only 
// the new pStackEntry lists (pStackEntry->MoveList,
// pStackEntry->SlaveList, pStackEntry->WorkIdList, pStackEntry->CompletedList)
// but at the moment the data is redundantly managed (there are at least no performance problems expected)
        pStackEntry->localData.fullRootDat.move = LIST_MOVE(pStackEntry->parameters.fullRootPar.list, pStackEntry->localData.fullRootDat.i); 

        SearchRoot->depth      = pStackEntry->parameters.fullRootPar.depth;
        SearchRoot->move       = pStackEntry->localData.fullRootDat.move;
        SearchRoot->move_pos   = pStackEntry->localData.fullRootDat.i;
        SearchRoot->move_nb    = LIST_SIZE(pStackEntry->parameters.fullRootPar.list);

        bTmpSkipMove = false;

        if(g_pYBWCManagerInstance->bSearchingSubproblem)
        {
          ASSERT(SearchCurrent->multipv == 0);

          if(SearchRoot->move == g_pYBWCManagerInstance->pWorkAvailableResult->nMove)
          {
          }
          else
          {
            bTmpSkipMove                                            = true;
            pStackEntry->CompletedList[pStackEntry->nMoveListIndex] = true;
          }
        } // if(g_pYBWCManagerInstance->bSearchingSubproblem)
        else
        {

// kh 10.04.07 start Thomas Gaksch
	        if(SearchCurrent->multipv > 0)
          {
		        pStackEntry->localData.fullRootDat.found = false;
		        for(pStackEntry->localData.fullRootDat.j = 0; pStackEntry->localData.fullRootDat.j < SearchCurrent->multipv; pStackEntry->localData.fullRootDat.j++)
            {
			        if(SearchBest[pStackEntry->localData.fullRootDat.j].pv[0] == pStackEntry->localData.fullRootDat.move)
              {
				        pStackEntry->localData.fullRootDat.found = true;
				        break;
			        }
		        }

		        if(pStackEntry->localData.fullRootDat.found)
            {
//  		      continue;
              bTmpSkipMove                                            = true; // kh 10.04.07
              pStackEntry->CompletedList[pStackEntry->nMoveListIndex] = true; 
            }
	        }
// kh 10.04.07 end Thomas Gaksch

        } // !if(g_pYBWCManagerInstance->bSearchingSubproblem)

        if(bTmpSkipMove)
        {

          // kh 10.04.07 pseudo root move for sub problem skipped (no match)
          // or multipv move already searched skipped

        } // if(bTmpSkipMove)
        else
        {

          search_update_root();

          if(    (pStackEntry->SlaveList    [pStackEntry->nMoveListIndex] > 0) // kh 07.09.06 a slave is searching for this move
              ||  pStackEntry->CompletedList[pStackEntry->nMoveListIndex]      // kh 07.09.06 a slave has already completed the search for this move 
            )
          {

// kh 11.10.06 only one pseudo root move is analyzed at the relative root level of a subproblem
// so there can not be any distributed subproblems here
            ASSERT(!g_pYBWCManagerInstance->bSearchingSubproblem)

            // kh 07.09.06 skip

          } // if(    (pStackEntry->SlaveList    [pStackEntry->nMoveListIndex] > 0)...
          else
          {
            pStackEntry->CompletedList[pStackEntry->nMoveListIndex] = true; // kh 07.09.06 this move will now be searched locally

// kh 02.02.07 memo start count (negative, defensive)
            pStackEntry->NodesList[pStackEntry->nMoveListIndex]     = -SearchCurrent->node_nb;
            pStackEntry->TimeList[pStackEntry->nMoveListIndex]      = SearchCurrent->time;
            strcpy(pStackEntry->TimeStampList[pStackEntry->nMoveListIndex], 
                   YBWCManager_TimeStampShortAsString(g_pYBWCManagerInstance));

            pStackEntry->AlphaList [pStackEntry->nMoveListIndex] = pStackEntry->parameters.fullRootPar.alpha;
            pStackEntry->BetaList  [pStackEntry->nMoveListIndex] = pStackEntry->parameters.fullRootPar.beta;

            g_pYBWCManagerInstance->nSlaveNodesReceivedInBetween  = 0;

            if(g_pYBWCManagerInstance->bSearchingSubproblem)
            {
              if(g_pYBWCManagerInstance->pWorkAvailableResult->bInPV)
              { 
                bTmpInPV = true;
              }
              else
              {
                bTmpInPV = false;
              }

              if(g_pYBWCManagerInstance->pWorkAvailableResult->bExtended)
              { 
                bTmpExtended = true;
              }
              else
              {
                bTmpExtended = false;
              }

// kh 17.06.08 $$$ temp only
/*
              if(    g_pYBWCManagerInstance->pWorkAvailableResult->bAlphaBoundIsEstimated 
                  && g_pYBWCManagerInstance->pWorkAvailableResult->nCallType == CALL_TYPE_FULL_ROOT)
              {
                bTmpForcedFirst = true;
              }
              else
              {
                bTmpForcedFirst = false;
              }
*/

            } // if(g_pYBWCManagerInstance->bSearchingSubproblem)
            else
            {

// kh 12.10.06 original fruit assignment
              bTmpInPV     = true;

// kh 03.06.08 original toga assignment
              bTmpExtended = false;

// kh 17.06.08 $$$ temp only
//            bTmpForcedFirst = false;

            } // !if(g_pYBWCManagerInstance->bSearchingSubproblem)

            bTmpInCheck = board_is_check(pStackEntry->parameters.fullRootPar.board);

// kh 03.06.08 Thomas Gaksch 14b5c
            pStackEntry->localData.fullRootDat.new_depth = 
              full_new_depth(pStackEntry->parameters.fullRootPar.depth,
                             pStackEntry->localData.fullRootDat.move,
                             pStackEntry->parameters.fullRootPar.board,
                             bTmpInCheck && LIST_SIZE(pStackEntry->parameters.fullRootPar.list) == 1,
                             bTmpInPV, 
                             pStackEntry->parameters.fullRootPar.height,
                             bTmpExtended, 
                             &pStackEntry->localData.fullRootDat.cap_extended);

// kh 04.06.08 code below is not used (and not ported to 14b5c yet)
// kh 08.02.07 history pruning for sub problems (analogous to the full search call type) part a

// kh 19.03.08 disable real history pruning (goto cut_full_root) at the root 
// it seems not appropriate in respect to the overhead of starting a sub job and transmitting its result back
// to history prune at the root immediately.
// that case is now handled before the job is transmitted and the submission of such a job is suppressed
// (the boolean expression (pStackEntry->parameters.fullRootPar.depth <= SearchCurrent->max_extensions / 2) (see below)
// will never be true without additional handling (i.e. transmitting (pStackEntry->parameters.fullRootPar.depth <= SearchCurrent->max_extensions / 2))
// as a flag with the sub job info)
/*
            if(g_pYBWCManagerInstance->bSearchingSubproblem)
            {
//            pStackEntry->localData.fullRootDat.value = pStackEntry->SortValueList[pStackEntry->nMoveListIndex]; 
              pStackEntry->localData.fullRootDat.value = g_pYBWCManagerInstance->pWorkAvailableResult->nHistoryValue;

              if(    UseHistoryPruning && !bTmpInCheck /* && depth < HistoryDepth * / && pStackEntry->parameters.fullRootPar.depth <= SearchCurrent->max_extensions / 2 /* depth <= 4 * / 
			            && (!bTmpInPV /* || UseExtendedHistory * /) 
			            && g_pYBWCManagerInstance->pWorkAvailableResult->nPlayedNb >= HistoryMoveNb /* && height % 2 == 0 * /
			            && pStackEntry->localData.fullRootDat.new_depth < pStackEntry->parameters.fullRootPar.depth && pStackEntry->localData.fullRootDat.value < (pStackEntry->parameters.fullRootPar.depth <= 2 ? HistoryValue / 2 : HistoryValue / 3)

// kh 16.04.07 check !move_is_tactical(... first, because this is asserted in move_is_dangerous(..., defensive, assertion is disabled in  move_is_dangerous(... anyway
			            && !move_is_tactical(pStackEntry->localData.fullRootDat.move, pStackEntry->parameters.fullRootPar.board)  && !move_is_dangerous(pStackEntry->localData.fullRootDat.move, pStackEntry->parameters.fullRootPar.board)) 
//	              && !move_is_dangerous(pStackEntry->localData.fullRootDat.move, pStackEntry->parameters.fullRootPar.board) && !move_is_tactical(pStackEntry->localData.fullRootDat.move, pStackEntry->parameters.fullRootPar.board))
              { 

// kh 16.04.07
                ASSERT(g_pYBWCManagerInstance->pWorkAvailableResult->nCallType == CALL_TYPE_FULL_SEARCH);


// kh 17.04.07 real cutoffs are now supported for the root
/*
// kh 12.04.07 pStackEntry->localData.fullRootDat.i++ is necessary now, so continue must not be used any more
//              continue;
                goto L_FULL_ROOT_END_WHILE;
* /

// kh 17.04.07 future expansion: the master needs a result for that move
// if this seems to be too dangerous, this kind of history pruning here could be disabled or 
// that special state could be transmitted to the master and handled in an appropriate way there
                SearchBest[SearchCurrent->multipv].move           = pStackEntry->localData.fullRootDat.move;

// kh 17.04.07 prepare a "logically skip" of this move for the master by a "bad" value (lower than alpha)
/*
                SearchBest[SearchCurrent->multipv].value          = pStackEntry->localData.fullRootDat.value;
                pStackEntry->parameters.fullRootPar.list->value[pStackEntry->localData.fullRootDat.i]        = pStackEntry->localData.fullRootDat.value;
                pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv]  = pStackEntry->localData.fullRootDat.value;
* /

// kh 24.04.07 nAlpha - 2 seems to be more defensive than nAlpha - 1
                SearchBest[SearchCurrent->multipv].value          = g_pYBWCManagerInstance->pWorkAvailableResult->nAlpha - 2;
                pStackEntry->parameters.fullRootPar.list->value[pStackEntry->localData.fullRootDat.i]        = g_pYBWCManagerInstance->pWorkAvailableResult->nAlpha - 2;
                pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv]  = g_pYBWCManagerInstance->pWorkAvailableResult->nAlpha - 2;

                goto cut_full_root;

              } // if(    UseHistoryPruning && !bTmpInCheck /* && depth < HistoryDepth * / && pStackEntry->parameters.fullRootPar.depth <= SearchCurrent->max_extensions / 2 /* depth <= 4 * / ...
            } // if(g_pYBWCManagerInstance->bSearchingSubproblem)
*/

// kh 19.03.08 disable futility pruning at the root for sub problems
// the minimum remote search depth (i.e. the search depth of a sub problem here) is usually at least 4 plies,
// so there will be actually no futility pruning (search depth <= 3)
// but if an additional "outer" IID is configured for sub problems, there may be a futility pruning for the first 
// 3 iterations. A potential problem of such a futility pruning is that there may be no estimation of the
// completion of the job via the moves marked completed divided by the maximum move list count
// ever reached on level 1 to to suppress window update messages. (not necessarily the number of legal moves in level 1, 
// (see also comment from 14.03.07 for nMaximumPercentCompletedForRerunSearch in FruitConfiguration.h)
// (if the minimum remote search depth is >= 5 that special problem can not arise, because when iteration 
// depth 4 is reached an appropriate estimation of the move list count on level 1 will be performed. but it seems 
// not necessary to handle that case)
//
// if a remote search depth of <= 3 is configured, it seems to make no sense anyway to "terminate" such a sub job 
// potentially early by futility pruning here in respect to the overhead of starting a job and transmitting its 
// result back. if a remote search depth <= 3 is of more interest (in the future) the futility pruning should be
// checked and handled before transmitting the job (analogous to the "early history pruning check" for such cases)
/*
// kh 12.04.07 futility pruning for sub problems (analogous to the full search call type)

            // futility pruning

            if(g_pYBWCManagerInstance->bSearchingSubproblem)
            {

// kh 11.04.07 Thomas Gaksch
              if(UseFutility && pStackEntry->parameters.fullRootPar.depth <= 3 && !bTmpInPV) 
              {

// kh 16.04.07
                ASSERT(g_pYBWCManagerInstance->pWorkAvailableResult->nCallType == CALL_TYPE_FULL_SEARCH);

                if(    !bTmpInCheck

// kh 11.04.07 Thomas Gaksch
                    && pStackEntry->localData.fullRootDat.new_depth < pStackEntry->parameters.fullRootPar.depth 
//                  && pStackEntry->localData.fullRootDat.new_depth == 0 

                    && !move_is_tactical (pStackEntry->localData.fullRootDat.move, pStackEntry->parameters.fullRootPar.board) 
                    && !move_is_dangerous(pStackEntry->localData.fullRootDat.move, pStackEntry->parameters.fullRootPar.board)) 

                {
                  ASSERT(!move_is_check(pStackEntry->localData.fullRootDat.move, pStackEntry->parameters.fullRootPar.board));

                  // optimistic evaluation

                  if(pStackEntry->localData.fullRootDat.opt_value == +ValueInf) 
                  {

// kh 11.04.07 start Thomas Gaksch
					          if(pStackEntry->parameters.fullRootPar.depth == 1)
                    {
						          FutilityMargin = FutilityMargin1;
                    }
					          else if(pStackEntry->parameters.fullRootPar.depth == 2)
                    {
						          FutilityMargin = FutilityMargin2;
                    }
					          else
                    {
						          FutilityMargin = FutilityMargin3;
                    }
  					
                    pStackEntry->localData.fullRootDat.opt_value = eval(pStackEntry->parameters.fullRootPar.board, 
                                                                        pStackEntry->parameters.fullRootPar.alpha, 
                                                                        pStackEntry->parameters.fullRootPar.beta, 
                                                                        bTmpInPV /* pStackEntry->parameters.fullSearchPar.node_type == NodePV * /) + FutilityMargin;
// kh 11.04.07 end Thomas Gaksch

                    ASSERT(pStackEntry->localData.fullRootDat.opt_value < +ValueInf);
                  }

                  pStackEntry->localData.fullRootDat.value = pStackEntry->localData.fullRootDat.opt_value;

                  // pruning

                  if(pStackEntry->localData.fullRootDat.value <= pStackEntry->parameters.fullRootPar.alpha) 
                  {
                    if(pStackEntry->localData.fullRootDat.value > pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv])
                    {
                      pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv] = pStackEntry->localData.fullRootDat.value;

                      PV_CLEAR(pStackEntry->localData.fullRootDat.new_pv);
//                    PV_CLEAR(pStackEntry->parameters.fullRootPar.ppv);
                    }

// kh 17.04.07 real cutoffs are now supported for the root
/*
// kh 12.04.07 pStackEntry->localData.fullRootDat.i++ is necessary now, so continue must not be used any more
//                  continue;
                    goto L_FULL_ROOT_END_WHILE;
* /

// kh 17.04.07 the master needs a result for that move
                    SearchBest[SearchCurrent->multipv].move           = pStackEntry->localData.fullRootDat.move;

                    SearchBest[SearchCurrent->multipv].value          = pStackEntry->localData.fullRootDat.value;
                    pStackEntry->parameters.fullRootPar.list->value[pStackEntry->localData.fullRootDat.i]        = pStackEntry->localData.fullRootDat.value;
                    pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv]  = pStackEntry->localData.fullRootDat.value;

                    goto cut_full_root;

                  } // if(pStackEntry->localData.fullRootDat.value <= pStackEntry->parameters.fullRootPar.alpha) 
                } // if(    !bTmpInCheck ...
              } // if(UseFutility && pStackEntry->parameters.fullRootPar.depth <= 3 && !bTmpInPV) 
            } // if(g_pYBWCManagerInstance->bSearchingSubproblem)
*/

// kh 08.02.07 history pruning for sub problems (analogous to the full search call type) part b

// kh 03.06.08 Thomas Gaksch 14b5c
            pStackEntry->localData.fullRootDat.reduced = false;

            if(g_pYBWCManagerInstance->bSearchingSubproblem)
            {
              if(g_pYBWCManagerInstance->pWorkAvailableResult->nCallType == CALL_TYPE_FULL_SEARCH)
              {

// kh 04.06.08 start Thomas Gaksch 14b5c
                if(UseHistory)
                {

// kh 30.05.08 for a test only
/*
                  if(pStackEntry->bHasAnySubWork)
                  {
                    nTmpPlayed = g_pYBWCManagerInstance->pWorkAvailableResult->nPlayedNb + 1;
                  }
                  else
                  {
                    nTmpPlayed = g_pYBWCManagerInstance->pWorkAvailableResult->nPlayedNb;
                  }
*/

                  if(    !bTmpInCheck
                      && pStackEntry->localData.fullRootDat.new_depth            < pStackEntry->parameters.fullRootPar.depth
                      && g_pYBWCManagerInstance->pWorkAvailableResult->nPlayedNb >= HistoryMoveNb 
//                    && nTmpPlayed                                              >= HistoryMoveNb 
				              && pStackEntry->parameters.fullRootPar.depth               >= HistoryDepth 
                      && !move_is_dangerous(pStackEntry->localData.fullRootDat.move, pStackEntry->parameters.fullRootPar.board)
                    )
                  {
					          if(    g_pYBWCManagerInstance->pWorkAvailableResult->bGoodCap 
                        && !move_is_tactical(pStackEntry->localData.fullRootDat.move, pStackEntry->parameters.fullRootPar.board))
                    {
						          g_pYBWCManagerInstance->pWorkAvailableResult->bGoodCap = false;
					          }

					          if(!g_pYBWCManagerInstance->pWorkAvailableResult->bGoodCap)
                    {
						          if(!bTmpInPV)
                      {
							          pStackEntry->localData.fullRootDat.new_depth--;
							          pStackEntry->localData.fullRootDat.reduced = true;
						          } // if(!bTmpInPV)
						          else
                      {
							          if(g_pYBWCManagerInstance->pWorkAvailableResult->nPlayedNb >= HistoryMoveNb + 3)
                        {
							            pStackEntry->localData.fullRootDat.new_depth--;
							            pStackEntry->localData.fullRootDat.reduced = true;
							          }
						          } // !if(!bTmpInPV)
			              } // if(!g_pYBWCManagerInstance->pWorkAvailableResult->bGoodCap)
                  } // if(    !bTmpInCheck...
                } // if(    UseHistory...
              } // if(g_pYBWCManagerInstance->pWorkAvailableResult->nCallType == CALL_TYPE_FULL_SEARCH)
              else
              {
                ASSERT(g_pYBWCManagerInstance->pWorkAvailableResult->nCallType == CALL_TYPE_FULL_ROOT);
              } //!if(g_pYBWCManagerInstance->pWorkAvailableResult->nCallType == CALL_TYPE_FULL_SEARCH)
            } // if(g_pYBWCManagerInstance->bSearchingSubproblem)

            move_do(pStackEntry->parameters.fullRootPar.board, pStackEntry->localData.fullRootDat.move, pStackEntry->localData.fullRootDat.undo);

            if(    (pStackEntry->parameters.fullRootPar.search_type == SearchShort) 

// kh 10.04.07 Thomas Gaksch
                || (pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv] == ValueNone)  // first move
                || !bTmpInPV

// kh 18.06.08 support nMinimumBrothersFinishedRoot = 0, i.e. the second (third...) root move is e.g. searched before the first root move
// kh 17.06.08 not really used
//              || bTmpForcedFirst
// kh 18.06.08 not really useful
//              || !pStackEntry->localData.fullRootDat.bIterationConfirmed 
              )
            {

// kh 27.03.07
              if(bTmpInPV)
              {
                nTmpNodeType = NodePV;
              }
              else
              {
                nTmpNodeType = NodeCut;
              }

// kh 24.07.06
//            value = -full_search(board, -beta, -alpha, new_depth, height + 1, new_pv, NodePV);
              ASSERT(g_Stack.nCount > 0);
              Stack_PushFullSearch(/* pStack, */
                                   pStackEntry->parameters.fullRootPar.board, 
                                   -pStackEntry->parameters.fullRootPar.beta, 
                                   -pStackEntry->parameters.fullRootPar.alpha, 
                                   pStackEntry->localData.fullRootDat.new_depth, 
                                   pStackEntry->parameters.fullRootPar.height + 1, 
                                   pStackEntry->localData.fullRootDat.new_pv, 
                                   nTmpNodeType, 
                                   pStackEntry->localData.fullRootDat.cap_extended, // kh 03.06.08 Thomas Gaksch 14b5c
                                   RETURN_POSITION_FULL_ROOT_01);
              goto L_CALL_FULL_SEARCH;

// kh 26.07.06
L_RETURN_POSITION_FULL_ROOT_01:

// kh 23.04.07 assertion does not hold any longer for toga, because cutoffs at the root level are possible
//            ASSERT(pStackEntry->bIsAlive); // kh 09.02.07

// kh 23.04.07 
              if(!pStackEntry->bIsAlive)
              {

// kh 23.04.07 an asynchronous cutoff at the root level is potentially expected only for the root master,
// because only the root master may potentially have sub jobs at the root level
                ASSERT(g_pYBWCManagerInstance->bRootMaster); 

// kh 23.04.07 !pStackEntry->bIsAlive at the root level implicates an asynchronous cutoff at the root level 
                ASSERT(pStackEntry->bSlaveCutoffLevel); 
                goto L_FULL_ROOT_NO_LONGER_ALIVE_UNWIND_MOVE;
              }

              pStackEntry->localData.fullRootDat.value = -pStackEntry->nResult;

              pStackEntry->EvalList[pStackEntry->nMoveListIndex] = pStackEntry->localData.fullRootDat.value;

// kh 22.05.08 if at least the first root move has been completely searched, alpha is also still not "estimated" for CALL_TYPE_FULL_ROOT
// (see - 30 .. + 30 window setting in search_full_root(...

// kh 24.05.08 this code will not be reached for CALL_TYPE_FULL_ROOT as long as nMinimumBrothersFinishedRoot >= 1 
// see also if(    (pStackEntry->parameters.fullRootPar.search_type == SearchShort)... above,
// (best value is still set and !bTmpInPV will not be true)

// kh 17.06.08 assertion does not hold any longer
//            ASSERT(!g_pYBWCManagerInstance->bSearchingSubproblem || g_pYBWCManagerInstance->pWorkAvailableResult->nCallType != CALL_TYPE_FULL_ROOT);

              if(g_pYBWCManagerInstance->bSearchingSubproblem)
              {
                if(g_pYBWCManagerInstance->pWorkAvailableResult->nCallType == CALL_TYPE_FULL_SEARCH)
                {
                  bTmpTotalSkip = true;
                }
                else
                {
                  bTmpTotalSkip = false;
                }
              }
              else
              {
                bTmpTotalSkip = false;
              }

              if(bTmpTotalSkip)
              {

                // kh 12.04.07 standard full_search(... behavior, no research for non root (implicates master) subproblems 

              } // if(bTmpTotalSkip)
              else
              {
                if(g_pYBWCManagerInstance->bSearchingSubproblem)
                {
                  if(    g_pYBWCManagerInstance->pWorkAvailableResult->bAlphaBoundIsEstimated 
                      && g_pYBWCManagerInstance->pWorkAvailableResult->nCallType == CALL_TYPE_FULL_ROOT)
                  {
/*
                    if(g_pYBWCManagerInstance->pWorkAvailableResult->nMoveListIndex == 0)
                    {
*/
                      bTmpFailLowSkip = false;
/*
                    }
                    else
                    {
                      bTmpFailLowSkip = true;
                    }
*/
                  }
                  else
                  {
                    bTmpFailLowSkip = true;
                  }
                } // if(g_pYBWCManagerInstance->bSearchingSubproblem)
                else
                {
                  if(SearchCurrent->multipv > 0)
                  {
                    bTmpFailLowSkip = false;
                  }
                  else
                  {
/*
                    if(pStackEntry->localData.fullRootDat.move == LIST_MOVE(pStackEntry->parameters.fullRootPar.list, 0))
                    {
*/
                      bTmpFailLowSkip = false;
/*
                    }
                    else
                    {
                      bTmpFailLowSkip = true;
                    }
*/
                  }
                } // !if(g_pYBWCManagerInstance->bSearchingSubproblem)

// kh 10.04.07 start Thomas Gaksch
			          if(    (pStackEntry->localData.fullRootDat.value <= pStackEntry->parameters.fullRootPar.alpha) // research
                    && !bTmpFailLowSkip)
                {
				          pStackEntry->localData.fullRootDat.old_alpha = pStackEntry->parameters.fullRootPar.alpha = -ValueInf;
				          SearchRoot->change  = true;
				          SearchRoot->easy    = false;
				          SearchRoot->flag    = false;

				          search_update_root();

// kh 11.04.07
//		            value = -full_search(board, -beta, ValueInf, new_depth, height + 1, new_pv, NodePV);
                  ASSERT(g_Stack.nCount > 0);
                  Stack_PushFullSearch(/* pStack, */
                                       pStackEntry->parameters.fullRootPar.board, 
                                       -pStackEntry->parameters.fullRootPar.beta, 
                                       ValueInf,  
                                       pStackEntry->localData.fullRootDat.new_depth, 
                                       pStackEntry->parameters.fullRootPar.height + 1, 
                                       pStackEntry->localData.fullRootDat.new_pv, 
                                       nTmpNodeType, 
                                       pStackEntry->localData.fullRootDat.cap_extended, // kh 03.06.08 Thomas Gaksch 14b5c
                                       RETURN_POSITION_FULL_ROOT_01_1);
                  goto L_CALL_FULL_SEARCH;

// kh 11.04.07
L_RETURN_POSITION_FULL_ROOT_01_1:

// kh 23.04.07 assertion does not hold any longer for toga, because cutoffs at the root level are possible
//                ASSERT(pStackEntry->bIsAlive); // kh 11.04.07

// kh 23.04.07 
                  if(!pStackEntry->bIsAlive)
                  {

// kh 23.04.07 an asynchronous cutoff at the root level is potentially expected only for the root master,
// because only the root master may potentially have sub jobs at the root level
                    ASSERT(g_pYBWCManagerInstance->bRootMaster); 

// kh 23.04.07 !pStackEntry->bIsAlive at the root level implicates an asynchronous cutoff at the root level 
                    ASSERT(pStackEntry->bSlaveCutoffLevel); 
                    goto L_FULL_ROOT_NO_LONGER_ALIVE_UNWIND_MOVE;
                  }

                  pStackEntry->localData.fullRootDat.value = -pStackEntry->nResult;
                  pStackEntry->EvalList[pStackEntry->nMoveListIndex] = pStackEntry->localData.fullRootDat.value;

// kh 17.06.08 $$$ temp only
//                pStackEntry->bAlphaBoundIsEstimated = false;
			          }
  		          else if(pStackEntry->localData.fullRootDat.value >= pStackEntry->parameters.fullRootPar.beta) // research
                {

// kh 17.06.08 $$$ temp only
//                pStackEntry->bAlphaBoundIsEstimated = false;

			            SearchRoot->change  = true;
                  SearchRoot->easy    = false;
                  SearchRoot->flag    = false;

                  search_update_root();

// kh 11.04.07
//  	            value = -full_search(board, -ValueInf, -alpha, new_depth, height + 1, new_pv, NodePV);
                  ASSERT(g_Stack.nCount > 0);
                  Stack_PushFullSearch(/* pStack, */
                                       pStackEntry->parameters.fullRootPar.board, 
                                       -ValueInf, 
                                       -pStackEntry->parameters.fullRootPar.alpha,  
                                       pStackEntry->localData.fullRootDat.new_depth, 
                                       pStackEntry->parameters.fullRootPar.height + 1, 
                                       pStackEntry->localData.fullRootDat.new_pv, 
                                       nTmpNodeType, 
                                       pStackEntry->localData.fullRootDat.cap_extended, // kh 03.06.08 Thomas Gaksch 14b5c
                                       RETURN_POSITION_FULL_ROOT_01_2);
                  goto L_CALL_FULL_SEARCH;

// kh 11.04.07
L_RETURN_POSITION_FULL_ROOT_01_2:

// kh 23.04.07 assertion does not hold any longer for toga, because cutoffs at the root level are possible
//                ASSERT(pStackEntry->bIsAlive); // kh 11.04.07

// kh 23.04.07 
                  if(!pStackEntry->bIsAlive)
                  {

// kh 23.04.07 an asynchronous cutoff at the root level is potentially expected only for the root master,
// because only the root master may potentially have sub jobs at the root level
                    ASSERT(g_pYBWCManagerInstance->bRootMaster); 

// kh 23.04.07 !pStackEntry->bIsAlive at the root level implicates an asynchronous cutoff at the root level 
                    ASSERT(pStackEntry->bSlaveCutoffLevel); 
                    goto L_FULL_ROOT_NO_LONGER_ALIVE_UNWIND_MOVE;
                  }

                  pStackEntry->localData.fullRootDat.value = -pStackEntry->nResult;
                  pStackEntry->EvalList[pStackEntry->nMoveListIndex] = pStackEntry->localData.fullRootDat.value;
		            }
// kh 10.04.07 end Thomas Gaksch

              } // !if(bTmpTotalSkip)
            } // if(pStackEntry->parameters.fullRootPar.search_type == SearchShort || pStackEntry->localData.fullRootDat.best_value == ValueNone)
            else 
            { // other moves

// kh 24.07.06
//            value = -full_search(board, -alpha - 1, -alpha, new_depth, height + 1, new_pv, NodeCut);
              ASSERT(g_Stack.nCount > 0);
              Stack_PushFullSearch(/* pStack, */
                                   pStackEntry->parameters.fullRootPar.board, 
                                   -pStackEntry->parameters.fullRootPar.alpha - 1, 
                                   -pStackEntry->parameters.fullRootPar.alpha, 
                                   pStackEntry->localData.fullRootDat.new_depth, 
                                   pStackEntry->parameters.fullRootPar.height + 1, 
                                   pStackEntry->localData.fullRootDat.new_pv, 
                                   NodeCut,
                                   pStackEntry->localData.fullRootDat.cap_extended, // kh 03.06.08 Thomas Gaksch 14b5c
                                   RETURN_POSITION_FULL_ROOT_02);
              goto L_CALL_FULL_SEARCH;

// kh 26.07.06
L_RETURN_POSITION_FULL_ROOT_02:

// kh 23.04.07 assertion does not hold any longer for toga, because cutoffs at the root level are possible
//            ASSERT(pStackEntry->bIsAlive); // kh 09.02.07

// kh 23.04.07 
              if(!pStackEntry->bIsAlive)
              {

// kh 23.04.07 an asynchronous cutoff at the root level is potentially expected only for the root master,
// because only the root master may potentially have sub jobs at the root level
                ASSERT(g_pYBWCManagerInstance->bRootMaster); 

// kh 23.04.07 !pStackEntry->bIsAlive at the root level implicates an asynchronous cutoff at the root level 
                ASSERT(pStackEntry->bSlaveCutoffLevel); 
                goto L_FULL_ROOT_NO_LONGER_ALIVE_UNWIND_MOVE;
              }

              pStackEntry->localData.fullRootDat.value = -pStackEntry->nResult;
              pStackEntry->EvalList[pStackEntry->nMoveListIndex] = pStackEntry->localData.fullRootDat.value;

              if(pStackEntry->localData.fullRootDat.value > pStackEntry->parameters.fullRootPar.alpha) // && value < beta
              {
                SearchRoot->change = true;
                SearchRoot->easy   = false;
                SearchRoot->flag   = false;

                search_update_root();

// kh 09.02.07 forced NodePV seems to be appropriate (see CALL_TYPE_FULL_SEARCH)
/*
                if(    (g_pYBWCManagerInstance->pWorkAvailableResult->nCallType == CALL_TYPE_FULL_ROOT)
                    || (g_pYBWCManagerInstance->pWorkAvailableResult->bInPV))
                {
                  nTmpNodeType = NodePV;
                }
                else
                {
                  nTmpNodeType = NodeAll;
                }
*/

                if(g_pYBWCManagerInstance->bSearchingSubproblem && (g_pYBWCManagerInstance->pWorkAvailableResult->nCallType == CALL_TYPE_FULL_SEARCH))
                {

// kh 12.04.07 standard full_search(... fruit/toga behavior for non root (implicates master) subproblems
                  nTmpBetaLimit = -pStackEntry->parameters.fullRootPar.beta;

                } // if(g_pYBWCManagerInstance->bSearchingSubproblem && (g_pYBWCManagerInstance->pWorkAvailableResult->nCallType == CALL_TYPE_FULL_SEARCH))
                else
                {

// kh 03.06.08 Thomas Gaksch 14b5c
//                nTmpBetaLimit = -pStackEntry->parameters.fullRootPar.beta - 50; // kh 12.04.07 for a standard toga root move 
                  nTmpBetaLimit = -ValueInf;

                } // !if(g_pYBWCManagerInstance->bSearchingSubproblem && (g_pYBWCManagerInstance->pWorkAvailableResult->nCallType == CALL_TYPE_FULL_SEARCH))

// kh 24.07.06
//              value = -full_search(board, -beta, -alpha, new_depth, height + 1, new_pv, NodePV);
                ASSERT(g_Stack.nCount > 0);
                Stack_PushFullSearch(/* pStack, */
                                     pStackEntry->parameters.fullRootPar.board,
                                     nTmpBetaLimit, // kh 12.04.07 -pStackEntry->parameters.fullRootPar.beta or -pStackEntry->parameters.fullRootPar.beta - 50, // kh 11.04.07 Thomas Gaksch
                                     -pStackEntry->parameters.fullRootPar.alpha,
                                     pStackEntry->localData.fullRootDat.new_depth,
                                     pStackEntry->parameters.fullRootPar.height + 1,
                                     pStackEntry->localData.fullRootDat.new_pv,

// kh 09.02.07 the node type is not needed more specific (see above)
//                                   nTmpNodeType,
                                     NodePV,
                                     pStackEntry->localData.fullRootDat.cap_extended, // kh 03.06.08 Thomas Gaksch 14b5c
                                     RETURN_POSITION_FULL_ROOT_03);
                goto L_CALL_FULL_SEARCH;

// kh 26.07.06
L_RETURN_POSITION_FULL_ROOT_03:

// kh 23.04.07 assertion does not hold any longer for toga, because cutoffs at the root level are possible
//              ASSERT(pStackEntry->bIsAlive); // kh 09.02.07

// kh 23.04.07 
                if(!pStackEntry->bIsAlive)
                {

// kh 23.04.07 an asynchronous cutoff at the root level is potentially expected only for the root master,
// because only the root master may potentially have sub jobs at the root level
                  ASSERT(g_pYBWCManagerInstance->bRootMaster); 

// kh 23.04.07 !pStackEntry->bIsAlive at the root level implicates an asynchronous cutoff at the root level 
                  ASSERT(pStackEntry->bSlaveCutoffLevel); 
                  goto L_FULL_ROOT_NO_LONGER_ALIVE_UNWIND_MOVE;
                }

                pStackEntry->localData.fullRootDat.value = -pStackEntry->nResult;

                pStackEntry->EvalList[pStackEntry->nMoveListIndex] = pStackEntry->localData.fullRootDat.value;

// kh 03.06.08 Thomas Gaksch 14b5c
/*
                if(g_pYBWCManagerInstance->bSearchingSubproblem && (g_pYBWCManagerInstance->pWorkAvailableResult->nCallType == CALL_TYPE_FULL_SEARCH))
                {

                  // kh 12.04.07 standard full_search(... behavior, no research for non root (implicates master) subproblems

                } // if(g_pYBWCManagerInstance->bSearchingSubproblem && (g_pYBWCManagerInstance->pWorkAvailableResult->nCallType == CALL_TYPE_FULL_SEARCH))
                else
                {

// kh 11.04.07 start Thomas Gaksch
				          if(pStackEntry->localData.fullRootDat.value >= pStackEntry->parameters.fullRootPar.beta) // research
                  {

// kh 24.07.06
//			            value = -full_search(board, -ValueInf, -alpha, new_depth, height + 1, new_pv, NodePV);
                    ASSERT(g_Stack.nCount > 0);
                    Stack_PushFullSearch(/* pStack, * /
                                         pStackEntry->parameters.fullRootPar.board, 
                                         -ValueInf, 
                                         -pStackEntry->parameters.fullRootPar.alpha,  
                                         pStackEntry->localData.fullRootDat.new_depth, 
                                         pStackEntry->parameters.fullRootPar.height + 1, 
                                         pStackEntry->localData.fullRootDat.new_pv, 
                                         NodePV,
                                         pStackEntry->localData.fullRootDat.cap_extended, // kh 04.06.08 Thomas Gaksch 14b5c
                                         RETURN_POSITION_FULL_ROOT_03_1);
                    goto L_CALL_FULL_SEARCH;

// kh 11.04.07
L_RETURN_POSITION_FULL_ROOT_03_1:

// kh 23.04.07 assertion does not hold any longer for toga, because cutoffs at the root level are possible
//                  ASSERT(pStackEntry->bIsAlive); // kh 11.04.07

// kh 23.04.07 
                    if(!pStackEntry->bIsAlive)
                    {

// kh 23.04.07 an asynchronous cutoff at the root level is potentially expected only for the root master,
// because only the root master may potentially have sub jobs at the root level
                      ASSERT(g_pYBWCManagerInstance->bRootMaster); 

// kh 23.04.07 !pStackEntry->bIsAlive at the root level implicates an asynchronous cutoff at the root level 
                      ASSERT(pStackEntry->bSlaveCutoffLevel); 
                      goto L_FULL_ROOT_NO_LONGER_ALIVE_UNWIND_MOVE;
                    }

                    pStackEntry->localData.fullRootDat.value = -pStackEntry->nResult;
                    pStackEntry->EvalList[pStackEntry->nMoveListIndex] = pStackEntry->localData.fullRootDat.value;
                  }
// kh 11.04.07 end Thomas Gaksch

                } // !if(g_pYBWCManagerInstance->bSearchingSubproblem && (g_pYBWCManagerInstance->pWorkAvailableResult->nCallType == CALL_TYPE_FULL_SEARCH))
*/

              } // if(pStackEntry->localData.fullRootDat.value > pStackEntry->parameters.fullRootPar.alpha)
            } // !if(pStackEntry->parameters.fullRootPar.search_type == SearchShort || pStackEntry->localData.fullRootDat.best_value == ValueNone)

// kh 09.02.07 
            // history-pruning re-search

// kh 05.06.08 end Thomas Gaksch 14b5c
            if(HistoryReSearch && pStackEntry->localData.fullRootDat.reduced && pStackEntry->localData.fullRootDat.value >= pStackEntry->parameters.fullRootPar.beta) 
            {

// kh 16.04.07
              ASSERT(g_pYBWCManagerInstance->pWorkAvailableResult->nCallType == CALL_TYPE_FULL_SEARCH);

// kh 12.04.07 assertion does not hold any longer for toga
/*
// kh 09.02.07 use analogous assertion for the root
//            ASSERT(pStackEntry->parameters.fullSearchPar.node_type != NodePV);
              ASSERT(!g_pYBWCManagerInstance->pWorkAvailableResult->bInPV);
*/

              pStackEntry->localData.fullRootDat.new_depth++;
              ASSERT(pStackEntry->localData.fullRootDat.new_depth == pStackEntry->parameters.fullRootPar.depth - 1);

// kh 24.07.06 simulate recursive call
//            value = -full_search(board, -beta, -alpha, new_depth, height + 1, new_pv, NODE_OPP(node_type));
              ASSERT(g_Stack.nCount > 0);
              Stack_PushFullSearch(/* pStack, */
                                   pStackEntry->parameters.fullRootPar.board, 
                                   -pStackEntry->parameters.fullRootPar.beta, 
                                   -pStackEntry->parameters.fullRootPar.alpha, 
                                   pStackEntry->localData.fullRootDat.new_depth, 
                                   pStackEntry->parameters.fullRootPar.height + 1, 
                                   pStackEntry->localData.fullRootDat.new_pv, 

// kh 09.02.07 $$$ as a future expansion make node type more specific, 
// but NodeAll seems plausible for the moment
//                                 NODE_OPP(pStackEntry->parameters.fullSearchPar.node_type),
                                   NodeAll, 
                                   pStackEntry->localData.fullRootDat.cap_extended, // kh 04.06.08 Thomas Gaksch 14b5c
                                   RETURN_POSITION_FULL_ROOT_04);
              goto L_CALL_FULL_SEARCH;

L_RETURN_POSITION_FULL_ROOT_04:

// kh 23.04.07 assertion does not hold any longer for toga, because cutoffs at the root level are possible
//            ASSERT(pStackEntry->bIsAlive); // kh 09.02.07

// kh 23.04.07 
              if(!pStackEntry->bIsAlive)
              {

// kh 23.04.07 an asynchronous cutoff at the root level is potentially expected only for the root master,
// because only the root master may potentially have sub jobs at the root level
                ASSERT(g_pYBWCManagerInstance->bRootMaster); 

// kh 23.04.07 !pStackEntry->bIsAlive at the root level implicates an asynchronous cutoff at the root level 
                ASSERT(pStackEntry->bSlaveCutoffLevel); 
                goto L_FULL_ROOT_NO_LONGER_ALIVE_UNWIND_MOVE;
              }

              pStackEntry->localData.fullRootDat.value = -pStackEntry->nResult;

              pStackEntry->EvalList[pStackEntry->nMoveListIndex] = pStackEntry->localData.fullRootDat.value;

// kh 30.10.06 redundant here
/*
              if(!pStackEntry->bIsAlive)
              {
                goto L_FULL_ROOT_NO_LONGER_ALIVE_UNWIND_MOVE;
              }
*/
            } // if(HistoryReSearch && pStackEntry->localData.fullRootDat.reduced && pStackEntry->localData.fullRootDat.value > pStackEntry->parameters.fullRootPar.alpha) /* was >= beta */  

L_FULL_ROOT_NO_LONGER_ALIVE_UNWIND_MOVE:
            move_undo(pStackEntry->parameters.fullRootPar.board, pStackEntry->localData.fullRootDat.move, pStackEntry->localData.fullRootDat.undo);

// kh 02.02.07 calc nodes count as difference to the memo start count (negative, defensive)
            pStackEntry->NodesList[pStackEntry->nMoveListIndex] = 
                SearchCurrent->node_nb 
              + pStackEntry->NodesList[pStackEntry->nMoveListIndex] 
              - g_pYBWCManagerInstance->nSlaveNodesReceivedInBetween; // kh 02.02.07 slave nodes asynchronously received in between

            ASSERT(pStackEntry->NodesList[pStackEntry->nMoveListIndex] >= 0);

            post_search_update_root(pStackEntry->nMoveListIndex);

// kh 23.04.07
            if(!pStackEntry->bIsAlive)
            {
              goto L_FULL_ROOT_NO_LONGER_ALIVE;
            }

// kh 27.10.06 the tests below are also done for a slave result received 
// any cut off handling is irrelevant (at the moment) at the root level (see also comment 
// from 27.10.06 in YBWCManager_ProcessSlaveResult(...)

            if(g_pYBWCManagerInstance->bSearchingSubproblem)
            {
            }
            else
            {
              if(SearchCurrent->multipv > 0)
              {
              }
              else
              {
//              if(SearchBestLast[SearchCurrent->multipv].pv[0] == pStackEntry->localData.fullRootDat.move)
                if(pStackEntry->localData.fullRootDat.move == LIST_MOVE(pStackEntry->parameters.fullRootPar.list, 0))
                {
                  pStackEntry->localData.fullRootDat.bIterationConfirmed  = true;
                  g_pYBWCManagerInstance->bRestoreBestFromBestLast        = FALSE;
                }
              }
            }

            if(pStackEntry->localData.fullRootDat.value <= pStackEntry->parameters.fullRootPar.alpha) // upper bound
            {
              if(g_pYBWCManagerInstance->bSearchingSubproblem)
              {
                pStackEntry->parameters.fullRootPar.list->value[pStackEntry->localData.fullRootDat.i] = pStackEntry->localData.fullRootDat.value;
              }
              else
              {

// kh 11.10.06 fruit original assignment
                pStackEntry->parameters.fullRootPar.list->value[pStackEntry->localData.fullRootDat.i] = pStackEntry->localData.fullRootDat.old_alpha;
              }
            } 
            else if(pStackEntry->localData.fullRootDat.value >= pStackEntry->parameters.fullRootPar.beta) // lower bound
            {
              if(g_pYBWCManagerInstance->bSearchingSubproblem)
              {
                pStackEntry->parameters.fullRootPar.list->value[pStackEntry->localData.fullRootDat.i] = pStackEntry->localData.fullRootDat.value;
              }
              else
              {

// kh 11.10.06 fruit original assignment
                pStackEntry->parameters.fullRootPar.list->value[pStackEntry->localData.fullRootDat.i] = pStackEntry->parameters.fullRootPar.beta;
              }
            } 
            else // alpha < value < beta => exact value
            {
              pStackEntry->parameters.fullRootPar.list->value[pStackEntry->localData.fullRootDat.i] = pStackEntry->localData.fullRootDat.value;
            }

// kh 10.04.07 Thomas Gaksch
            if(    (    (pStackEntry->localData.fullRootDat.value > pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv])
                     && (    (pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv] == ValueNone) 
                          || (pStackEntry->localData.fullRootDat.value > pStackEntry->parameters.fullRootPar.alpha)))

// kh 11.10.06 force update of the internal data structures if the only pseudo root move 
// of a subproblem was searched
                || g_pYBWCManagerInstance->bSearchingSubproblem)
            {

// kh 10.04.07 Thomas Gaksch
              SearchBest[SearchCurrent->multipv].move = pStackEntry->localData.fullRootDat.move;

// kh 10.04.07 Thomas Gaksch
              SearchBest[SearchCurrent->multipv].value = pStackEntry->localData.fullRootDat.value;

              if(pStackEntry->localData.fullRootDat.value <= pStackEntry->parameters.fullRootPar.alpha) // upper bound
              {

// kh 10.04.07 Thomas Gaksch
                SearchBest[SearchCurrent->multipv].flags = SearchUpper;

              } 
              else if(pStackEntry->localData.fullRootDat.value >= pStackEntry->parameters.fullRootPar.beta) // lower bound
              {

// kh 10.04.07 Thomas Gaksch
                SearchBest[SearchCurrent->multipv].flags = SearchLower;

              } 
              else // alpha < value < beta => exact value
              {

// kh 10.04.07 Thomas Gaksch
                SearchBest[SearchCurrent->multipv].flags = SearchExact;

              }

// kh 10.04.07 Thomas Gaksch
              SearchBest[SearchCurrent->multipv].depth = pStackEntry->parameters.fullRootPar.depth;
              pv_cat(SearchBest[SearchCurrent->multipv].pv, pStackEntry->localData.fullRootDat.new_pv, pStackEntry->localData.fullRootDat.move);

              if(SearchBest[SearchCurrent->multipv].value >= SearchBestLast[SearchCurrent->multipv].value)
              {
                pStackEntry->localData.fullRootDat.bIterationConfirmed  = true;
                g_pYBWCManagerInstance->bRestoreBestFromBestLast        = FALSE;
              }

              if(pStackEntry->localData.fullRootDat.bIterationConfirmed)
              {
                search_update_best();
              }
              else
              {
                g_pYBWCManagerInstance->bRestoreBestFromBestLast = TRUE;
              }
            }

// kh 10.04.07 Thomas Gaksch
            if(    (pStackEntry->localData.fullRootDat.value > pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv])

// kh 11.10.06 force update of the internal data structures if the only pseudo root move 
// of a subproblem was searched
                || g_pYBWCManagerInstance->bSearchingSubproblem)
            {

// kh 10.04.07 Thomas Gaksch
              pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv] = pStackEntry->localData.fullRootDat.value;

              if(pStackEntry->localData.fullRootDat.value > pStackEntry->parameters.fullRootPar.alpha) 
              {
                if(pStackEntry->parameters.fullRootPar.search_type == SearchNormal) 
                {
                  pStackEntry->parameters.fullRootPar.alpha = pStackEntry->localData.fullRootDat.value;
                }

                if(pStackEntry->localData.fullRootDat.value >= pStackEntry->parameters.fullRootPar.beta) 
                {

// kh 12.04.07 assertion does not hold any longer for toga
/*
// kh 07.09.06 probably possible only in case of searching for a subproblem (where exactly one single
// move is filtered or searched respectively)
                  ASSERT(g_pYBWCManagerInstance->bSearchingSubproblem); 
*/

// kh 12.04.07 fail high is possible in toga, reenable the break idea
                  goto cut_full_root;

// kh 20.10.06 disable fruit original break statement to set the CompletedList for all moves
//                break;

                } // if(pStackEntry->localData.fullRootDat.value >= pStackEntry->parameters.fullRootPar.beta) 
                else
                {
                  if(g_pYBWCManagerInstance->pFruitConfiguration->bUpdateSearchWindows)
                  {
                    if(g_pYBWCManagerInstance->bSearchingSubproblem)
                    {

// kh 23.03.07 there are no other moves to consider at the root level when searching a sub problem

                    } // if(g_pYBWCManagerInstance->bSearchingSubproblem)
                    else
                    {

// kh 09.11.06 update the search windows for all processors for the stack entry
                      nTmpUpdateSearchWindowResult = Stack_UpdateSearchWindowForEntry(/* g_pYBWCManagerInstance->pStack, */
                                                                                      pStackEntry,
                                                                                      pStackEntry->localData.fullRootDat.value,
                                                                                      pStackEntry->parameters.fullRootPar.beta);
                      if(nTmpUpdateSearchWindowResult == MPI_SUCCESS)
                      {
                      }
                      else
                      {
                        if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_ERROR_PRIO_1)
                        {
                          YBWCManager_Printf(g_pYBWCManagerInstance, "ERROR fullSearch(... failed at Stack_UpdateSearchWindowForEntry(..., errorcode = %d\n", nTmpUpdateSearchWindowResult);
                        }
                      }
                    } // !if(g_pYBWCManagerInstance->bSearchingSubproblem)
                  } // if(pThis->pFruitConfiguration->bUpdateSearchWindows)
                } // !if(pStackEntry->localData.fullRootDat.value >= pStackEntry->parameters.fullRootPar.beta)
              } // if(pStackEntry->localData.fullRootDat.value > pStackEntry->parameters.fullRootPar.alpha)
            } // if(pStackEntry->localData.fullRootDat.value > pStackEntry->localData.fullRootDat.best_value)
          } // !if(    (pStackEntry->SlaveList    [pStackEntry->nMoveListIndex] > 0)...

// kh 04.05.07 "net" move list index, not counting the filtered moves in multipv mode (if > 0)
// used only for testing the YBWC condition in Stack_HasSendWorkToSlave(...
          pStackEntry->nNetMoveListIndex++;

        } // !if(bTmpSkipMove)

// kh 17.04.07 real cutoffs are now supported for the root
//L_FULL_ROOT_END_WHILE:

        pStackEntry->localData.fullRootDat.i++;
        pStackEntry->nMoveListIndex = pStackEntry->localData.fullRootDat.i;
      } // while(pStackEntry->bIsAlive && (pStackEntry->localData.fullRootDat.i < LIST_SIZE(pStackEntry->parameters.fullRootPar.list)))

L_FULL_ROOT_NO_LONGER_ALIVE:
#if DEBUG
      if(pStackEntry->nMemoMoveListTotalCount == pStackEntry->nMoveListTotalCount)
      {
      }
      else
      {
        if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_ERROR_PRIO_1)
        {
          YBWCManager_Printf(g_pYBWCManagerInstance, 
                             "ERROR fullSearch(... (root 1) nMoveListTotalCount changed from %d to %d\n",
                             pStackEntry->nMemoMoveListTotalCount,
                             pStackEntry->nMoveListTotalCount);
        }
      }
#endif

      bTmpBreak = false;

// kh 12.04.07 assertion does not hold any longer for toga
/*
// kh 30.10.06 the root level will never be aborted via bIsAlive (neither locally nor via processing a slave result)
// a slave already searching for a subproblem here, will never have a master role at the root level anyway,
// because he will search only for exactly one move at his root level
      ASSERT(pStackEntry->bIsAlive);
*/

      bTmpFirst = true;
      if(g_pYBWCManagerInstance->pFruitConfiguration->nDebugWaitForSlaveRate > 0)
      {
        CountdownTimer_Restart(g_pYBWCManagerInstance->pCountdownTimerDebugWaitForSlave);
      }

#if DEBUG
      pStackEntry->nMemoMoveListTotalCount = pStackEntry->nMoveListTotalCount; // kh 18.03.07 for debug purposes only
#endif

      if(pStackEntry->bHasAnySubWork) // kh 22.10.07 quick check for potential subwork (performance)
      {

// kh 22.10.07 performance will not be a real problem here, but for the sake of completeness checking 
// for potential subwroke here seesm to be appropriate

        while(pStackEntry->bIsAlive && !bTmpBreak) 
        {
          nTmpIndex = 0;
          while((nTmpIndex < pStackEntry->nMoveListTotalCount) && !bTmpBreak) 
          {
//          YBWCManager_ServiceMessages(g_pYBWCManagerInstance); // kh 18.03.07 tuning 

            if(pStackEntry->CompletedList[nTmpIndex])
            {
            }
            else
            {

// kh 30.10.06 only the root master will wait at the root level for outstanding slave results
// (a slave will search only for exactly one move at his root level)
              ASSERT(g_pYBWCManagerInstance->bRootMaster);
              bTmpBreak = true;
            }

            nTmpIndex++;
          } // while((nTmpIndex < pStackEntry->nMoveListTotalCount) && !bTmpBreak)

          if(bTmpBreak)
          {

// kh 30.10.06 only the root master will wait at the root level for outstanding slave results (see above)
// (a slave will search only for exactly one move at his root level)
            ASSERT(g_pYBWCManagerInstance->bRootMaster);
            bTmpBreak = false;

// kh 07.09.06 waiting for at least one slave result is required

            if(g_pYBWCManagerInstance->pFruitConfiguration->nDebugWaitForSlaveRate > 0)
            {
              if(CountdownTimer_IsRunning(g_pYBWCManagerInstance->pCountdownTimerDebugWaitForSlave))
              {
              }
              else
              {
                if(bTmpFirst)
                {
                  g_pYBWCManagerInstance->nDebugWaitId++;
                  bTmpFirst = false;
                }
                for(nTmpIndex2 = 0; nTmpIndex2 < pStackEntry->nMoveListTotalCount; nTmpIndex2++) 
                {
                  if(pStackEntry->CompletedList[nTmpIndex2])
                  {
                  }
                  else
                  {
                    if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_FORCE_OUTPUT)
                    {

#if DEBUG
                      move_to_string(pStackEntry->MoveList[nTmpIndex2], sTmpMoveString, 256);
                      YBWCManager_Printf(g_pYBWCManagerInstance, 
//                                       "waiting (wait id "S64_FORMAT") StackIndex %d MoveNumber %d/%d Move %s (%d) WorkId " S64_FORMAT " at root (search depth %d) nodes " S64_FORMAT " localnodes " S64_FORMAT " on slave %d\n", 
                                         "waiting for %d (wait id "S64_FORMAT") StackIndex %d Move %d/%d %s (%d) WorkId " S64_FORMAT " at root (search depth %d) initial a=%d b=%d, last a=%d b=%d, work a=%d b=%d nodes " S64_FORMAT " local " S64_FORMAT "\n", 
                                         pStackEntry->SlaveList[nTmpIndex2],
                                         g_pYBWCManagerInstance->nDebugWaitId,
                                         g_Stack.nCount - 1,
                                         nTmpIndex2 + 1,
                                         pStackEntry->nMoveListTotalCount,
                                         sTmpMoveString,
                                         pStackEntry->MoveList[nTmpIndex2],
                                         pStackEntry->WorkIdList[nTmpIndex2],
                                         pStackEntry->parameters.fullRootPar.depth,
                                         pStackEntry->nAlphaParameterOnEntry,
                                         pStackEntry->nBetaParameterOnEntry,
                                         pStackEntry->parameters.fullRootPar.alpha,
                                         pStackEntry->parameters.fullRootPar.beta,
                                         pStackEntry->AlphaList[nTmpIndex2],
                                         pStackEntry->BetaList[nTmpIndex2],
                                         SearchCurrent->node_nb,
                                         SearchCurrent->node_local_nb);
#endif
                    }
                  }
                }
                CountdownTimer_Restart(g_pYBWCManagerInstance->pCountdownTimerDebugWaitForSlave);
              }
            } // if(g_pYBWCManagerInstance->pFruitConfiguration->nDebugWaitForSlaveRate > 0)

            YBWCManager_ServiceMessages(g_pYBWCManagerInstance);

#if DEBUG
            if(pStackEntry->nMemoMoveListTotalCount == pStackEntry->nMoveListTotalCount)
            {
            } // if(pStackEntry->nMemoMoveListTotalCount == pStackEntry->nMoveListTotalCount)
            else
            {
              if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_ERROR_PRIO_1)
              {
                YBWCManager_Printf(g_pYBWCManagerInstance, 
                                   "ERROR fullSearch(... (root 2) nMoveListTotalCount changed from %d to %d\n",
                                   pStackEntry->nMemoMoveListTotalCount,
                                   pStackEntry->nMoveListTotalCount);
              }
            } // !if(pStackEntry->nMemoMoveListTotalCount == pStackEntry->nMoveListTotalCount)
#endif

// kh 25.12.06 do this for the root master now to handle a stop received from the gui fast
            search_check();

// kh 25.12.06 would have not been executed anyway here, because only the root master will reach the statement 
/*
// kh 07.12.06 should make stopping faster
            if(g_pYBWCManagerInstance->bStoppingActive)
            {
              search_check();
            } // if(g_pYBWCManagerInstance->bStoppingActive)
*/
          } // if(bTmpBreak)
          else
          {
            bTmpBreak = true;
          } // !if(bTmpBreak)
        } // while(pStackEntry->bIsAlive && !bTmpBreak) 
      } // if(pStackEntry->bHasAnySubWork)
      else
      {
        // kh 22.10.07 no actions are required if there is not any potential subwork (performance)
      } // !if(pStackEntry->bHasAnySubWork)

      if(pStackEntry->bIsAlive)
      {
      }
      else
      {

// kh 12.04.07 assertion does not hold any longer for toga
//      ASSERT(false); // kh 30.10.06 (see also assertion for the bIsAlive state at the root level above)


        goto cut_full_root; // kh 12.04.07 use a goto here, following the standard Fruit programming style 
      }

cut_full_root:

// kh 20.09.06 stop searching on all processors for the stack entry
// stop may be broadcasted here as a "forced stop" as 
// a future expansion to all appropriate slaves for a better performance
      nStopResult = Stack_StopEntry(/* g_pYBWCManagerInstance->pStack, */ pStackEntry);
      if(nStopResult == MPI_SUCCESS)
      {
      }
      else
      {
        if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_ERROR_PRIO_1)
        {
          YBWCManager_Printf(g_pYBWCManagerInstance, "ERROR fullSearch(... failed at Stack_StopEntry(..., errorcode = %d\n", nStopResult);
        }
      }

      ASSERT(value_is_ok(pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv]));

      list_sort(pStackEntry->parameters.fullRootPar.list);

// kh 03.05.07 in multipv move the best move after list_sort(... is expected at position 0, 
// the second best move is expected at position 1, etc. ...
// kh 03.05.07 will still not work, the pStackEntry->parameters.fullRootPar.list is only initialized once for SearchCurrent->multipv == 0
// and the list_sort(... can get "out of sync" in respect to the SearchCurrent->multipv index or 
// SearchBest[SearchCurrent->multipv] respectively

// kh 04.05.07 one possible reason for this is the dependency of the evaluation from the "search history" in general
// (due to hash table filling, history pruning etc.), so slight differences in the evaluation are possible for 
// the multipv mode (analogous to searching a move in parallel). the second best move found with 
// SearchCurrent->multipv == 1 may e.g. have a score of 48 and the third best move for SearchCurrent->multipv == 2
// may have a score of 50 (expected is a score <= 48 of course). in search_update_best(... the move is separately
// sorted at the correct position so this behavior is not obvious
//    ASSERT(SearchBest[SearchCurrent->multipv].move == LIST_MOVE(pStackEntry->parameters.fullRootPar.list, SearchCurrent->multipv)); 
//    ASSERT(SearchBest[SearchCurrent->multipv].move == LIST_MOVE(pStackEntry->parameters.fullRootPar.list, 0));

// kh 03.05.07 use implication
      ASSERT(    (SearchBest[SearchCurrent->multipv].move == LIST_MOVE(pStackEntry->parameters.fullRootPar.list, 0))
              || (SearchCurrent->multipv > 0));

// kh 23.04.07 assertion does not hold any longer for toga
//    ASSERT(SearchBest[SearchCurrent->multipv].value == pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv]);

// kh 24.04.07 $$$ for debug purposes
      if(SearchBest[SearchCurrent->multipv].value == pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv])
      {
      }
      else
      {

// kh 24.04.07 that seems to be no problem, because in send_best_move(... or 
// fruit_send_work_available_best_move_result_move(... only SearchBest[0]... is accessed anyway
        if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_WARNING_PRIO_1)
        {
          YBWCManager_Printf(g_pYBWCManagerInstance, 
                             "WARNING fullSearch(... SearchBest[SearchCurrent->multipv].value = %d != pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv] = %d \n", 
                             SearchBest[SearchCurrent->multipv].value,
                             pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv]);
        }
      }

      if(g_pYBWCManagerInstance->bSearchingSubproblem)
      {

// kh 04.06.08 code below is not used (and not ported to 14b5c yet)
/*
        if(false) // kh 23.03.07 temp only for a test
        {

// kh 21.03.07 do all handling here analogous to full search 
          ASSERT(SearchBest[SearchCurrent->multipv].move != MoveNone);

          if(SearchBest[SearchCurrent->multipv].move != MoveNone) 
          {

// kh 21.03.07 good_move(... marking of a move is potentially doubled at the moment
// because it is also done again when the move is received by the master
// this needs eventually further experimentation to analyze the tradeoff of a "wrong" duplication
// but having e.g. the result immediately available especially when the move result is transmitted back to
// another machine or when the history tables are not in shared memory or the history tables are not 
// broadcasted anyway
            if(g_pYBWCManagerInstance->pFruitConfiguration->bForceReproducibleEvaluation)
            {
            }
            else
            {

// kh 21.03.07 make the good_move_marking a little bit more defensive
// (the original fruit statement has the best move directly available here)
              if(    pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv] >= pStackEntry->parameters.fullRootPar.beta 
                  && !move_is_tactical(SearchBest[SearchCurrent->multipv].move, pStackEntry->parameters.fullRootPar.board))
              {
                good_move(SearchBest[SearchCurrent->multipv].move, pStackEntry->parameters.fullRootPar.board, pStackEntry->parameters.fullRootPar.depth, pStackEntry->parameters.fullRootPar.height);
              }
            }

// kh 21.03.07 there are no other moves here when searching a subproblem 

// some data structures referenced in the (commented) program fragment below do not even exist for the root call type
// kh 21.03.07 $$$ use it as a future expansion
/*            
            if(    pStackEntry->localData.fullRootDat.best_value >= pStackEntry->parameters.fullRootPar.beta 
                && !move_is_tactical(SearchBest[SearchCurrent->multipv].move, pStackEntry->parameters.fullRootPar.board)) 
            {
/*
              ASSERT(pStackEntry->localData.fullRootDat.played_nb > 0);
              ASSERT(pStackEntry->localData.fullRootDat.played[pStackEntry->localData.fullRootDat.played_nb - 1] == SearchBest[SearchCurrent->multipv].move);
/*
              ASSERT(    pStackEntry->localData.fullRootDat.played_nb > 0 
                      && pStackEntry->localData.fullRootDat.played[pStackEntry->localData.fullRootDat.played_nb - 1] == SearchBest[SearchCurrent->multipv].move);
* /
              for(pStackEntry->localData.fullRootDat.i = 0; pStackEntry->localData.fullRootDat.i < pStackEntry->localData.fullRootDat.played_nb - 1; pStackEntry->localData.fullRootDat.i++) 
              {
                pStackEntry->localData.fullRootDat.move = pStackEntry->localData.fullRootDat.played[pStackEntry->localData.fullRootDat.i];
                ASSERT(pStackEntry->localData.fullRootDat.move != SearchBest[SearchCurrent->multipv].move);
                if(g_pYBWCManagerInstance->pFruitConfiguration->bForceReproducibleEvaluation)
                {
                }
                else
                {
                  history_bad(pStackEntry->localData.fullRootDat.move, pStackEntry->parameters.fullRootPar.board);
                }
              }
* /

// kh 21.03.07 here again may exist some kind of over estimation of "how good the move is"
// (see comments from 21.03.07 above for the good_move(... marking) 
              if(g_pYBWCManagerInstance->pFruitConfiguration->bForceReproducibleEvaluation)
              {
              }
              else
              {
                history_good(SearchBest[SearchCurrent->multipv].move, pStackEntry->parameters.fullRootPar.board);
              }
            } // if(    pStackEntry->localData.fullRootDat.best_value >= pStackEntry->parameters.fullRootPar.beta...
* / <- kh 04.06.08 remove blank before port to 14b5c

          } // if(SearchBest[SearchCurrent->multipv].move != MoveNone) 

          // transposition table

//        if(pStackEntry->localData.fullRootDat.best_value > pStackEntry->localData.fullRootDat.old_alpha)
          if(pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv] >= pStackEntry->parameters.fullRootPar.beta)
//        if(pStackEntry->localData.fullRootDat.best_value > pStackEntry->parameters.fullRootPar.alpha)
//        {
            if(UseTrans && pStackEntry->parameters.fullRootPar.depth >= TransDepth) 
            {
              nTmpTransMove  = SearchBest[SearchCurrent->multipv].move;
              nTmpTransDepth = pStackEntry->parameters.fullRootPar.depth;

              nTmpTransMinValue = 
                (pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv] > pStackEntry->localData.fullRootDat.old_alpha) ? value_to_trans(pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv], pStackEntry->parameters.fullRootPar.height + SearchInfo->nHeightOffset) : -ValueInf;

// kh 21.03.07 adjust by SearchInfo->nHeightOffset here now
/*
              nTmpTransMaxValue = 
                (pStackEntry->localData.fullRootDat.best_value < pStackEntry->parameters.fullRootPar.beta)      ? value_to_trans(pStackEntry->localData.fullRootDat.best_value, pStackEntry->parameters.fullRootPar.height + SearchInfo->nHeightOffset) : +ValueInf;
* / <- kh 04.06.08 remove blank before port to 14b5c


              nTmpTransMaxValue = +ValueInf;

/*
              if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_FORCE_OUTPUT)
              {
                YBWCManager_Printf(g_pYBWCManagerInstance, 
                                  "full_search(... at trans store at the root\n");
              }
* / <- kh 04.06.08 remove blank before port to 14b5c

              trans_store(Trans, 
                          pStackEntry->parameters.fullRootPar.board->key, 
                          nTmpTransMove, 
                          nTmpTransDepth, 
                          nTmpTransMinValue, 
                          nTmpTransMaxValue);

              if(g_pYBWCManagerInstance->bPotentialBroadcastTranspositionTable)
              {
                if(    (nTmpTransDepth >= g_pYBWCManagerInstance->pFruitConfiguration->nMinimumTransDepthForBroadcast)
//                  && g_pYBWCManagerInstance->nUniversalDebugFlag1 
                  )
                {
                  HashTableBuffer_AddEntryAndCheckBroadcast(g_pYBWCManagerInstance->pHashTableTransmitBuffer, 
                                                            pStackEntry->parameters.fullRootPar.board->key, 
                                                            nTmpTransMove, 
                                                            nTmpTransDepth, 
                                                            nTmpTransMinValue, 
                                                            nTmpTransMaxValue);
                }
              } // if(g_pYBWCManagerInstance->bPotentialBroadcastTranspositionTable)
            } // if(UseTrans && pStackEntry->parameters.fullRootPar.depth >= TransDepth) 
//        }  // if(pStackEntry->localData.fullRootDat.best_value > pStackEntry->parameters.fullRootPar.alpha)
        } // if(false) 
*/

      } // if(g_pYBWCManagerInstance->bSearchingSubproblem)
      else
      {

        if(    UseTrans 

// kh 10.04.07 Thomas Gaksch
            && pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv] > pStackEntry->localData.fullRootDat.old_alpha 
//          && pStackEntry->localData.fullRootDat.best_value > pStackEntry->localData.fullRootDat.old_alpha 
            && pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv] < pStackEntry->parameters.fullRootPar.beta) 
//          && pStackEntry->localData.fullRootDat.best_value < pStackEntry->parameters.fullRootPar.beta) 
        {

// kh 10.04.07 Thomas Gaksch
          pv_fill(SearchBest[SearchCurrent->multipv].pv, pStackEntry->parameters.fullRootPar.board);
//        pv_fill(SearchBest->pv, pStackEntry->parameters.fullRootPar.board);
        }
      } // !if(g_pYBWCManagerInstance->bSearchingSubproblem)

// kh 21.03.07
      ASSERT(!g_pYBWCManagerInstance->bSearchingSubproblem || (pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv] == pStackEntry->localData.fullRootDat.value));

// kh 26.07.06
//    return best_value;

// kh 10.04.07 Thomas Gaksch
      pStackEntry->nResult = pStackEntry->localData.fullRootDat.best_value[SearchCurrent->multipv];

      break;

    case CALL_TYPE_FULL_SEARCH:

#if DEBUG
      pStackEntry->nAlphaParameterOnEntry = pStackEntry->parameters.fullSearchPar.alpha;
      pStackEntry->nBetaParameterOnEntry  = pStackEntry->parameters.fullSearchPar.beta;
#endif

      ASSERT(pStackEntry->parameters.fullSearchPar.board != NULL);

// kh 16.04.07 assertion does not hold any longer for toga in multipv mode
//    ASSERT(range_is_ok(pStackEntry->parameters.fullSearchPar.alpha, pStackEntry->parameters.fullSearchPar.beta));
      ASSERT(    range_is_ok(pStackEntry->parameters.fullSearchPar.alpha, pStackEntry->parameters.fullSearchPar.beta) 
              || (SearchInput->multipv > 0));
      
      ASSERT(depth_is_ok(pStackEntry->parameters.fullSearchPar.depth));
      ASSERT(height_is_ok(pStackEntry->parameters.fullSearchPar.height + SearchInfo->nHeightOffset));
      ASSERT(pStackEntry->parameters.fullSearchPar.ppv != NULL);
      ASSERT(    pStackEntry->parameters.fullSearchPar.node_type == NodePV 
              || pStackEntry->parameters.fullSearchPar.node_type == NodeCut 
              || pStackEntry->parameters.fullSearchPar.node_type == NodeAll);

      ASSERT(board_is_legal(pStackEntry->parameters.fullSearchPar.board));

// kh 30.10.06 check this early too (defensive, performance)
      if(!pStackEntry->bIsAlive)
      {

// kh 23.04.07 this lines are potentially reached for the next level, so the cutoff level must have been already set
// for a lower level
        ASSERT(!pStackEntry->bSlaveCutoffLevel);

        pStackEntry->localData.fullSearchDat.best_value  = ValueNone; // kh 01.11.06 defensive
        pStackEntry->localData.fullSearchDat.best_move   = MoveNone;  // kh 01.11.06 defensive

// kh 30.10.06 minimal optimized for this special case
//      goto L_FULL_SEARCH_NO_LONGER_ALIVE;
        goto cut_full_search;
      }

      // horizon?

// kh 10.04.07 start Thomas Gaksch
      if(pStackEntry->parameters.fullSearchPar.depth <= 0) 
      {
	      if(pStackEntry->parameters.fullSearchPar.node_type == NodePV)
        {
			    CheckDepth = 1 - CheckNb - 1;
        }
	      else
        {
			    CheckDepth = 1 - CheckNb;
        }

        if(pStackEntry->parameters.fullSearchPar.depth <= 0) 
        {

// kh 21.07.06
//        return full_quiescence(board, alpha, beta, 0, height, pv);
          ASSERT(g_Stack.nCount > 0);

          Stack_PushFullQuiescence(/* pStack, */
                                   pStackEntry->parameters.fullSearchPar.board, 
                                   pStackEntry->parameters.fullSearchPar.alpha, 
                                   pStackEntry->parameters.fullSearchPar.beta, 
                                   0, 
                                   pStackEntry->parameters.fullSearchPar.height, 
                                   pStackEntry->parameters.fullSearchPar.ppv,
                                   RETURN_POSITION_FULL_SEARCH_01);
          goto L_CALL_FULL_SEARCH;

L_RETURN_POSITION_FULL_SEARCH_01:
          goto L_RETURN_FULL_SEARCH;
        }
      } // if(pStackEntry->parameters.fullSearchPar.depth <= 0)

      // init

      SearchCurrent->node_nb++;
      SearchCurrent->node_local_nb++;
      g_pYBWCManagerInstance->nTotalNodes++;

      SearchInfo->check_nb--;
      SearchInfo->check_nb_mpi_poll--;
      PV_CLEAR(pStackEntry->parameters.fullSearchPar.ppv);

      if(pStackEntry->parameters.fullSearchPar.height > SearchCurrent->max_depth) 
      {
        SearchCurrent->max_depth = pStackEntry->parameters.fullSearchPar.height;
      }

      if(pStackEntry->parameters.fullSearchPar.height > SearchCurrent->max_local_depth) 
      {
        SearchCurrent->max_local_depth = pStackEntry->parameters.fullSearchPar.height;
      }

      if(SearchInfo->check_nb <= 0) 
      {
        SearchInfo->check_nb += SearchInfo->check_inc;
        search_check();
      }

      // draw?

// kh 03.06.08 start Thomas Gaksch 14b5c
      if(board_is_repetition(pStackEntry->parameters.fullSearchPar.board))
      {

// kh 03.06.08
//      return ValueDraw;
        pStackEntry->nResult = ValueDraw;
        goto L_RETURN_FULL_SEARCH;
      }
// kh 03.06.08 end Thomas Gaksch 14b5c


#if defined(_WIN32) || defined(_WIN64)

// kh 03.06.08 start Thomas Gaksch 14b5c
/*
		Interior node recognizer from scorpio by Daniel Shawul
		-> dont probe at the leaves as this will slow down search
	    For 4/3 pieces probe there also.
		-> After captures and pawn moves assume exact score and cutoff tree,
	    because we are making progress. Note this is not done only for speed.
		-> if we are far from root (depth / 2), assume exact score and cutoff tree
*/
      
	    if(egbb_is_loaded && pStackEntry->parameters.fullSearchPar.board->piece_nb <= 5)
      { 
		    pStackEntry->localData.fullSearchDat.probe_depth = (2 * SearchCurrent->act_iteration) / 3;
		    if(    (    pStackEntry->parameters.fullSearchPar.board->piece_nb <=4 
                 || pStackEntry->parameters.fullSearchPar.height          <= pStackEntry->localData.fullSearchDat.probe_depth)
            && (    pStackEntry->parameters.fullSearchPar.height >= pStackEntry->localData.fullSearchDat.probe_depth 
		             || pStackEntry->parameters.fullSearchPar.board->cap_sq != SquareNone 
                 || PIECE_IS_PAWN(pStackEntry->parameters.fullSearchPar.board->moving_piece))
			    ) 
        {
			    if(probe_bitbases(pStackEntry->parameters.fullSearchPar.board, 
                            pStackEntry->localData.fullSearchDat.probe_score))
          {

// kh 04.06.08 adjust by SearchInfo->nHeightOffset here now
				    pStackEntry->localData.fullSearchDat.probe_score = 
              value_from_trans(pStackEntry->localData.fullSearchDat.probe_score, 
                               pStackEntry->parameters.fullSearchPar.height + SearchInfo->nHeightOffset);

          /*trans_move  = MoveNone;
				    trans_depth = depth;
				    trans_flags = TransUnknown;
				    if (probe_score > alpha) trans_flags |= TransLower;
				    if (probe_score < beta) trans_flags |= TransUpper;
   			        trans_store(Trans,board->key,trans_move,trans_depth,trans_flags,probe_score);*/

// kh 03.06.08
//		      return probe_score;
            pStackEntry->nResult = pStackEntry->localData.fullSearchDat.probe_score;
            goto L_RETURN_FULL_SEARCH;
			    }
		    }
	    } // if(egbb_is_loaded && pStackEntry->parameters.fullSearchPar.board->piece_nb <= 5)
// kh 03.06.08 end Thomas Gaksch 14b5c

#else // assume POSIX

#endif

      if(recog_draw(pStackEntry->parameters.fullSearchPar.board)) 
      {

// kh 03.06.08
//      return ValueDraw;
        pStackEntry->nResult = ValueDraw;
        goto L_RETURN_FULL_SEARCH;
      }

      // mate-distance pruning

      if(UseDistancePruning) 
      {

        // lower bound

        pStackEntry->localData.fullSearchDat.value = VALUE_MATE((pStackEntry->parameters.fullSearchPar.height + SearchInfo->nHeightOffset) + 2); // does not work if the current position is mate
        if(pStackEntry->localData.fullSearchDat.value > pStackEntry->parameters.fullSearchPar.alpha && board_is_mate(pStackEntry->parameters.fullSearchPar.board)) 
        {
          pStackEntry->localData.fullSearchDat.value = VALUE_MATE(pStackEntry->parameters.fullSearchPar.height + SearchInfo->nHeightOffset);
        }

        if(pStackEntry->localData.fullSearchDat.value > pStackEntry->parameters.fullSearchPar.alpha) 
        {
          pStackEntry->parameters.fullSearchPar.alpha = pStackEntry->localData.fullSearchDat.value;
          if(pStackEntry->localData.fullSearchDat.value >= pStackEntry->parameters.fullSearchPar.beta) 
          {

// kh 21.07.06
//          return value;
            pStackEntry->nResult = pStackEntry->localData.fullSearchDat.value;
            goto L_RETURN_FULL_SEARCH;
          } // if(pStackEntry->localData.fullSearchDat.value >= pStackEntry->parameters.fullSearchPar.beta)
        } // if(pStackEntry->localData.fullSearchDat.value > pStackEntry->parameters.fullSearchPar.alpha)

        // upper bound

        pStackEntry->localData.fullSearchDat.value = -VALUE_MATE((pStackEntry->parameters.fullSearchPar.height + SearchInfo->nHeightOffset) + 1);

        if(pStackEntry->localData.fullSearchDat.value < pStackEntry->parameters.fullSearchPar.beta) 
        {
          pStackEntry->parameters.fullSearchPar.beta = pStackEntry->localData.fullSearchDat.value;
          if(pStackEntry->localData.fullSearchDat.value <= pStackEntry->parameters.fullSearchPar.alpha) 
          {

// kh 21.07.06
//          return value;
            pStackEntry->nResult = pStackEntry->localData.fullSearchDat.value;
            goto L_RETURN_FULL_SEARCH;
          }
        }
      } // if(UseDistancePruning) 

    // transposition table

      pStackEntry->localData.fullSearchDat.trans_move = MoveNone;

      if(UseTrans && pStackEntry->parameters.fullSearchPar.depth >= TransDepth) 
      {

// kh 03.06.08 start Thomas Gaksch 14b5c
        if(trans_retrieve(Trans, 
                          &pStackEntry->localData.fullSearchDat.found_entry,
                          pStackEntry->parameters.fullSearchPar.board->key, 
                          &pStackEntry->localData.fullSearchDat.trans_move, 
                          &pStackEntry->localData.fullSearchDat.trans_depth, 
                          &pStackEntry->localData.fullSearchDat.trans_flags, 
                          &pStackEntry->localData.fullSearchDat.trans_value)) 
        {
          // trans_move is now updated

/*        if(found_entry->depth != trans_depth)
          {
			      found_entry->depth = trans_depth;
		      }
*/

          if(pStackEntry->parameters.fullSearchPar.node_type != NodePV) 
          {
            if(UseMateValues) 
            {
              if(pStackEntry->localData.fullSearchDat.trans_depth < pStackEntry->parameters.fullSearchPar.depth) 
              {
				        if(pStackEntry->localData.fullSearchDat.trans_value < -ValueEvalInf && TRANS_IS_UPPER(pStackEntry->localData.fullSearchDat.trans_flags)) 
                {
					        pStackEntry->localData.fullSearchDat.trans_depth = pStackEntry->parameters.fullSearchPar.depth;
					        pStackEntry->localData.fullSearchDat.trans_flags = TransUpper;
				        } 
                else if(pStackEntry->localData.fullSearchDat.trans_value > +ValueEvalInf && TRANS_IS_LOWER(pStackEntry->localData.fullSearchDat.trans_flags)) 
                {
					        pStackEntry->localData.fullSearchDat.trans_depth = pStackEntry->parameters.fullSearchPar.depth;
					        pStackEntry->localData.fullSearchDat.trans_flags = TransLower;
				        }
			        } // if(pStackEntry->localData.fullSearchDat.trans_depth < pStackEntry->parameters.fullSearchPar.depth) 

				      if(pStackEntry->localData.fullSearchDat.trans_depth >= pStackEntry->parameters.fullSearchPar.depth) 
              {

// kh 03.06.08 adjust by SearchInfo->nHeightOffset here now
				        pStackEntry->localData.fullSearchDat.trans_value = 
                  value_from_trans(pStackEntry->localData.fullSearchDat.trans_value, 
                                   pStackEntry->parameters.fullSearchPar.height + SearchInfo->nHeightOffset);

				        if(   (UseExact && TRANS_IS_EXACT(pStackEntry->localData.fullSearchDat.trans_flags))
					          ||(TRANS_IS_LOWER(pStackEntry->localData.fullSearchDat.trans_flags) && pStackEntry->localData.fullSearchDat.trans_value >= pStackEntry->parameters.fullSearchPar.beta)
					          ||(TRANS_IS_UPPER(pStackEntry->localData.fullSearchDat.trans_flags) && pStackEntry->localData.fullSearchDat.trans_value <= pStackEntry->parameters.fullSearchPar.alpha)) 
                {
//                return trans_value;
                  pStackEntry->nResult = pStackEntry->localData.fullSearchDat.trans_value;
                  goto L_RETURN_FULL_SEARCH;
				        } 

/*
                if (TRANS_IS_EXACT(trans_flags))
					        return trans_value;
				        if (TRANS_IS_LOWER(trans_flags)) 
                {
						      if (trans_value >= beta)
							      return trans_value;
						      if (trans_value > alpha)
							      alpha = trans_value;
					      }
					      if(TRANS_IS_UPPER(trans_flags)) 
                {
						      if (trans_value <= alpha)
							      return trans_value;
						      if (trans_value < beta)
							      beta = trans_value;
					      } 
*/

				      } // if(trans_depth >= depth) 
			      } // if(UseMateValues) 
          } // if(pStackEntry->parameters.fullSearchPar.node_type != NodePV)
        } // if(trans_retrieve(Trans,...
// kh 03.06.08 end Thomas Gaksch 14b5c

      } // if(UseTrans && pStackEntry->parameters.fullSearchPar.depth >= TransDepth)

    // height limit

      if((pStackEntry->parameters.fullSearchPar.height + SearchInfo->nHeightOffset) >= HeightMax - 1) 
      {

// kh 19.03.07        
        if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_WARNING_PRIO_1)
        {
          YBWCManager_Printf(g_pYBWCManagerInstance, 
                             "WARNING full_search(... at CALL_TYPE_FULL_SEARCH HeightMax %d + %d >= limit %d reached\n",
                             SearchInfo->nHeightOffset,
                             pStackEntry->parameters.fullSearchPar.height,
                             HeightMax - 1);
        }

// kh 24.07.06
//      return eval(board);

// kh 03.06.08 Thomas Gaksch 14b5c
        pStackEntry->nResult = eval(pStackEntry->parameters.fullSearchPar.board, pStackEntry->parameters.fullSearchPar.alpha, pStackEntry->parameters.fullSearchPar.beta);
        goto L_RETURN_FULL_SEARCH;
      }

      // more init

      pStackEntry->localData.fullSearchDat.old_alpha   = pStackEntry->parameters.fullSearchPar.alpha;
      pStackEntry->localData.fullSearchDat.best_value  = ValueNone;
      pStackEntry->localData.fullSearchDat.best_move   = MoveNone;
      pStackEntry->localData.fullSearchDat.played_nb   = 0;

      attack_set(pStackEntry->localData.fullSearchDat.attack, pStackEntry->parameters.fullSearchPar.board);
      pStackEntry->localData.fullSearchDat.in_check = ATTACK_IN_CHECK(pStackEntry->localData.fullSearchDat.attack);

      // null-move pruning

// kh 03.06.08 Thomas Gaksch 14b5c
      if(UseNull && pStackEntry->parameters.fullSearchPar.depth >= NullDepth && pStackEntry->parameters.fullSearchPar.node_type != NodePV) 
      {
        if(    !pStackEntry->localData.fullSearchDat.in_check
            && !value_is_mate(pStackEntry->parameters.fullSearchPar.beta)
            && do_null(pStackEntry->parameters.fullSearchPar.board)
            && (    !UseNullEval 
                 || pStackEntry->parameters.fullSearchPar.depth <= NullReduction + 1 

// kh 03.06.08 Thomas Gaksch 14b5c
                 || eval(pStackEntry->parameters.fullSearchPar.board, pStackEntry->parameters.fullSearchPar.alpha, pStackEntry->parameters.fullSearchPar.beta) >= pStackEntry->parameters.fullSearchPar.beta))

        {
          // null-move search

// kh 03.06.08 Thomas Gaksch 14b5c
       //  if (depth < 11)

          pStackEntry->localData.fullSearchDat.new_depth = pStackEntry->parameters.fullSearchPar.depth - NullReduction - 1;

// kh 11.04.07 Thomas Gaksch
//        new_depth = depth - R_adpt(board->piece_size[board->turn]+board->pawn_size[board->turn],depth,NullReduction) - 1;

          move_do_null(pStackEntry->parameters.fullSearchPar.board, pStackEntry->localData.fullSearchDat.undo);

// kh 03.06.08 Thomas Gaksch 14b5c
		// else
		//	new_depth = depth - NullReduction - 2;
		 //new_depth = depth - R_adpt(board->piece_size[board->turn]+board->pawn_size[board->turn],depth,NullReduction) - 1;

// kh 30.10.06 bIsAlive state will never have changed to false above and up to here for this actual stack entry CALL_TYPE_FULL_SEARCH
          ASSERT(pStackEntry->bIsAlive); 

// kh 30.10.06 the bIsAlive state may change below in between each call (goto L_CALL_FULL_SEARCH) 
// and return (reaching L_RETURN_POSITION_...) 

// kh 21.07.06 simulate recursive call
//        value = -full_search(board, -beta, -beta + 1, new_depth, height + 1, new_pv, NODE_OPP(node_type));
          ASSERT(g_Stack.nCount > 0);
          Stack_PushFullSearch(/* pStack, */
                               pStackEntry->parameters.fullSearchPar.board, 
                               -pStackEntry->parameters.fullSearchPar.beta, 
                               -pStackEntry->parameters.fullSearchPar.beta + 1, 
                               pStackEntry->localData.fullSearchDat.new_depth, 
                               pStackEntry->parameters.fullSearchPar.height + 1, 
                               pStackEntry->localData.fullSearchDat.new_pv, 
                               NODE_OPP(pStackEntry->parameters.fullSearchPar.node_type),
                               false, // kh 03.06.08 Thomas Gaksch 14b5c
                               RETURN_POSITION_FULL_SEARCH_02);
          goto L_CALL_FULL_SEARCH;

L_RETURN_POSITION_FULL_SEARCH_02:
          if(!pStackEntry->bIsAlive)
          {
            goto L_FULL_SEARCH_NO_LONGER_ALIVE_UNWIND_NULL_MOVE;
          }

          pStackEntry->localData.fullSearchDat.value = -pStackEntry->nResult;

L_FULL_SEARCH_NO_LONGER_ALIVE_UNWIND_NULL_MOVE:
          move_undo_null(pStackEntry->parameters.fullSearchPar.board, pStackEntry->localData.fullSearchDat.undo);

          if(!pStackEntry->bIsAlive)
          {
            goto L_FULL_SEARCH_NO_LONGER_ALIVE;
          }

          // verification search

          if(UseVer && pStackEntry->parameters.fullSearchPar.depth > VerReduction)
          {
            if(    pStackEntry->localData.fullSearchDat.value >= pStackEntry->parameters.fullSearchPar.beta 
                && (!UseVerEndgame || do_ver(pStackEntry->parameters.fullSearchPar.board))) 
            {
              pStackEntry->localData.fullSearchDat.new_depth = pStackEntry->parameters.fullSearchPar.depth - VerReduction;
              ASSERT(pStackEntry->localData.fullSearchDat.new_depth > 0);

              ASSERT(g_Stack.nCount > 0);
              Stack_PushFullNoNull(/* pStack, */
                                   pStackEntry->parameters.fullSearchPar.board, 
                                   pStackEntry->parameters.fullSearchPar.alpha, 
                                   pStackEntry->parameters.fullSearchPar.beta, 
                                   pStackEntry->localData.fullSearchDat.new_depth, 
                                   pStackEntry->parameters.fullSearchPar.height, 
                                   pStackEntry->localData.fullSearchDat.new_pv, 
                                   NodeCut, 
                                   pStackEntry->localData.fullSearchDat.trans_move, 
                                   &pStackEntry->localData.fullSearchDat.move,
                                   false, // kh 03.06.08 Thomas Gaksch 14b5c
                                   RETURN_POSITION_FULL_SEARCH_03);
              goto L_CALL_FULL_SEARCH;

L_RETURN_POSITION_FULL_SEARCH_03:
              if(!pStackEntry->bIsAlive)
              {
                goto L_FULL_SEARCH_NO_LONGER_ALIVE;
              }

              pStackEntry->localData.fullSearchDat.value = pStackEntry->nResult;

              if((pStackEntry->localData.fullSearchDat.value >= pStackEntry->parameters.fullSearchPar.beta)) // kh 14.12.06 $cut...
              {
                ASSERT(pStackEntry->localData.fullSearchDat.move == pStackEntry->localData.fullSearchDat.new_pv[0]);
                pStackEntry->localData.fullSearchDat.played[pStackEntry->localData.fullSearchDat.played_nb++] = pStackEntry->localData.fullSearchDat.move;
                pStackEntry->localData.fullSearchDat.best_move                           = pStackEntry->localData.fullSearchDat.move;

                pStackEntry->localData.fullSearchDat.best_value                          = pStackEntry->localData.fullSearchDat.value;
                pv_copy(pStackEntry->parameters.fullSearchPar.ppv, pStackEntry->localData.fullSearchDat.new_pv);

                pStackEntry->bCutoff = true;
                goto cut_full_search;
              }
            } // if(    pStackEntry->localData.fullSearchDat.value >= pStackEntry->parameters.fullSearchPar.beta...
          } // if(UseVer && pStackEntry->parameters.fullSearchPar.depth > VerReduction)

          // pruning

// kh 03.06.08 Thomas Gaksch 14b5c
          if((pStackEntry->localData.fullSearchDat.value >= pStackEntry->parameters.fullSearchPar.beta)) // kh 14.12.06 $cut...
          {
            if(pStackEntry->localData.fullSearchDat.value > +ValueEvalInf) // do not return unproven mates
            {
              pStackEntry->localData.fullSearchDat.value = +ValueEvalInf; 
            }

// kh 23.05.08 pStackEntry->parameters.fullSearchPar.beta may have been potentially asynchronously lowered in between
//          ASSERT(!value_is_mate(pStackEntry->localData.fullSearchDat.value));

            // pv_cat(pStackEntry->parameters.fullSearchPar.pv, pStackEntry->localData.fullSearchDat.new_pv, MoveNull);

            pStackEntry->localData.fullSearchDat.best_move   = MoveNone;
            pStackEntry->localData.fullSearchDat.best_value  = pStackEntry->localData.fullSearchDat.value;

            pStackEntry->bCutoff = true;
            goto cut_full_search;

          } // if(pStackEntry->localData.fullSearchDat.value >= pStackEntry->parameters.fullSearchPar.beta)
        } // if(    !pStackEntry->localData.fullSearchDat.in_check...
      } // if(UseNull && pStackEntry->parameters.fullSearchPar.depth >= NullDepth && pStackEntry->parameters.fullSearchPar.node_type != NodePV) 

// kh/tg 26.02.08
// Razoring: 
      else if(    pStackEntry->parameters.fullSearchPar.node_type  != NodePV 
               && pStackEntry->parameters.fullSearchPar.depth      <= RazorDepth 

// kh 04.06.08 Thomas Gaksch 14b5c
               && eval(pStackEntry->parameters.fullSearchPar.board, 
                       pStackEntry->parameters.fullSearchPar.alpha, 
                       pStackEntry->parameters.fullSearchPar.beta) < pStackEntry->parameters.fullSearchPar.beta - RazorMargin)
      {
//      value = full_quiescence(board, alpha, beta, 0, height, pv, node_type == NodePV);

        Stack_PushFullQuiescence(/* pStack, */
                                 pStackEntry->parameters.fullSearchPar.board, 
                                 pStackEntry->parameters.fullSearchPar.alpha, 
                                 pStackEntry->parameters.fullSearchPar.beta, 
                                 0, 
                                 pStackEntry->parameters.fullSearchPar.height, 
                                 pStackEntry->parameters.fullSearchPar.ppv,
                                 RETURN_POSITION_FULL_SEARCH_03_1);
        goto L_CALL_FULL_SEARCH;

L_RETURN_POSITION_FULL_SEARCH_03_1:
        if(!pStackEntry->bIsAlive) // kh 26.02.08 defensive, performance
        {
          goto L_FULL_SEARCH_NO_LONGER_ALIVE;
        }

        pStackEntry->localData.fullSearchDat.value = pStackEntry->nResult;

        if(pStackEntry->localData.fullSearchDat.value < pStackEntry->parameters.fullSearchPar.beta)
        {
//	      return value;
//        pStackEntry->nResult = pStackEntry->localData.fullSearchDat.value; // kh 26.02.08 redundant here (see pStackEntry->localData.fullSearchDat.value = pStackEntry->nResult; above)
          goto L_RETURN_FULL_SEARCH;
        }
      } // else if(    pStackEntry->parameters.fullSearchPar.node_type != NodePV...

    // Internal Iterative Deepening

      if(    UseIID 
          && pStackEntry->parameters.fullSearchPar.depth      >= IIDDepth 
          && pStackEntry->parameters.fullSearchPar.node_type  == NodePV 
          && pStackEntry->localData.fullSearchDat.trans_move  == MoveNone) 
      {

// kh 11.04.07 Thomas Gaksch
        pStackEntry->localData.fullSearchDat.new_depth = MIN(pStackEntry->parameters.fullSearchPar.depth - IIDReduction, pStackEntry->parameters.fullSearchPar.depth / 2);

        ASSERT(pStackEntry->localData.fullSearchDat.new_depth > 0);

// kh 24.07.06 simulate recursive call
//      value = full_search(board, alpha, beta, new_depth, height, new_pv, node_type);
        ASSERT(g_Stack.nCount > 0);
        Stack_PushFullSearch(/* pStack, */
                             pStackEntry->parameters.fullSearchPar.board, 
                             pStackEntry->parameters.fullSearchPar.alpha, 
                             pStackEntry->parameters.fullSearchPar.beta, 
                             pStackEntry->localData.fullSearchDat.new_depth, 
                             pStackEntry->parameters.fullSearchPar.height, 
                             pStackEntry->localData.fullSearchDat.new_pv, 
                             pStackEntry->parameters.fullSearchPar.node_type,
                             false, // kh 03.06.08 Thomas Gaksch 14b5c
                             RETURN_POSITION_FULL_SEARCH_04);
        goto L_CALL_FULL_SEARCH;

L_RETURN_POSITION_FULL_SEARCH_04:
        if(!pStackEntry->bIsAlive)
        {
          goto L_FULL_SEARCH_NO_LONGER_ALIVE;
        }

        pStackEntry->localData.fullSearchDat.value = pStackEntry->nResult;

        if(pStackEntry->localData.fullSearchDat.value <= pStackEntry->parameters.fullSearchPar.alpha) 
        {

// kh 24.07.06 simulate recursive call
//        value = full_search(board, -ValueInf, beta, new_depth, height, new_pv, node_type);
          ASSERT(g_Stack.nCount > 0);
          Stack_PushFullSearch(/* pStack, */
                               pStackEntry->parameters.fullSearchPar.board, 
                               -ValueInf, 
                               pStackEntry->parameters.fullSearchPar.beta, 
                               pStackEntry->localData.fullSearchDat.new_depth, 
                               pStackEntry->parameters.fullSearchPar.height, 
                               pStackEntry->localData.fullSearchDat.new_pv, 
                               pStackEntry->parameters.fullSearchPar.node_type,
                               false, // kh 03.06.08 Thomas Gaksch 14b5c
                               RETURN_POSITION_FULL_SEARCH_05);
          goto L_CALL_FULL_SEARCH;

L_RETURN_POSITION_FULL_SEARCH_05:
          if(!pStackEntry->bIsAlive)
          {
            goto L_FULL_SEARCH_NO_LONGER_ALIVE;
          }

          pStackEntry->localData.fullSearchDat.value = pStackEntry->nResult;
        }

        pStackEntry->localData.fullSearchDat.trans_move = pStackEntry->localData.fullSearchDat.new_pv[0];
      } // if(    UseIID...

    // move generation

      sort_init(pStackEntry->localData.fullSearchDat.sort, 
                pStackEntry->parameters.fullSearchPar.board, 
                pStackEntry->localData.fullSearchDat.attack, 
                pStackEntry->parameters.fullSearchPar.depth, 
                pStackEntry->parameters.fullSearchPar.height, 
                pStackEntry->localData.fullSearchDat.trans_move);

      pStackEntry->localData.fullSearchDat.single_reply = false;
      if(pStackEntry->localData.fullSearchDat.in_check && LIST_SIZE(pStackEntry->localData.fullSearchDat.sort->list) == 1) // HACK
      {
        pStackEntry->localData.fullSearchDat.single_reply = true; 
      }

      // move loop

      pStackEntry->localData.fullSearchDat.opt_value  = +ValueInf;
      pStackEntry->localData.fullSearchDat.good_cap   = true;

// kh 07.09.06 start of standard real main search loop 
//    while((pStackEntry->localData.fullSearchDat.move = sort_next(pStackEntry->localData.fullSearchDat.sort)) != MoveNone) 
      pStackEntry->bMoveListBreak           = false;
      pStackEntry->nMoveListIndex           = 0;
      pStackEntry->nMoveListTotalCount      = 0;

#if DEBUG
      pStackEntry->nMemoMoveListTotalCount  = -1;
#endif

      pStackEntry->bIsAlive                 = true; // kh 07.09.06 asynchronous cutoff by a slave result is signaled

      if(g_pYBWCManagerInstance->pFruitConfiguration->bSuppressDistributionOfFullSearchMoves)
      {
      } // if(g_pYBWCManagerInstance->pFruitConfiguration->bSuppressDistributionOfRootMoves)
      else
      {
        pStackEntry->bTryToDistribute         = true; 
      }

      pStackEntry->bMoveListFullyGenerated  = false;

// kh 16.10.06 sort_next(... needs an access to the correct board state and is also accessed in 
// Stack_HasSendWorkToSlave(... trying to support the original lazy move list generation
// the board state is now accessible per stack level 

// kh 17.10.06 lazy move list generation is supported now, 
// generation once in advance is no longer necessary
/* 
      while((nTmpMove = sort_next(pStackEntry->localData.fullSearchDat.sort)) != MoveNone)
      {
        StackEntry_AddMove(pStackEntry, nTmpMove);
        pStackEntry->SortValueList[pStackEntry->nMoveListTotalCount - 1] = pStackEntry->localData.fullSearchDat.sort->value;
      }

      pStackEntry->bMoveListFullyGenerated = true;
*/

// kh 16.10.06 lazy move list generation is now supported (see below)
      while(pStackEntry->bIsAlive && !pStackEntry->bMoveListBreak) 
      {
        if(pStackEntry->nMoveListIndex < pStackEntry->nMoveListTotalCount)
        {

// kh 07.09.06 there is a least the next move in the list (buffered) available, 
// already created while searching the stack for work in the meantime
          pStackEntry->localData.fullSearchDat.move = pStackEntry->MoveList[pStackEntry->nMoveListIndex];

        }
        else if(pStackEntry->bMoveListFullyGenerated) // kh 07.09.06 bMoveListFullyGenerated may have been already set while searching the stack for work in the meantime
        {
          pStackEntry->bMoveListBreak = true;
        }
        else if(LAZY_MOVE_LIST_GENERATION_NOT_SUPPORTED)// kh 17.10.06 actual false, lazy move list generation is supported
        {
          if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_ERROR_PRIO_1)
          {
            YBWCManager_Printf(g_pYBWCManagerInstance, "ERROR fullSearch(... failed at pStackEntry->MoveList[pStackEntry->nMoveListIndex] access, move list was not fully generated in advance\n");
          }
          pStackEntry->bMoveListBreak = true; // kh 16.10.06 defensive (will probably not help any more...)
          ASSERT(false); 
        }

//kh 03.06.08 Thomas Gaksch 14b5c
        else if((pStackEntry->localData.fullSearchDat.move = sort_next(pStackEntry->localData.fullSearchDat.sort)) != MoveNone)
        {
          ASSERT(pStackEntry->nMoveListIndex == pStackEntry->nMoveListTotalCount);

          StackEntry_AddMove(pStackEntry, pStackEntry->localData.fullSearchDat.move);
          pStackEntry->SortValueList[pStackEntry->nMoveListTotalCount - 1] = pStackEntry->localData.fullSearchDat.sort->value;

#if DEBUG
          pStackEntry->nMemoMoveListTotalCount = pStackEntry->nMoveListTotalCount;
#endif
        }
        else
        {

// kh 07.09.06 bMoveListFullyGenerated is potentially also set while searching the stack for work in the meantime
          pStackEntry->bMoveListFullyGenerated = true; // kh 07.09.06 defensive
          pStackEntry->bMoveListBreak          = true;

#if DEBUG
          pStackEntry->nMemoMoveListTotalCount = pStackEntry->nMoveListTotalCount;
#endif
        }

        // extensions

        if(pStackEntry->bMoveListBreak)
        {

          // kh 07.09.06 move list access completed for all moves, 
          // all moves have been either locally searched or are distributed (and the remote search may not be completed yet)

        } // if(pStackEntry->bMoveListBreak)
        else
        {
          if(    (pStackEntry->SlaveList    [pStackEntry->nMoveListIndex] > 0) // kh 07.09.06 a slave is searching for this move
              ||  pStackEntry->CompletedList[pStackEntry->nMoveListIndex]      // kh 07.09.06 a slave has already completed the search for this move 
            )
          {

            // kh 07.09.06 skip

          } // if(    (pStackEntry->SlaveList    [pStackEntry->nMoveListIndex] > 0)...
          else
          {
            pStackEntry->CompletedList[pStackEntry->nMoveListIndex] = true; // kh 07.09.06 this move will now be searched locally

#if DEBUG
// kh 30.03.07 memo start count (negative, defensive)
            pStackEntry->NodesList[pStackEntry->nMoveListIndex] = -SearchCurrent->node_nb;
#endif

// kh 03.06.08 Thomas Gaksch 14b5c
            pStackEntry->localData.fullSearchDat.new_depth = full_new_depth(pStackEntry->parameters.fullSearchPar.depth, 
                                                                            pStackEntry->localData.fullSearchDat.move, 
                                                                            pStackEntry->parameters.fullSearchPar.board, 
                                                                            pStackEntry->localData.fullSearchDat.single_reply, 
                                                                            pStackEntry->parameters.fullSearchPar.node_type == NodePV,  
                                                                            pStackEntry->parameters.fullSearchPar.height,
                                                                            pStackEntry->parameters.fullSearchPar.extended,
                                                                            &pStackEntry->localData.fullSearchDat.cap_extended);

            // history pruning part a 

// kh 11.04.07 start Thomas Gaksch
// kh 11.04.07 lazy move list generation is now supported (see comment from 16.10.06 above)
// therefore the pStackEntry->localData.fullSearchDat.sort->value is additionally buffered 
/*
            pStackEntry->localData.fullSearchDat.value = pStackEntry->localData.fullSearchDat.sort->value; // history score
*/

// kh 11.04.07 try it a little bit more dynamic? ok, do it, if the move has an initial sort value an update is allowed
            if(g_pYBWCManagerInstance->nSize <= 1)
            {

// kh 05.05.08 more dynamic not needed (minor optimization for the single processor version)
              pStackEntry->localData.fullSearchDat.value = pStackEntry->localData.fullSearchDat.sort->value; // history score
            } 
            else
            {

// kh 11.04.07 try it a little bit more dynamic?
              pStackEntry->localData.fullSearchDat.value = pStackEntry->SortValueList[pStackEntry->nMoveListIndex];
              if(pStackEntry->localData.fullSearchDat.value < 16384) 
              {

// kh 04.06.08 Thomas Gaksch 14b5c
                pStackEntry->localData.fullSearchDat.value = history_prob(pStackEntry->localData.fullSearchDat.move, pStackEntry->parameters.fullSearchPar.board);
              }
            }

// kh 30.05.08 for a test only
/*
            if(pStackEntry->bHasAnySubWork)
            {
              nTmpPlayed = pStackEntry->localData.fullSearchDat.played_nb + 1;
            }
            else
            {
              nTmpPlayed = pStackEntry->localData.fullSearchDat.played_nb;
            }
*/

// kh 03.06.08 Thomas Gaksch 14b5c
            if(    UseHistoryPruning
                && !pStackEntry->localData.fullSearchDat.in_check 
                && pStackEntry->parameters.fullSearchPar.depth      <= 6 /*SearchCurrent->act_iteration / 2*/ 
			          && pStackEntry->parameters.fullSearchPar.node_type  != NodePV 
                && pStackEntry->localData.fullSearchDat.new_depth   <  pStackEntry->parameters.fullSearchPar.depth 
                && pStackEntry->localData.fullSearchDat.value       <  HistoryValue / (pStackEntry->parameters.fullSearchPar.depth / 3 + 1) /*2*/
			          && pStackEntry->localData.fullSearchDat.played_nb   >= 1+/*sort->capture_nb*/+pStackEntry->parameters.fullSearchPar.depth
//              && nTmpPlayed                                       >= 1+/*sort->capture_nb*/+pStackEntry->parameters.fullSearchPar.depth
    	          && !move_is_dangerous(pStackEntry->localData.fullSearchDat.move, 
                                      pStackEntry->parameters.fullSearchPar.board) 
              )
            { 

			        //history_reset(move,board);

// kh 11.04.07 pStackEntry->nMoveListIndex++ is necessary now, so continue must not be used any more
//            continue;
              goto L_FULL_SEARCH_END_WHILE;

            } // if(    UseHistoryPruning...

            // futility pruning

// kh 03.06.08 Thomas Gaksch 14b5c
            if(    UseFutility 
                && pStackEntry->parameters.fullSearchPar.node_type != NodePV 
                && pStackEntry->parameters.fullSearchPar.depth <= 3)
            {
              if(    !pStackEntry->localData.fullSearchDat.in_check 

// kh 11.04.07 Thomas Gaksch
                  && pStackEntry->localData.fullSearchDat.new_depth < pStackEntry->parameters.fullSearchPar.depth 
                  && !move_is_tactical (pStackEntry->localData.fullSearchDat.move, pStackEntry->parameters.fullSearchPar.board)
                  && !move_is_dangerous(pStackEntry->localData.fullSearchDat.move, pStackEntry->parameters.fullSearchPar.board)
                )

              {

// kh 04.06.08 assertion does not hold any longer for toga 14b5c
//              ASSERT(!move_is_check(pStackEntry->localData.fullSearchDat.move, pStackEntry->parameters.fullSearchPar.board));

                // optimistic evaluation

                if(pStackEntry->localData.fullSearchDat.opt_value == +ValueInf) 
                {

// kh 03.06.08 Thomas Gaksch 14b5c
				          if(pStackEntry->parameters.fullSearchPar.depth >= 2)
                  {
					          FutilityMargin = FutilityMargin2 + ((pStackEntry->parameters.fullSearchPar.depth - 2) * 50);
				          }
				          else
                  {
					          FutilityMargin = FutilityMargin1;
				          }

                  pStackEntry->localData.fullSearchDat.opt_value = eval(pStackEntry->parameters.fullSearchPar.board, 
                                                                        pStackEntry->parameters.fullSearchPar.alpha, 
                                                                        pStackEntry->parameters.fullSearchPar.beta) + FutilityMargin;

                  ASSERT(pStackEntry->localData.fullSearchDat.opt_value < +ValueInf);
                }

                pStackEntry->localData.fullSearchDat.value = pStackEntry->localData.fullSearchDat.opt_value;

                // pruning

                if(pStackEntry->localData.fullSearchDat.value <= pStackEntry->parameters.fullSearchPar.alpha) 
                {
                  if(pStackEntry->localData.fullSearchDat.value > pStackEntry->localData.fullSearchDat.best_value)
                  {
                    pStackEntry->localData.fullSearchDat.best_value = pStackEntry->localData.fullSearchDat.value;
                    PV_CLEAR(pStackEntry->parameters.fullSearchPar.ppv);
                  }

// kh 22.12.06 pStackEntry->nMoveListIndex++ is necessary now, so continue must not be used any more
//                continue;
                  goto L_FULL_SEARCH_END_WHILE;
                }
              } // if(    !pStackEntry->localData.fullSearchDat.in_check...
            } // if(    UseFutility...

            // history pruning part b

// kh 03.06.08 Thomas Gaksch 14b5c
            pStackEntry->localData.fullSearchDat.reduced = false;

// kh 11.04.07 start Thomas Gaksch
            if(UseHistory)
            {

// kh 30.05.08 for a test only
/*
              if(pStackEntry->bHasAnySubWork)
              {
                nTmpPlayed = pStackEntry->localData.fullSearchDat.played_nb + 1;
              }
              else
              {
                nTmpPlayed = pStackEntry->localData.fullSearchDat.played_nb;
              }
*/

// kh 03.06.08 start Thomas Gaksch 14b5c
              if(    !pStackEntry->localData.fullSearchDat.in_check 
                  && pStackEntry->localData.fullSearchDat.new_depth < pStackEntry->parameters.fullSearchPar.depth
                  && pStackEntry->localData.fullSearchDat.played_nb >= HistoryMoveNb 
//                && nTmpPlayed                                     >= HistoryMoveNb 
				          && pStackEntry->parameters.fullSearchPar.depth    >= HistoryDepth 
                  && !move_is_dangerous(pStackEntry->localData.fullSearchDat.move, pStackEntry->parameters.fullSearchPar.board)
                )
              {
					      if(    pStackEntry->localData.fullSearchDat.good_cap 
                    && !move_is_tactical(pStackEntry->localData.fullSearchDat.move, pStackEntry->parameters.fullSearchPar.board))
                {
						      pStackEntry->localData.fullSearchDat.good_cap = false;
					      }

					      if(!pStackEntry->localData.fullSearchDat.good_cap)
                {
						      if(pStackEntry->parameters.fullSearchPar.node_type != NodePV)
                  {
							      pStackEntry->localData.fullSearchDat.new_depth--;
							      pStackEntry->localData.fullSearchDat.reduced = true;
						      } // if(pStackEntry->parameters.fullSearchPar.node_type != NodePV)
						      else
                  {
							      if(pStackEntry->localData.fullSearchDat.played_nb >= HistoryMoveNb + 3)
                    {
							        pStackEntry->localData.fullSearchDat.new_depth--;
							        pStackEntry->localData.fullSearchDat.reduced = true;
							      }
						      } // !if(pStackEntry->parameters.fullSearchPar.node_type != NodePV)
			          } // if(!pStackEntry->localData.fullSearchDat.good_cap)
              } // if(    !pStackEntry->localData.fullSearchDat.in_check...
            } // if(UseHistory)
// kh 03.06.08 end Thomas Gaksch 14b5c

            // recursive search

            move_do(pStackEntry->parameters.fullSearchPar.board, pStackEntry->localData.fullSearchDat.move, pStackEntry->localData.fullSearchDat.undo);

// kh 30.10.06 if bIsAlive state has changed to false above this statement is not reachable for this actual stack entry CALL_TYPE_FULL_SEARCH
            ASSERT(pStackEntry->bIsAlive); 

            if(    pStackEntry->parameters.fullSearchPar.node_type != NodePV
                || pStackEntry->localData.fullSearchDat.best_value == ValueNone) // first move
            {

// kh 24.07.06 simulate recursive call
//            value = -full_search(board, -beta, -alpha, new_depth, height + 1, new_pv, NODE_OPP(node_type));
              ASSERT(g_Stack.nCount > 0);
              Stack_PushFullSearch(/* pStack, */
                                   pStackEntry->parameters.fullSearchPar.board, 
                                   -pStackEntry->parameters.fullSearchPar.beta, 
                                   -pStackEntry->parameters.fullSearchPar.alpha, 
                                   pStackEntry->localData.fullSearchDat.new_depth, 
                                   pStackEntry->parameters.fullSearchPar.height + 1, 
                                   pStackEntry->localData.fullSearchDat.new_pv,
                                   NODE_OPP(pStackEntry->parameters.fullSearchPar.node_type),
                                   pStackEntry->localData.fullSearchDat.cap_extended, // kh 03.06.08 Thomas Gaksch 14b5c
                                   RETURN_POSITION_FULL_SEARCH_06);
              goto L_CALL_FULL_SEARCH;

L_RETURN_POSITION_FULL_SEARCH_06:
              if(!pStackEntry->bIsAlive)
              {
                goto L_FULL_SEARCH_NO_LONGER_ALIVE_UNWIND_MOVE;
              }

              pStackEntry->localData.fullSearchDat.value = -pStackEntry->nResult;

            } // if(    pStackEntry->parameters.fullSearchPar.node_type != NodePV...
            else // other moves
            {

// kh 24.07.06 simulate recursive call
//            value = -full_search(board, -alpha - 1, -alpha, new_depth, height + 1, new_pv, NodeCut);
              ASSERT(g_Stack.nCount > 0);
              Stack_PushFullSearch(/* pStack, */
                                   pStackEntry->parameters.fullSearchPar.board, 
                                   -pStackEntry->parameters.fullSearchPar.alpha - 1, 
                                   -pStackEntry->parameters.fullSearchPar.alpha, 
                                   pStackEntry->localData.fullSearchDat.new_depth, 
                                   pStackEntry->parameters.fullSearchPar.height + 1, 
                                   pStackEntry->localData.fullSearchDat.new_pv, 
                                   NodeCut,
                                   pStackEntry->localData.fullSearchDat.cap_extended, // kh 03.06.08 Thomas Gaksch 14b5c
                                   RETURN_POSITION_FULL_SEARCH_07);
              goto L_CALL_FULL_SEARCH;

L_RETURN_POSITION_FULL_SEARCH_07:
              if(!pStackEntry->bIsAlive)
              {
                goto L_FULL_SEARCH_NO_LONGER_ALIVE_UNWIND_MOVE;
              }

              pStackEntry->localData.fullSearchDat.value = -pStackEntry->nResult;

              if(pStackEntry->localData.fullSearchDat.value > pStackEntry->parameters.fullSearchPar.alpha) // && value < beta
              {

// kh 24.07.06 simulate recursive call
//              value = -full_search(board, -beta, -alpha, new_depth, height + 1, new_pv, NodePV);
                ASSERT(g_Stack.nCount > 0);
                Stack_PushFullSearch(/* pStack, */
                                     pStackEntry->parameters.fullSearchPar.board, 
                                     -pStackEntry->parameters.fullSearchPar.beta, 
                                     -pStackEntry->parameters.fullSearchPar.alpha, 
                                     pStackEntry->localData.fullSearchDat.new_depth, 
                                     pStackEntry->parameters.fullSearchPar.height + 1, 
                                     pStackEntry->localData.fullSearchDat.new_pv, 
                                     NodePV,
                                     pStackEntry->localData.fullSearchDat.cap_extended, // kh 03.06.08 Thomas Gaksch 14b5c
                                     RETURN_POSITION_FULL_SEARCH_08);
                goto L_CALL_FULL_SEARCH;

L_RETURN_POSITION_FULL_SEARCH_08:
                if(!pStackEntry->bIsAlive)
                {
                  goto L_FULL_SEARCH_NO_LONGER_ALIVE_UNWIND_MOVE;
                }

                pStackEntry->localData.fullSearchDat.value = -pStackEntry->nResult;

              } // if(pStackEntry->localData.fullSearchDat.value > pStackEntry->parameters.fullSearchPar.alpha)
            } // !if(    pStackEntry->parameters.fullSearchPar.node_type != NodePV...

            // history-pruning re-search

// kh 03.06.08 end Thomas Gaksch 14b5c
            if(HistoryReSearch && pStackEntry->localData.fullSearchDat.reduced && pStackEntry->localData.fullSearchDat.value >= pStackEntry->parameters.fullSearchPar.beta) 
            {

// kh 12.04.07 assertion does not hold any longer for toga
//            ASSERT(pStackEntry->parameters.fullSearchPar.node_type != NodePV);

              pStackEntry->localData.fullSearchDat.new_depth++;
              ASSERT(pStackEntry->localData.fullSearchDat.new_depth == pStackEntry->parameters.fullSearchPar.depth - 1);

// kh 24.07.06 simulate recursive call
//            value = -full_search(board, -beta, -alpha, new_depth, height + 1, new_pv, NODE_OPP(node_type));
              ASSERT(g_Stack.nCount > 0);
              Stack_PushFullSearch(/* pStack, */
                                   pStackEntry->parameters.fullSearchPar.board, 
                                   -pStackEntry->parameters.fullSearchPar.beta, 
                                   -pStackEntry->parameters.fullSearchPar.alpha, 
                                   pStackEntry->localData.fullSearchDat.new_depth, 
                                   pStackEntry->parameters.fullSearchPar.height + 1, 
                                   pStackEntry->localData.fullSearchDat.new_pv, 
                                   NODE_OPP(pStackEntry->parameters.fullSearchPar.node_type),
                                   pStackEntry->localData.fullSearchDat.cap_extended, // kh 03.06.08 Thomas Gaksch 14b5c
                                   RETURN_POSITION_FULL_SEARCH_09);
              goto L_CALL_FULL_SEARCH;

L_RETURN_POSITION_FULL_SEARCH_09:
              if(!pStackEntry->bIsAlive)
              {
                goto L_FULL_SEARCH_NO_LONGER_ALIVE_UNWIND_MOVE;
              }

              pStackEntry->localData.fullSearchDat.value = -pStackEntry->nResult;

            } // if(HistoryReSearch && pStackEntry->localData.fullSearchDat.reduced && pStackEntry->localData.fullSearchDat.value > pStackEntry->parameters.fullSearchPar.alpha) /* was >= beta */

L_FULL_SEARCH_NO_LONGER_ALIVE_UNWIND_MOVE:
            move_undo(pStackEntry->parameters.fullSearchPar.board, pStackEntry->localData.fullSearchDat.move, pStackEntry->localData.fullSearchDat.undo);

#if DEBUG
// kh 30.03.07 calc nodes count as difference to the memo start count (negative, defensive)
            pStackEntry->NodesList[pStackEntry->nMoveListIndex] = 
                SearchCurrent->node_nb 
              + pStackEntry->NodesList[pStackEntry->nMoveListIndex];
#endif

            if(!pStackEntry->bIsAlive)
            {
              goto L_FULL_SEARCH_NO_LONGER_ALIVE;
            }

// kh 27.10.06 the tests below are also done for a slave result received 
// but in case of a cut bIsAlive - up to the actual top stack level - is set to false
            pStackEntry->localData.fullSearchDat.played[pStackEntry->localData.fullSearchDat.played_nb++] = pStackEntry->localData.fullSearchDat.move;

            if(pStackEntry->localData.fullSearchDat.value > pStackEntry->localData.fullSearchDat.best_value) 
            {
              pStackEntry->localData.fullSearchDat.best_value = pStackEntry->localData.fullSearchDat.value;
              pv_cat(pStackEntry->parameters.fullSearchPar.ppv, pStackEntry->localData.fullSearchDat.new_pv, pStackEntry->localData.fullSearchDat.move);
              if(pStackEntry->localData.fullSearchDat.value > pStackEntry->parameters.fullSearchPar.alpha) 
              {
                pStackEntry->parameters.fullSearchPar.alpha    = pStackEntry->localData.fullSearchDat.value;
                pStackEntry->localData.fullSearchDat.best_move = pStackEntry->localData.fullSearchDat.move;

                if((pStackEntry->localData.fullSearchDat.value >= pStackEntry->parameters.fullSearchPar.beta)) // kh 14.12.06 $cut...
                {
                  pStackEntry->bCutoff = true;
                  goto cut_full_search;
                } // if(pStackEntry->localData.fullSearchDat.value >= pStackEntry->parameters.fullSearchPar.beta)
                else
                {
                  if(g_pYBWCManagerInstance->pFruitConfiguration->bUpdateSearchWindows)
                  {

// kh 09.11.06 update the search windows for all processors for the stack entry
                    nTmpUpdateSearchWindowResult = Stack_UpdateSearchWindowForEntry(/* g_pYBWCManagerInstance->pStack, */
                                                                                    pStackEntry,
                                                                                    pStackEntry->localData.fullSearchDat.value,
                                                                                    pStackEntry->parameters.fullSearchPar.beta);
                    if(nTmpUpdateSearchWindowResult == MPI_SUCCESS)
                    {
                    }
                    else
                    {
                      if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_ERROR_PRIO_1)
                      {
                        YBWCManager_Printf(g_pYBWCManagerInstance, "ERROR fullSearch(... failed at Stack_UpdateSearchWindowForEntry(..., errorcode = %d\n", nTmpUpdateSearchWindowResult);
                      }
                    }
                  } // if(pThis->pFruitConfiguration->bUpdateSearchWindows)
                } // !if(pStackEntry->localData.fullSearchDat.value >= pStackEntry->parameters.fullSearchPar.beta)
              } // if(pStackEntry->localData.fullSearchDat.value > pStackEntry->parameters.fullSearchPar.alpha)
            } // if(pStackEntry->localData.fullSearchDat.value > pStackEntry->localData.fullSearchDat.best_value)

            if(pStackEntry->parameters.fullSearchPar.node_type == NodeCut)
            {
              pStackEntry->parameters.fullSearchPar.node_type = NodeAll;
            }
          } // !if(    (pStackEntry->SlaveList    [pStackEntry->nMoveListIndex] > 0)...
        } // !if(pStackEntry->bMoveListBreak)

L_FULL_SEARCH_END_WHILE:

        pStackEntry->nMoveListIndex++;

//    } // while((pStackEntry->localData.fullSearchDat.move = sort_next(pStackEntry->localData.fullSearchDat.sort)) != MoveNone)
      } // while(pStackEntry->bIsAlive && !pStackEntry->bMoveListBreak) 

// kh 18.03.07 pStackEntry->nMoveListTotalCount change is expected here due to asynchronous work requests 
/*
#if DEBUG
      if(pStackEntry->nMemoMoveListTotalCount == pStackEntry->nMoveListTotalCount)
      {
      }
      else
      {
        if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_ERROR_PRIO_1)
        {
          if(pStackEntry->bMoveListFullyGenerated)
          {
            YBWCManager_Printf(g_pYBWCManagerInstance, 
                               "ERROR fullSearch(... (full search 1) nMoveListTotalCount changed from %d to %d (fully generated)\n",
                               pStackEntry->nMemoMoveListTotalCount,
                               pStackEntry->nMoveListTotalCount);
          }
          else
          {
            YBWCManager_Printf(g_pYBWCManagerInstance, 
                               "ERROR fullSearch(... (full search 1) nMoveListTotalCount changed from %d to %d (partially generated)\n",
                               pStackEntry->nMemoMoveListTotalCount,
                               pStackEntry->nMoveListTotalCount);
          }
        }
      }
#endif
*/

L_FULL_SEARCH_NO_LONGER_ALIVE:
      bTmpFirst = true;
      if(g_pYBWCManagerInstance->pFruitConfiguration->nDebugWaitForSlaveRate > 0)
      {
        CountdownTimer_Restart(g_pYBWCManagerInstance->pCountdownTimerDebugWaitForSlave);
      }

#if DEBUG
      pStackEntry->nMemoMoveListTotalCount = pStackEntry->nMoveListTotalCount;
#endif

      if(pStackEntry->bHasAnySubWork) // kh 22.10.07 quick check for potential subwork (performance)
      {
        bTmpBreak = false;
        while(pStackEntry->bIsAlive && !bTmpBreak) 
        {
          nTmpIndex = 0;
          while((nTmpIndex < pStackEntry->nMoveListTotalCount) && !bTmpBreak) 
          {
//          YBWCManager_ServiceMessages(g_pYBWCManagerInstance); // kh 18.03.07 tuning 

            if(pStackEntry->CompletedList[nTmpIndex])
            {
            }
            else
            {
              bTmpBreak = true;
            }

            nTmpIndex++;
          } // while((nTmpIndex < pStackEntry->nMoveListTotalCount) && !bTmpBreak)

          if(bTmpBreak)
          {

            bTmpBreak = false;

// kh 07.09.06 waiting for at least one slave result is required
            if(g_pYBWCManagerInstance->pFruitConfiguration->nDebugWaitForSlaveRate > 0)
            {
              if(CountdownTimer_IsRunning(g_pYBWCManagerInstance->pCountdownTimerDebugWaitForSlave))
              {
              }
              else
              {
                if(bTmpFirst)
                {
                  g_pYBWCManagerInstance->nDebugWaitId++;
                  bTmpFirst = false;
                }
                for(nTmpIndex2 = 0; nTmpIndex2 < pStackEntry->nMoveListTotalCount; nTmpIndex2++) 
                {
                  if(pStackEntry->CompletedList[nTmpIndex2])
                  {
                  }
                  else
                  {
                    if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_ERROR_PRIO_1)
                    {

#if DEBUG
                      move_to_string(pStackEntry->MoveList[nTmpIndex2], sTmpMoveString, 256);
                      YBWCManager_Printf(g_pYBWCManagerInstance, 
//                                       "waiting (wait id "S64_FORMAT") StackIndex %d MoveNumber %d/%d Move %s (%d) WorkId " S64_FORMAT " at full search depth %d/%d nodes " S64_FORMAT " localnodes " S64_FORMAT " on slave %d\n", 
                                         "waiting for %d (wait id "S64_FORMAT") StackIndex %d Move %d/%d %s (%d) WorkId " S64_FORMAT " at full search height/depth %d+%d/%d initial a=%d b=%d, last a=%d b=%d, work a=%d b=%d nodes " S64_FORMAT " local " S64_FORMAT "\n", 
                                         pStackEntry->SlaveList[nTmpIndex2],
                                         g_pYBWCManagerInstance->nDebugWaitId,
                                         g_Stack.nCount - 1,
                                         nTmpIndex2 + 1,
                                         pStackEntry->nMoveListTotalCount,
                                         sTmpMoveString,
                                         pStackEntry->MoveList[nTmpIndex2],
                                         pStackEntry->WorkIdList[nTmpIndex2],
                                         SearchInfo->nHeightOffset, // kh 19.03.07 nTmpHeightOffset,
                                         pStackEntry->parameters.fullSearchPar.height,
                                         pStackEntry->parameters.fullSearchPar.depth,
                                         pStackEntry->nAlphaParameterOnEntry,
                                         pStackEntry->nBetaParameterOnEntry,
                                         pStackEntry->parameters.fullSearchPar.alpha,
                                         pStackEntry->parameters.fullSearchPar.beta,
                                         pStackEntry->AlphaList[nTmpIndex2],
                                         pStackEntry->BetaList[nTmpIndex2],

                                         SearchCurrent->node_nb,
                                         SearchCurrent->node_local_nb);
#endif
                    }
                  }
                }
                CountdownTimer_Restart(g_pYBWCManagerInstance->pCountdownTimerDebugWaitForSlave);
              }
            }

            YBWCManager_ServiceMessages(g_pYBWCManagerInstance);

#if DEBUG
            if(pStackEntry->nMemoMoveListTotalCount == pStackEntry->nMoveListTotalCount)
            {
            } // if(pStackEntry->nMemoMoveListTotalCount == pStackEntry->nMoveListTotalCount)
            else
            {
              if(pStackEntry->bMoveListFullyGenerated)
              {
                if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_ERROR_PRIO_1)
                {
                  YBWCManager_Printf(g_pYBWCManagerInstance, 
                                     "ERROR fullSearch(... (full search 2) nMoveListTotalCount changed from %d to %d (fully generated)\n",
                                     pStackEntry->nMemoMoveListTotalCount,
                                     pStackEntry->nMoveListTotalCount);
                }
              }
              else
              {
                if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_ERROR_PRIO_1)
                {
                  YBWCManager_Printf(g_pYBWCManagerInstance, 
                                     "ERROR fullSearch(... (full search 2) nMoveListTotalCount changed from %d to %d (partially generated)\n",
                                     pStackEntry->nMemoMoveListTotalCount,
                                     pStackEntry->nMoveListTotalCount);
                }
              }
            } // !if(pStackEntry->nMemoMoveListTotalCount == pStackEntry->nMoveListTotalCount)
#endif

// kh 25.12.06 do this for all master now too (not only the root master (see above)),
// to handle a stop received (not only (indirectly) from the gui) fast
            search_check();

/*
// kh 07.12.06 should make stopping faster
            if(g_pYBWCManagerInstance->bStoppingActive)
            {
              search_check();
            } // if(g_pYBWCManagerInstance->bStoppingActive)
*/
          } // if(bTmpBreak)
          else
          {
            bTmpBreak = true;
          } // !if(bTmpBreak)
        } // while(pStackEntry->bIsAlive && !bTmpBreak) 
      } // if(pStackEntry->bHasAnySubWork)
      else
      {
        // kh 22.10.07 no actions are required if there is not any potential subwork (performance)
      } // !if(pStackEntry->bHasAnySubWork)

      if(pStackEntry->bIsAlive)
      {
      }
      else
      {
        goto cut_full_search; // kh 07.09.06 use a goto here, following the standard Fruit programming style 
      }

    // ALL node

      if(pStackEntry->localData.fullSearchDat.best_value == ValueNone) // no legal move
      {
        if(pStackEntry->localData.fullSearchDat.in_check) 
        {
          ASSERT(board_is_mate(pStackEntry->parameters.fullSearchPar.board));

// kh 24.07.06
//        return VALUE_MATE(height);
          pStackEntry->nResult = VALUE_MATE(pStackEntry->parameters.fullSearchPar.height + SearchInfo->nHeightOffset);
          goto L_RETURN_FULL_SEARCH;

        } // if(pStackEntry->localData.fullSearchDat.in_check) 
        else 
        {
          ASSERT(board_is_stalemate(pStackEntry->parameters.fullSearchPar.board));

// kh 24.07.06
//        return ValueDraw;
          pStackEntry->nResult = ValueDraw;
          goto L_RETURN_FULL_SEARCH;
        } // !if(pStackEntry->localData.fullSearchDat.in_check) 
      } // if(pStackEntry->localData.fullSearchDat.best_value == ValueNone)

cut_full_search:
      ASSERT(value_is_ok(pStackEntry->localData.fullSearchDat.best_value) || !pStackEntry->bIsAlive);

// kh 20.09.06 stop searching on all processors for the stack entry
// stop may be broadcasted here as a "forced stop" as 
// a future expansion to all appropriate slaves for a better performance

      nStopResult = Stack_StopEntry(/* g_pYBWCManagerInstance->pStack, */ pStackEntry);
      if(nStopResult == MPI_SUCCESS)
      {
      }
      else
      {
        if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_ERROR_PRIO_1)
        {
          YBWCManager_Printf(g_pYBWCManagerInstance, "ERROR fullSearch(... failed at Stack_StopEntry(..., errorcode = %d\n", nStopResult);
        }
      }

      // move ordering

// kh 30.10.06 may be optimized as a future expansion by trying to get some useful (partial) information 
// if an intermediate node (i.e. not the node with the slave result itself) is no longer alive
      if(pStackEntry->bIsAlive || pStackEntry->bSlaveCutoffLevel)
      {
        if(pStackEntry->localData.fullSearchDat.best_move != MoveNone) 
        {
          if(g_pYBWCManagerInstance->pFruitConfiguration->bForceReproducibleEvaluation)
          {
          }
          else
          {

// kh 27.10.06 fruit original statement
            good_move(pStackEntry->localData.fullSearchDat.best_move, pStackEntry->parameters.fullSearchPar.board, pStackEntry->parameters.fullSearchPar.depth, pStackEntry->parameters.fullSearchPar.height);
          }

// kh 22.05.08 pStackEntry->parameters.fullSearchPar.beta may have been potentially asynchronously lowered in between
          if(    (pStackEntry->bCutoff || pStackEntry->bSlaveCutoffLevel)
//        if(    pStackEntry->localData.fullSearchDat.best_value >= pStackEntry->parameters.fullSearchPar.beta 
              && !move_is_tactical(pStackEntry->localData.fullSearchDat.best_move, pStackEntry->parameters.fullSearchPar.board)) 
          {

            ASSERT(pStackEntry->localData.fullSearchDat.played_nb > 0);
            ASSERT(pStackEntry->localData.fullSearchDat.played[pStackEntry->localData.fullSearchDat.played_nb - 1] == pStackEntry->localData.fullSearchDat.best_move);

            for(pStackEntry->localData.fullSearchDat.i = 0; pStackEntry->localData.fullSearchDat.i < pStackEntry->localData.fullSearchDat.played_nb - 1; pStackEntry->localData.fullSearchDat.i++) 
            {
              pStackEntry->localData.fullSearchDat.move = pStackEntry->localData.fullSearchDat.played[pStackEntry->localData.fullSearchDat.i];
              ASSERT(pStackEntry->localData.fullSearchDat.move != pStackEntry->localData.fullSearchDat.best_move);
              if(g_pYBWCManagerInstance->pFruitConfiguration->bForceReproducibleEvaluation)
              {
              }
              else
              {

// kh 04.06.08 Thomas Gaksch 14b5c
                history_bad(pStackEntry->localData.fullSearchDat.move, pStackEntry->parameters.fullSearchPar.board); 
              }
            }

            if(g_pYBWCManagerInstance->pFruitConfiguration->bForceReproducibleEvaluation)
            {
            }
            else
            {

// kh 04.06.08 Thomas Gaksch 14b5c
              history_good(pStackEntry->localData.fullSearchDat.best_move, pStackEntry->parameters.fullSearchPar.board); 
            }
          } // if(    pStackEntry->localData.fullSearchDat.best_value >= pStackEntry->parameters.fullSearchPar.beta...
        } // if(pStackEntry->localData.fullSearchDat.best_move != MoveNone) 

        // transposition table

// kh 02.06.08 start Thomas Gaksch 14b5c
        if(UseTrans && pStackEntry->parameters.fullSearchPar.depth >= TransDepth)
        {
          pStackEntry->localData.fullSearchDat.trans_move      = pStackEntry->localData.fullSearchDat.best_move;
          pStackEntry->localData.fullSearchDat.trans_depth     = pStackEntry->parameters.fullSearchPar.depth;

          pStackEntry->localData.fullSearchDat.trans_flags      = TransUnknown;

          if(pStackEntry->localData.fullSearchDat.best_value > pStackEntry->localData.fullSearchDat.old_alpha) 
          {
            pStackEntry->localData.fullSearchDat.trans_flags |= TransLower;
          }

          if(pStackEntry->localData.fullSearchDat.best_value < pStackEntry->parameters.fullSearchPar.beta) 
          {
            pStackEntry->localData.fullSearchDat.trans_flags |= TransUpper;
          }

// kh 16.03.07 adjust by SearchInfo->nHeightOffset here now
          pStackEntry->localData.fullSearchDat.trans_value = 
            value_to_trans(pStackEntry->localData.fullSearchDat.best_value,
                           pStackEntry->parameters.fullSearchPar.height + SearchInfo->nHeightOffset);

// kh 21.03.07 future expansion: suppress trans_store if a shared memory transpositon table is used
// and the result is from a slave sharing the transposition table (i.e. he had already stored that entry)
/*
          if(    pStackEntry->bSlaveCutoffLevel 
              && pThis->pFruitConfiguration->bUseSharedMemoryTranspositionTable
              && (pThis->nHashTableGroupId == pStackEntry->nSlaveGroupId)
          {
*/
            trans_store(Trans, 
                        pStackEntry->parameters.fullSearchPar.board->key, 
                        pStackEntry->localData.fullSearchDat.trans_move, 
                        pStackEntry->localData.fullSearchDat.trans_depth, 
                        pStackEntry->localData.fullSearchDat.trans_flags, 
                        pStackEntry->localData.fullSearchDat.trans_value);

            if(g_pYBWCManagerInstance->bPotentialBroadcastTranspositionTable)
            {
              if(pStackEntry->localData.fullSearchDat.trans_depth >= g_pYBWCManagerInstance->pFruitConfiguration->nMinimumTransDepthForBroadcast)
              {
                HashTableBuffer_AddEntryAndCheckBroadcast(g_pYBWCManagerInstance->pHashTableTransmitBuffer, 
                                                          pStackEntry->parameters.fullSearchPar.board->key, 
                                                          pStackEntry->localData.fullSearchDat.trans_move, 
                                                          pStackEntry->localData.fullSearchDat.trans_depth, 
                                                          pStackEntry->localData.fullSearchDat.trans_flags, 
                                                          pStackEntry->localData.fullSearchDat.trans_value);
// kh 02.06.08 end Thomas Gaksch 14b5c
              }
            } // if(g_pYBWCManagerInstance->bPotentialBroadcastTranspositionTable)
//        } // if(    pStackEntry->bSlaveCutoffLevel...
        } // if(UseTrans && pStackEntry->parameters.fullSearchPar.depth >= TransDepth) 
      } // if(pStackEntry->bIsAlive || pStackEntry->bSlaveCutoffLevel)

// kh 21.07.06 
//    return best_value; 
      pStackEntry->nResult = pStackEntry->localData.fullSearchDat.best_value;

      break;

    case CALL_TYPE_FULL_NO_NULL:

#if DEBUG
      pStackEntry->nAlphaParameterOnEntry = pStackEntry->parameters.fullNoNullPar.alpha;
      pStackEntry->nBetaParameterOnEntry  = pStackEntry->parameters.fullNoNullPar.beta;
#endif

      ASSERT(pStackEntry->parameters.fullNoNullPar.board != NULL);
      ASSERT(range_is_ok(pStackEntry->parameters.fullNoNullPar.alpha, pStackEntry->parameters.fullNoNullPar.beta));
      ASSERT(depth_is_ok(pStackEntry->parameters.fullNoNullPar.depth));
      ASSERT(height_is_ok(pStackEntry->parameters.fullNoNullPar.height + SearchInfo->nHeightOffset));
      ASSERT(pStackEntry->parameters.fullNoNullPar.ppv != NULL);
      ASSERT(    pStackEntry->parameters.fullNoNullPar.node_type == NodePV
              || pStackEntry->parameters.fullNoNullPar.node_type == NodeCut
              || pStackEntry->parameters.fullNoNullPar.node_type == NodeAll);
      ASSERT(pStackEntry->parameters.fullNoNullPar.trans_move == MoveNone || move_is_ok(pStackEntry->parameters.fullNoNullPar.trans_move));
      ASSERT(pStackEntry->parameters.fullNoNullPar.pbest_move != NULL);

      ASSERT(board_is_legal(pStackEntry->parameters.fullNoNullPar.board));
      ASSERT(!board_is_check(pStackEntry->parameters.fullNoNullPar.board));
      ASSERT(pStackEntry->parameters.fullNoNullPar.depth >= 1);

// kh 30.10.06 check this early too (defensive, performance)
      if(!pStackEntry->bIsAlive)
      {
        *pStackEntry->parameters.fullNoNullPar.pbest_move = MoveNone; // kh 01.11.06 defensive
        pStackEntry->localData.fullNoNullDat.best_value = ValueNone; // kh 01.11.06 defensive
        goto cut_full_no_null;
      }

      // init

      SearchCurrent->node_nb++;
      SearchCurrent->node_local_nb++;
      g_pYBWCManagerInstance->nTotalNodes++;

      SearchInfo->check_nb--;
      SearchInfo->check_nb_mpi_poll--;
      PV_CLEAR(pStackEntry->parameters.fullNoNullPar.ppv);

      if(pStackEntry->parameters.fullNoNullPar.height > SearchCurrent->max_depth) 
      {
        SearchCurrent->max_depth = pStackEntry->parameters.fullNoNullPar.height;
      }

      if(pStackEntry->parameters.fullNoNullPar.height > SearchCurrent->max_local_depth) 
      {
        SearchCurrent->max_local_depth = pStackEntry->parameters.fullNoNullPar.height;
      }

      if(SearchInfo->check_nb <= 0) 
      {
        SearchInfo->check_nb += SearchInfo->check_inc;
        search_check();
      }

      attack_set(pStackEntry->localData.fullNoNullDat.attack, pStackEntry->parameters.fullNoNullPar.board);
      ASSERT(!ATTACK_IN_CHECK(pStackEntry->localData.fullNoNullDat.attack));

      *pStackEntry->parameters.fullNoNullPar.pbest_move = MoveNone;
      pStackEntry->localData.fullNoNullDat.best_value = ValueNone;

      // move loop

      sort_init(pStackEntry->localData.fullNoNullDat.sort, 
                pStackEntry->parameters.fullNoNullPar.board, 
                pStackEntry->localData.fullNoNullDat.attack, 
                pStackEntry->parameters.fullNoNullPar.depth, 
                pStackEntry->parameters.fullNoNullPar.height, 
                pStackEntry->parameters.fullNoNullPar.trans_move);

// kh 27.10.06 consider search abort via !bIsAlive for the null move search too
//    while((pStackEntry->localData.fullNoNullDat.move = sort_next(pStackEntry->localData.fullNoNullDat.sort)) != MoveNone)

// kh 03.06.08 Thomas Gaksch 14b5c
      while(pStackEntry->bIsAlive && ((pStackEntry->localData.fullNoNullDat.move = sort_next(pStackEntry->localData.fullNoNullDat.sort)) != MoveNone))
      {

// kh 03.06.08 Thomas Gaksch 14b5c
        pStackEntry->localData.fullNoNullDat.new_depth = full_new_depth(pStackEntry->parameters.fullNoNullPar.depth, 
                                                                        pStackEntry->localData.fullNoNullDat.move, 
                                                                        pStackEntry->parameters.fullNoNullPar.board, 
                                                                        false, 
                                                                        false,
                                                                        pStackEntry->parameters.fullNoNullPar.height,
                                                                        pStackEntry->parameters.fullNoNullPar.extended,
                                                                        &pStackEntry->localData.fullNoNullDat.cap_extended);

// kh 11.04.07 end Thomas Gaksch

        move_do(pStackEntry->parameters.fullNoNullPar.board, pStackEntry->localData.fullNoNullDat.move, pStackEntry->localData.fullNoNullDat.undo);

// kh 24.07.06 simulate recursive call
//      value = -full_search(board, -beta, -alpha, new_depth, height + 1, new_pv, NODE_OPP(node_type));
        ASSERT(g_Stack.nCount > 0);
        Stack_PushFullSearch(/* pStack, */
                             pStackEntry->parameters.fullNoNullPar.board, 
                             -pStackEntry->parameters.fullNoNullPar.beta, 
                             -pStackEntry->parameters.fullNoNullPar.alpha, 
                             pStackEntry->localData.fullNoNullDat.new_depth, 
                             pStackEntry->parameters.fullNoNullPar.height + 1, 
                             pStackEntry->localData.fullNoNullDat.new_pv, 
                             NODE_OPP(pStackEntry->parameters.fullNoNullPar.node_type), 
                             pStackEntry->localData.fullNoNullDat.cap_extended, // kh 04.06.08 Thomas Gaksch 14b5c
                             RETURN_POSITION_FULL_NO_NULL_01);
        goto L_CALL_FULL_SEARCH;

// kh 26.07.06
L_RETURN_POSITION_FULL_NO_NULL_01:
        move_undo(pStackEntry->parameters.fullNoNullPar.board, pStackEntry->localData.fullNoNullDat.move, pStackEntry->localData.fullNoNullDat.undo);

        if(!pStackEntry->bIsAlive) // kh 30.10.06 performance
        {
          goto cut_full_no_null;
        }

        pStackEntry->localData.fullNoNullDat.value = -pStackEntry->nResult;

        if(pStackEntry->localData.fullNoNullDat.value > pStackEntry->localData.fullNoNullDat.best_value) 
        {
          pStackEntry->localData.fullNoNullDat.best_value = pStackEntry->localData.fullNoNullDat.value;
          pv_cat(pStackEntry->parameters.fullNoNullPar.ppv, pStackEntry->localData.fullNoNullDat.new_pv, pStackEntry->localData.fullNoNullDat.move);
          if(pStackEntry->localData.fullNoNullDat.value > pStackEntry->parameters.fullNoNullPar.alpha) 
          {
            pStackEntry->parameters.fullNoNullPar.alpha       = pStackEntry->localData.fullNoNullDat.value;
            *pStackEntry->parameters.fullNoNullPar.pbest_move = pStackEntry->localData.fullNoNullDat.move;

            if((pStackEntry->localData.fullNoNullDat.value >= pStackEntry->parameters.fullNoNullPar.beta)) // kh 14.12.06 $cut...
            {
              goto cut_full_no_null;
            }
          } // if(pStackEntry->localData.fullNoNullDat.value > pStackEntry->parameters.fullNoNullPar.alpha) 
        } // if(pStackEntry->localData.fullNoNullDat.value > pStackEntry->localData.fullNoNullDat.best_value) 
      } // while(pStackEntry->bIsAlive && ((pStackEntry->localData.fullNoNullDat.move = sort_next(pStackEntry->localData.fullNoNullDat.sort)) != MoveNone))

// kh 30.10.06 not really used, defensive (see bIsAlive check above)
      if(pStackEntry->bIsAlive)
      {
      }
      else
      {
        goto cut_full_no_null; // kh 27.10.06 use a goto here, following the standard Fruit programming style 
      }

      // ALL node

      if(pStackEntry->localData.fullNoNullDat.best_value == ValueNone) // no legal move => stalemate
      {
        ASSERT(board_is_stalemate(pStackEntry->parameters.fullNoNullPar.board));
        pStackEntry->localData.fullNoNullDat.best_value = ValueDraw;
      }

cut_full_no_null:
      ASSERT(!pStackEntry->bTryToDistribute);
      ASSERT(value_is_ok(pStackEntry->localData.fullNoNullDat.best_value) || !pStackEntry->bIsAlive);

// kh 26.07.06 
//    return best_value; 
      pStackEntry->nResult = pStackEntry->localData.fullNoNullDat.best_value;

      break;

    case CALL_TYPE_FULL_QUIESCENCE:

#if DEBUG
      pStackEntry->nAlphaParameterOnEntry = pStackEntry->parameters.fullQuiescencePar.alpha;
      pStackEntry->nBetaParameterOnEntry  = pStackEntry->parameters.fullQuiescencePar.beta;
#endif

      ASSERT(pStackEntry->parameters.fullQuiescencePar.board != NULL);
      ASSERT(range_is_ok(pStackEntry->parameters.fullQuiescencePar.alpha, pStackEntry->parameters.fullQuiescencePar.beta));
      ASSERT(depth_is_ok(pStackEntry->parameters.fullQuiescencePar.depth));
      ASSERT(height_is_ok(pStackEntry->parameters.fullQuiescencePar.height + SearchInfo->nHeightOffset));
      ASSERT(pStackEntry->parameters.fullQuiescencePar.ppv != NULL);

      ASSERT(board_is_legal(pStackEntry->parameters.fullQuiescencePar.board));
      ASSERT(pStackEntry->parameters.fullQuiescencePar.depth <= 0);

// kh 30.10.06 check this early too (defensive, performance)
      if(!pStackEntry->bIsAlive)
      {
        pStackEntry->localData.fullQuiescenceDat.best_value  = ValueNone; // kh 01.11.06 defensive
        pStackEntry->localData.fullQuiescenceDat.best_move   = MoveNone;  // kh 01.11.06 defensive
        goto cut_full_quiescence;
      }
      // init

      SearchCurrent->node_nb++;
      SearchCurrent->node_local_nb++;
      g_pYBWCManagerInstance->nTotalNodes++;

      SearchInfo->check_nb--;
      SearchInfo->check_nb_mpi_poll--;
      PV_CLEAR(pStackEntry->parameters.fullQuiescencePar.ppv);

      if(pStackEntry->parameters.fullQuiescencePar.height > SearchCurrent->max_depth) 
      {
        SearchCurrent->max_depth = pStackEntry->parameters.fullQuiescencePar.height;
      }

      if(pStackEntry->parameters.fullQuiescencePar.height > SearchCurrent->max_local_depth) 
      {
        SearchCurrent->max_local_depth = pStackEntry->parameters.fullQuiescencePar.height;
      }

      if(SearchInfo->check_nb <= 0) 
      {
        SearchInfo->check_nb += SearchInfo->check_inc;
        search_check();
      }

      // draw?

// kh 03.06.08 Thomas Gaksch 14b5c
      if(board_is_repetition(pStackEntry->parameters.fullQuiescencePar.board))
      {

// kh 07.08.06 
//      return ValueDraw;
        pStackEntry->nResult = ValueDraw;
        goto L_RETURN_FULL_SEARCH;
      }

#if defined(_WIN32) || defined(_WIN64)

// kh 03.06.08 start Thomas Gaksch 14b5c

/*
		Interior node recognizer from scorpio by Daniel Shawul
		-> dont probe at the leaves as this will slow down search
	    For 4/3 pieces probe there also.
		-> After captures and pawn moves assume exact score and cutoff tree,
	    because we are making progress. Note this is not done only for speed.
		-> if we are far from root (depth / 2), assume exact score and cutoff tree
*/

/*
	    if(    egbb_is_loaded 
          && pStackEntry->parameters.fullQuiescencePar.board->piece_nb <= 4) 
      {
		    if(probe_bitbases(pStackEntry->parameters.fullQuiescencePar.board, 
                          pStackEntry->localData.fullQuiescenceDat.probe_score))
        {

// kh 04.06.08 adjust by SearchInfo->nHeightOffset here now
  			  pStackEntry->localData.fullQuiescenceDat.probe_score = 
            value_from_trans(pStackEntry->localData.fullQuiescenceDat.probe_score,
                             pStackEntry->parameters.fullQuiescencePar.height + SearchInfo->nHeightOffset);

// kh 03.06.08 Thomas Gaksch 14b5c
//	      return probe_score;
          pStackEntry->nResult = pStackEntry->localData.fullQuiescenceDat.probe_score;
          goto L_RETURN_FULL_SEARCH;
		    }
      } // if(    egbb_is_loaded ...
*/

#else // assume POSIX

#endif
// kh 03.06.08 end Thomas Gaksch 14b5c

// kh 03.06.08 start Thomas Gaksch 14b5c
      if(recog_draw(pStackEntry->parameters.fullQuiescencePar.board))
      {

    // kh 03.06.08 
    //  return ValueDraw;
        pStackEntry->nResult = ValueDraw;
        goto L_RETURN_FULL_SEARCH;
      }
// kh 03.06.08 end Thomas Gaksch 14b5c

      // mate-distance pruning

      if(UseDistancePruning) 
      {
        // lower bound

        pStackEntry->localData.fullQuiescenceDat.value = VALUE_MATE((pStackEntry->parameters.fullQuiescencePar.height + SearchInfo->nHeightOffset) + 2); // does not work if the current position is mate
        if(pStackEntry->localData.fullQuiescenceDat.value > pStackEntry->parameters.fullQuiescencePar.alpha && board_is_mate(pStackEntry->parameters.fullQuiescencePar.board)) 
        {
          pStackEntry->localData.fullQuiescenceDat.value = VALUE_MATE(pStackEntry->parameters.fullQuiescencePar.height + SearchInfo->nHeightOffset);
        }

        if(pStackEntry->localData.fullQuiescenceDat.value > pStackEntry->parameters.fullQuiescencePar.alpha) 
        {
          pStackEntry->parameters.fullQuiescencePar.alpha = pStackEntry->localData.fullQuiescenceDat.value;
          if(pStackEntry->localData.fullQuiescenceDat.value >= pStackEntry->parameters.fullQuiescencePar.beta) 
          {

// kh 07.08.06 
//          return value;
            pStackEntry->nResult = pStackEntry->localData.fullQuiescenceDat.value;
            goto L_RETURN_FULL_SEARCH;
          }
        }

        // upper bound

        pStackEntry->localData.fullQuiescenceDat.value = -VALUE_MATE((pStackEntry->parameters.fullQuiescencePar.height + SearchInfo->nHeightOffset) + 1);

        if(pStackEntry->localData.fullQuiescenceDat.value < pStackEntry->parameters.fullQuiescencePar.beta) 
        {
          pStackEntry->parameters.fullQuiescencePar.beta = pStackEntry->localData.fullQuiescenceDat.value;
          if(pStackEntry->localData.fullQuiescenceDat.value <= pStackEntry->parameters.fullQuiescencePar.alpha) 
          {

// kh 07.08.06 
//          return value;
            pStackEntry->nResult = pStackEntry->localData.fullQuiescenceDat.value;
            goto L_RETURN_FULL_SEARCH;
          }
        }
      } // if(UseDistancePruning) 

      // more init

      attack_set(pStackEntry->localData.fullQuiescenceDat.attack, pStackEntry->parameters.fullQuiescencePar.board);
      pStackEntry->localData.fullQuiescenceDat.in_check = ATTACK_IN_CHECK(pStackEntry->localData.fullQuiescenceDat.attack);

      if(pStackEntry->localData.fullQuiescenceDat.in_check) 
      {

// kh 26.02.08 assertion does not hold any longer for toga when razoring is enabled
//      ASSERT(pStackEntry->parameters.fullQuiescencePar.depth < 0);
        pStackEntry->parameters.fullQuiescencePar.depth++; // in-check extension
      }

      // height limit

      if((pStackEntry->parameters.fullQuiescencePar.height + SearchInfo->nHeightOffset) >= HeightMax - 1) 

      {

// kh 19.03.07        
        if(g_pYBWCManagerInstance->pFruitConfiguration->nFruitDebugLevel >= FRUIT_DEBUG_LEVEL_WARNING_PRIO_1)
        {
          YBWCManager_Printf(g_pYBWCManagerInstance, 
                             "WARNING full_search(... at CALL_TYPE_FULL_QUIESCENCE HeightMax %d + %d >= limit %d reached\n",
                             SearchInfo->nHeightOffset,
                             pStackEntry->parameters.fullQuiescencePar.height,
                             HeightMax - 1);
        }

// kh 07.08.06 
//      return eval(board);

// kh 03.06.08 Thomas Gaksch 14b5c
        pStackEntry->nResult = eval(pStackEntry->parameters.fullQuiescencePar.board, pStackEntry->parameters.fullQuiescencePar.alpha, pStackEntry->parameters.fullQuiescencePar.beta);

        goto L_RETURN_FULL_SEARCH;
      }

      // more init

      pStackEntry->localData.fullQuiescenceDat.old_alpha   = pStackEntry->parameters.fullQuiescencePar.alpha;
      pStackEntry->localData.fullQuiescenceDat.best_value  = ValueNone;
      pStackEntry->localData.fullQuiescenceDat.best_move   = MoveNone;

      /* if (UseDelta) */ pStackEntry->localData.fullQuiescenceDat.opt_value = +ValueInf;

      if(!pStackEntry->localData.fullQuiescenceDat.in_check) 
      {
        // lone-king stalemate?

        if(simple_stalemate(pStackEntry->parameters.fullQuiescencePar.board)) 
        {
          
// kh 07.08.06 
//        return ValueDraw;
          pStackEntry->nResult = ValueDraw;
          goto L_RETURN_FULL_SEARCH;
        }

        // stand pat

// kh 03.06.08 Thomas Gaksch 14b5c
        pStackEntry->localData.fullQuiescenceDat.value = eval(pStackEntry->parameters.fullQuiescencePar.board, 
                                                              pStackEntry->parameters.fullQuiescencePar.alpha, 
                                                              pStackEntry->parameters.fullQuiescencePar.beta); 

        ASSERT(pStackEntry->localData.fullQuiescenceDat.value > pStackEntry->localData.fullQuiescenceDat.best_value);
        pStackEntry->localData.fullQuiescenceDat.best_value = pStackEntry->localData.fullQuiescenceDat.value;
        if(pStackEntry->localData.fullQuiescenceDat.value > pStackEntry->parameters.fullQuiescencePar.alpha) 
        {
          pStackEntry->parameters.fullQuiescencePar.alpha = pStackEntry->localData.fullQuiescenceDat.value;
          if((pStackEntry->localData.fullQuiescenceDat.value >= pStackEntry->parameters.fullQuiescencePar.beta)) // kh 14.12.06 $cut...
          {
            goto cut_full_quiescence;
          }
        }

        if(UseDelta) 
        {
          pStackEntry->localData.fullQuiescenceDat.opt_value = pStackEntry->localData.fullQuiescenceDat.value + DeltaMargin;
          ASSERT(pStackEntry->localData.fullQuiescenceDat.opt_value < +ValueInf);
        }
      } // if(!pStackEntry->localData.fullQuiescenceDat.in_check)

      // move loop

// kh 11.04.07 Thomas Gaksch
/*    
      cd = CheckDepth;
      if(cd < 0 && board->piece_size[board->turn] <= 5)
      {
        cd++; 
      }
*/

      sort_init_qs(pStackEntry->localData.fullQuiescenceDat.sort, 
                   pStackEntry->parameters.fullQuiescencePar.board, 
                   pStackEntry->localData.fullQuiescenceDat.attack, 
                   pStackEntry->parameters.fullQuiescencePar.depth >= CheckDepth /* depth>=cd */); // kh 11.04.07 Thomas Gaksch

// kh 27.10.06 consider search abort via !bIsAlive for the quiescence search too
//    while((pStackEntry->localData.fullQuiescenceDat.move = sort_next_qs(pStackEntry->localData.fullQuiescenceDat.sort)) != MoveNone) 
      while(pStackEntry->bIsAlive && ((pStackEntry->localData.fullQuiescenceDat.move = sort_next_qs(pStackEntry->localData.fullQuiescenceDat.sort)) != MoveNone))
      {

        // delta pruning

        if(UseDelta && pStackEntry->parameters.fullQuiescencePar.beta == pStackEntry->localData.fullQuiescenceDat.old_alpha + 1)
        {
          if(    !pStackEntry->localData.fullQuiescenceDat.in_check 
              && !move_is_check(pStackEntry->localData.fullQuiescenceDat.move, pStackEntry->parameters.fullQuiescencePar.board) 
              && !capture_is_dangerous(pStackEntry->localData.fullQuiescenceDat.move, pStackEntry->parameters.fullQuiescencePar.board)) 
          {
            ASSERT(move_is_tactical(pStackEntry->localData.fullQuiescenceDat.move, pStackEntry->parameters.fullQuiescencePar.board));

            // optimistic evaluation

            pStackEntry->localData.fullQuiescenceDat.value = pStackEntry->localData.fullQuiescenceDat.opt_value;

            int to      = MOVE_TO(pStackEntry->localData.fullQuiescenceDat.move);
            int capture = pStackEntry->parameters.fullQuiescencePar.board->square[to];

            if(capture != Empty) 
            {
              pStackEntry->localData.fullQuiescenceDat.value += VALUE_PIECE(capture);
            } 
            else if(MOVE_IS_EN_PASSANT(pStackEntry->localData.fullQuiescenceDat.move)) 
            {
              pStackEntry->localData.fullQuiescenceDat.value += ValuePawn;
            }

            if(MOVE_IS_PROMOTE(pStackEntry->localData.fullQuiescenceDat.move)) 
            {
              pStackEntry->localData.fullQuiescenceDat.value += ValueQueen - ValuePawn;
            }

            // pruning

            if(pStackEntry->localData.fullQuiescenceDat.value <= pStackEntry->parameters.fullQuiescencePar.alpha) 
            {
              if(pStackEntry->localData.fullQuiescenceDat.value > pStackEntry->localData.fullQuiescenceDat.best_value) 
              {
                pStackEntry->localData.fullQuiescenceDat.best_value = pStackEntry->localData.fullQuiescenceDat.value;
                PV_CLEAR(pStackEntry->parameters.fullQuiescencePar.ppv);
              }

              continue;
            }
          } // if(!in_check && !move_is_check(move, board) && !capture_is_dangerous(move, board)) 
        } // if(UseDelta && beta == old_alpha + 1)

        move_do(pStackEntry->parameters.fullQuiescencePar.board, pStackEntry->localData.fullQuiescenceDat.move, pStackEntry->localData.fullQuiescenceDat.undo);

// kh 07.08.06
//      value = -full_quiescence(board,-beta,-alpha,depth-1,height+1,new_pv);

// kh 03.06.08 Thomas Gaksch 14b5c
        Stack_PushFullQuiescence(/* pStack, */
                                 pStackEntry->parameters.fullQuiescencePar.board, 
                                 -pStackEntry->parameters.fullQuiescencePar.beta, 
                                 -pStackEntry->parameters.fullQuiescencePar.alpha, 
                                 pStackEntry->parameters.fullQuiescencePar.depth - 1, 
                                 pStackEntry->parameters.fullQuiescencePar.height + 1, 
                                 pStackEntry->localData.fullQuiescenceDat.new_pv,
                                 RETURN_POSITION_FULL_QUIESCENCE_01);
        goto L_CALL_FULL_SEARCH;

L_RETURN_POSITION_FULL_QUIESCENCE_01:
        move_undo(pStackEntry->parameters.fullQuiescencePar.board, pStackEntry->localData.fullQuiescenceDat.move, pStackEntry->localData.fullQuiescenceDat.undo);

        if(!pStackEntry->bIsAlive) // kh 30.10.06 defensive, performance
        {
          goto cut_full_quiescence;
        }

        pStackEntry->localData.fullQuiescenceDat.value = -pStackEntry->nResult;

        if(pStackEntry->localData.fullQuiescenceDat.value > pStackEntry->localData.fullQuiescenceDat.best_value) 
        {
          pStackEntry->localData.fullQuiescenceDat.best_value = pStackEntry->localData.fullQuiescenceDat.value;
          pv_cat(pStackEntry->parameters.fullQuiescencePar.ppv, pStackEntry->localData.fullQuiescenceDat.new_pv, pStackEntry->localData.fullQuiescenceDat.move);
          if(pStackEntry->localData.fullQuiescenceDat.value > pStackEntry->parameters.fullQuiescencePar.alpha) 
          {
            pStackEntry->parameters.fullQuiescencePar.alpha    = pStackEntry->localData.fullQuiescenceDat.value;
            pStackEntry->localData.fullQuiescenceDat.best_move = pStackEntry->localData.fullQuiescenceDat.move;

            if((pStackEntry->localData.fullQuiescenceDat.value >= pStackEntry->parameters.fullQuiescencePar.beta)) // // kh 14.12.06 $cut...
            {
              goto cut_full_quiescence;
            }
          }
        }
      } // while(pStackEntry->bIsAlive && ((pStackEntry->localData.fullQuiescenceDat.move = sort_next_qs(pStackEntry->localData.fullQuiescenceDat.sort)) != MoveNone))

// kh 30.10.06 not really used, defensive (see bIsAlive check above)
      if(pStackEntry->bIsAlive) 
      {
      }
      else
      {
        goto cut_full_quiescence; // kh 27.10.06 use a goto here, following the standard Fruit programming style 
      }

    // ALL node

      if(pStackEntry->localData.fullQuiescenceDat.best_value == ValueNone) // no legal move
      {
        ASSERT(board_is_mate(pStackEntry->parameters.fullQuiescencePar.board));

// kh 07.08.06 
//      return VALUE_MATE(height);
        pStackEntry->nResult = VALUE_MATE(pStackEntry->parameters.fullQuiescencePar.height + SearchInfo->nHeightOffset);
        goto L_RETURN_FULL_SEARCH;
      }

cut_full_quiescence:
      ASSERT(!pStackEntry->bTryToDistribute);
      ASSERT(value_is_ok(pStackEntry->localData.fullQuiescenceDat.best_value) || !pStackEntry->bIsAlive);

// kh 07.08.06 
//    return best_value; 
      pStackEntry->nResult = pStackEntry->localData.fullQuiescenceDat.best_value;

      break;

    default:
      ASSERT(false);
      break;

    } // switch(pStackEntry->nCallType)

// logical "return" from potential simulated recursive call
L_RETURN_FULL_SEARCH: 

#if DEBUG
// kh 09.02.07 for debug purposes
    if(pStackEntry->bSlaveCutoffLevel)
    {
      ASSERT(!pStackEntry->bIsAlive);

// kh 02.02.07 calc nodes count as difference to the memo start count (negative, defensive)
      g_pYBWCManagerInstance->nNodesSinceAbort =
          SearchCurrent->node_nb 
        + g_pYBWCManagerInstance->nNodesSinceAbort
        - g_pYBWCManagerInstance->nAllSlaveNodesReceivedInBetween; // kh 09.02.07 all slave nodes asynchronously received in between

      ASSERT(g_pYBWCManagerInstance->nNodesSinceAbort >= 0);

    }
#endif

    nTmpReturnPosition    = pStackEntry->nReturnPosition;
    nTmpResult            = pStackEntry->nResult;

    Stack_PopFast(/* pStack */);

    if(g_Stack.nCount > 0)
    {

// kh 25.07.06 restore state for recursion level at top of stack 
      pStackEntry           = Stack_Peek(/* pStack */); 

      pStackEntry->nResult  = nTmpResult;

      switch(nTmpReturnPosition)
      {
      case RETURN_POSITION_UNDEFINED:
        ASSERT(false);
        goto L_RETURN_FULL_SEARCH; // kh 24.07.06 defensive
        break;



      case RETURN_POSITION_FUNCTION_END:
        ASSERT(false)
        goto L_RETURN_FULL_SEARCH;
        break;



      case RETURN_POSITION_FULL_ROOT_01:
        goto L_RETURN_POSITION_FULL_ROOT_01;
        break;

      case RETURN_POSITION_FULL_ROOT_01_1:
        goto L_RETURN_POSITION_FULL_ROOT_01_1;
        break;

      case RETURN_POSITION_FULL_ROOT_01_2:
        goto L_RETURN_POSITION_FULL_ROOT_01_2;
        break;

      case RETURN_POSITION_FULL_ROOT_02:
        goto L_RETURN_POSITION_FULL_ROOT_02;
        break;

      case RETURN_POSITION_FULL_ROOT_03:
        goto L_RETURN_POSITION_FULL_ROOT_03;
        break;

// kh 04.06.08 Thomas Gaksch 14b5c
/*
      case RETURN_POSITION_FULL_ROOT_03_1:
        goto L_RETURN_POSITION_FULL_ROOT_03_1;
        break;
*/

      case RETURN_POSITION_FULL_ROOT_04:
        goto L_RETURN_POSITION_FULL_ROOT_04;
        break;



      case RETURN_POSITION_FULL_SEARCH_01:
        goto L_RETURN_POSITION_FULL_SEARCH_01;
        break;

      case RETURN_POSITION_FULL_SEARCH_02:
        goto L_RETURN_POSITION_FULL_SEARCH_02;
        break;

      case RETURN_POSITION_FULL_SEARCH_03:
        goto L_RETURN_POSITION_FULL_SEARCH_03;
        break;

      case RETURN_POSITION_FULL_SEARCH_03_1:
        goto L_RETURN_POSITION_FULL_SEARCH_03_1;
        break;

      case RETURN_POSITION_FULL_SEARCH_04:
        goto L_RETURN_POSITION_FULL_SEARCH_04;
        break;

      case RETURN_POSITION_FULL_SEARCH_05:
        goto L_RETURN_POSITION_FULL_SEARCH_05;
        break;

      case RETURN_POSITION_FULL_SEARCH_06:
        goto L_RETURN_POSITION_FULL_SEARCH_06;
        break;

      case RETURN_POSITION_FULL_SEARCH_07:
        goto L_RETURN_POSITION_FULL_SEARCH_07;
        break;

      case RETURN_POSITION_FULL_SEARCH_08:
        goto L_RETURN_POSITION_FULL_SEARCH_08;
        break;

      case RETURN_POSITION_FULL_SEARCH_09:
        goto L_RETURN_POSITION_FULL_SEARCH_09;
        break;



      case RETURN_POSITION_FULL_NO_NULL_01:
        goto L_RETURN_POSITION_FULL_NO_NULL_01;
        break;



      case RETURN_POSITION_FULL_QUIESCENCE_01:
        goto L_RETURN_POSITION_FULL_QUIESCENCE_01;
        break;



      default:
        ASSERT(false);
        goto L_RETURN_FULL_SEARCH; // kh 24.07.06 defensive
        break;

      } // switch(nTmpReturnPosition)
    } // if(g_Stack.nCount > 0)
  } // while(g_Stack.nCount > 1)

  ASSERT(pStackEntry->nReturnPosition == RETURN_POSITION_FUNCTION_END);

  return pStackEntry->nResult;
}

// full_no_null()

// kh 26.07.06 full_no_null(... is now included in fullSearch(... (via switch statement)

// full_quiescence()

// kh 07.08.06 full_quiescence(... is now included in fullSearch(... (via switch statement)

// full_new_depth()

// kh 02.06.08 Thomas Gaksch 14b5c
/*static*/ int full_new_depth(int depth, int move, board_t* board, bool single_reply, bool in_pv, int height, bool extended, bool* cap_extended)
{
  int new_depth;

  ASSERT(depth_is_ok (depth));
  ASSERT(move_is_ok  (move));
  ASSERT(board != NULL);
  ASSERT(single_reply == true || single_reply == false);
  ASSERT(in_pv == true || in_pv == false);

  ASSERT(depth > 0);

  new_depth     = depth - 1;
 *cap_extended  = false;

  if(in_pv && board->square[MOVE_TO(move)] != Empty && !PIECE_IS_PAWN(board->square[MOVE_TO(move)]))
  {
	  if((board->piece_size[White] + board->piece_size[Black]) == 3)
    {
			return new_depth + 1;
	  }
	  else if(    (board->piece_size[White] == 3 && board->piece_size[Black] == 2)
		         || (board->piece_size[White] == 2 && board->piece_size[Black] == 3))
    {
		   return new_depth + 1; 
    }
  }

  if(    (single_reply && ExtendSingleReply) 
		//|| (in_pv && MOVE_TO(move) == board->cap_sq // recapture
		//  && see_move(move,board) >= -100 /*|| ABS(VALUE_PIECE(board->square[MOVE_TO(move)])-VALUE_PIECE(board->square[MOVE_FROM(move)])) <= 250 )*/)  
		//|| (in_pv && PIECE_IS_PAWN(MOVE_PIECE(move,board))
		//	  && (PAWN_RANK(MOVE_TO(move),board->turn) == Rank7 || PAWN_RANK(MOVE_TO(move),board->turn) == Rank6))
		//|| (in_pv &&  board->square[MOVE_TO(move)] != PieceNone256 && SearchCurrent[ThreadId]->act_iteration-height >= 6 && see_move(move,board) >= -100) 
		//|| (in_pv &&  board->square[MOVE_TO(move)] != PieceNone256 && !extended && see_move(move,board) >= -100)
		//|| (in_pv && mate_threat == true)
		  || move_is_check(move, board) && (in_pv || see_move(move, board) >= -100)) 
  {
		return new_depth+1;
  }
  if(in_pv && PIECE_IS_PAWN(MOVE_PIECE(move, board)))
  {
		if(is_passed(board, MOVE_TO(move)))
			return new_depth+1;
  }

  if(    in_pv 
      && board->square[MOVE_TO(move)] != PieceNone256 
	    && !extended && see_move(move, board) >= -100)
  {
	  *cap_extended = true;
	  return new_depth + 1;
  }
  
  ASSERT(new_depth >= 0 && new_depth <= depth);

  return new_depth;
}

// do_null()

static bool do_null(const board_t * board) {

   ASSERT(board!=NULL);

   // use null move if the side-to-move has at least one piece

   return board->piece_size[board->turn] >= 2; // king + one piece
}

// do_ver()

static bool do_ver(const board_t * board) {

   ASSERT(board!=NULL);

   // use verification if the side-to-move has at most one piece

// kh 11.04.07 Thomas Gaksch
   return board->piece_size[board->turn] <= 3; // king + one piece was 2 
}

// pv_fill()

static void pv_fill(const mv_t pv[], board_t * board) 
{
  int    move;

  int    trans_move;
  int    trans_depth;

  undo_t undo[1];

  ASSERT(pv != NULL);
  ASSERT(board != NULL);

  ASSERT(UseTrans);

  move = *pv;

  if(move != MoveNone && move != MoveNull)
  {
    move_do(board, move, undo);
    pv_fill(pv + 1, board);
    move_undo(board, move, undo);

    trans_move = move;
    trans_depth = -127; // HACK

// kh 04.06.08 start Thomas Gaksch 14b5c
    trans_store(Trans, board->key, trans_move, trans_depth, TransUnknown, -ValueInf);

    if(g_pYBWCManagerInstance->bPotentialBroadcastTranspositionTable)
    {

// kh 20.03.08 ignore check here, trans_depth is -127  (see above)
/*
      if(    (trans_depth >= g_pYBWCManagerInstance->pFruitConfiguration->nMinimumTransDepthForBroadcast)
//        && g_pYBWCManagerInstance->nUniversalDebugFlag1 
        )
      {
*/
        HashTableBuffer_AddEntryAndCheckBroadcast(g_pYBWCManagerInstance->pHashTableTransmitBuffer, 
                                                  board->key, 
                                                  trans_move, 
                                                  trans_depth, 
                                                  TransUnknown, 
                                                  -ValueInf);
// kh 04.06.08 end Thomas Gaksch 14b5c
/*
      }
*/
    }
  }
}

// move_is_dangerous()

/*static*/ bool move_is_dangerous(int move, const board_t * board) 
{
  int piece;

  ASSERT(move_is_ok(move));
  ASSERT(board != NULL);

// kh 12.04.07 assertion does not hold any longer for toga
//ASSERT(!move_is_tactical(move,board));

  piece = MOVE_PIECE(move, board);

  if(    PIECE_IS_PAWN(piece)

// kh 03.06.08 Thomas Gaksch 14b5c
      && is_passed(board, MOVE_TO(move)) /*PAWN_RANK(MOVE_TO(move),board->turn) >= Rank7 */) 
  {
    return true;
  }

// kh 11.04.07 Thomas Gaksch
/*
 	if(is_passed(board, MOVE_TO(move)) && PAWN_RANK(MOVE_TO(move), board->turn) >= Rank6)
  {
 	  return true;
  }
*/

  return false;
}

// capture_is_dangerous()

static bool capture_is_dangerous(int move, const board_t * board) {

   int piece, capture;

   ASSERT(move_is_ok(move));
   ASSERT(board!=NULL);

   ASSERT(move_is_tactical(move,board));

   piece = MOVE_PIECE(move,board);

   if (PIECE_IS_PAWN(piece)
    && PAWN_RANK(MOVE_TO(move),board->turn) >= Rank7) {
      return true;
   }

   capture = move_capture(move,board);

   if (PIECE_IS_QUEEN(capture)) return true;

   if (PIECE_IS_PAWN(capture)
    && PAWN_RANK(MOVE_TO(move),board->turn) <= Rank2) {
      return true;
   }

   return false;
}

// simple_stalemate()

static bool simple_stalemate(const board_t * board) {

   int me, opp;
   int king;
   int opp_flag;
   int from, to;
   int capture;
   const inc_t * inc_ptr;
   int inc;

   ASSERT(board!=NULL);

   ASSERT(board_is_legal(board));
   ASSERT(!board_is_check(board));

   // lone king?

   me = board->turn;
   if (board->piece_size[me] != 1 || board->pawn_size[me] != 0) return false; // no

   // king in a corner?

   king = KING_POS(board,me);
   if (king != A1 && king != H1 && king != A8 && king != H8) return false; // no

   // init

   opp = COLOUR_OPP(me);
   opp_flag = COLOUR_FLAG(opp);

   // king can move?

   from = king;

   for (inc_ptr = KingInc; (inc=*inc_ptr) != IncNone; inc_ptr++) {
      to = from + inc;
      capture = board->square[to];
      if (capture == Empty || FLAG_IS(capture,opp_flag)) {
         if (!is_attacked(board,to,opp)) return false; // legal king move
      }
   }

   // no legal move

   ASSERT(board_is_stalemate((board_t*)board));

   return true;
}

static bool is_passed(const board_t * board, int to) { 

   int t2; 
   int me, opp;
   int file, rank;

   me = board->turn; 
   opp = COLOUR_OPP(me);
   file = SQUARE_FILE(to);
   rank = PAWN_RANK(to,me);
 
   t2 = board->pawn_file[me][file] | BitRev[board->pawn_file[opp][file]]; 

   // passed pawns 
   if ((t2 & BitGT[rank]) == 0) { 
 
    if (((BitRev[board->pawn_file[opp][file-1]] | BitRev[board->pawn_file[opp][file+1]]) & BitGT[rank]) == 0) { 
        return true;

       } 
   } 

   return false;
 
}
// kh 11.04.07 end Thomas Gaksch

// end of search_full.cpp
